[cfe] Allow member access on Never

Closes #40125.

Bug: http://dartbug.com/40125
Change-Id: I2dcb1bdc022990ba8c76c7798c4e6793c5c89108
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134326
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Dmitry Stefantsov 2020-02-05 12:32:09 +00:00 committed by commit-bot@chromium.org
parent d826ecc447
commit 4389ffa9d2
12 changed files with 712 additions and 1 deletions

View file

@ -1520,6 +1520,42 @@ Message _withArgumentsInitializingFormalTypeMismatch(
arguments: {'name': name, 'type': _type, 'type2': _type2});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
String string, DartType _type, bool isNonNullableByDefault)>
templateInternalProblemUnsupportedNullability = const Template<
Message Function(
String string, DartType _type, bool isNonNullableByDefault)>(
messageTemplate:
r"""Unsupported nullability value '#string' on type '#type'.""",
withArguments: _withArgumentsInternalProblemUnsupportedNullability);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<
Message Function(
String string, DartType _type, bool isNonNullableByDefault)>
codeInternalProblemUnsupportedNullability = const Code<
Message Function(
String string, DartType _type, bool isNonNullableByDefault)>(
"InternalProblemUnsupportedNullability",
templateInternalProblemUnsupportedNullability,
severity: Severity.internalProblem);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsInternalProblemUnsupportedNullability(
String string, DartType _type, bool isNonNullableByDefault) {
if (string.isEmpty) throw 'No string provided';
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
List<Object> typeParts = labeler.labelType(_type);
String type = typeParts.join();
return new Message(codeInternalProblemUnsupportedNullability,
message:
"""Unsupported nullability value '${string}' on type '${type}'.""" +
labeler.originMessages,
arguments: {'string': string, 'type': _type});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(

View file

@ -48,7 +48,7 @@ import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
import '../names.dart';
import '../problems.dart' show unexpected, unhandled;
import '../problems.dart' show internalProblem, unexpected, unhandled;
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
@ -1051,6 +1051,24 @@ class TypeInferrerImpl implements TypeInferrer {
target = new ObjectAccessTarget.interfaceMember(interfaceMember);
} else if (receiverType is DynamicType) {
target = const ObjectAccessTarget.dynamic();
} else if (receiverType is NeverType) {
switch (receiverType.nullability) {
case Nullability.nonNullable:
target = const ObjectAccessTarget.never();
break;
case Nullability.nullable:
case Nullability.legacy:
// Never? and Never* are equivalent to Null.
return findInterfaceMember(coreTypes.nullType, name, fileOffset);
case Nullability.undetermined:
return internalProblem(
templateInternalProblemUnsupportedNullability.withArguments(
"${receiverType.nullability}",
receiverType,
isNonNullableByDefault),
fileOffset,
library.fileUri);
}
} else if (receiverType is InvalidType) {
target = const ObjectAccessTarget.invalid();
} else if (receiverType is InterfaceType &&
@ -1356,6 +1374,8 @@ class TypeInferrerImpl implements TypeInferrer {
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.missing:
return const DynamicType();
case ObjectAccessTargetKind.never:
return const NeverType(Nullability.nonNullable);
case ObjectAccessTargetKind.instanceMember:
return getGetterTypeForMemberTarget(target.member, receiverType);
case ObjectAccessTargetKind.extensionMember:
@ -1456,6 +1476,7 @@ class TypeInferrerImpl implements TypeInferrer {
return _getFunctionType(receiverType);
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.missing:
return unknownFunction;
@ -1519,6 +1540,8 @@ class TypeInferrerImpl implements TypeInferrer {
throw unhandled('$target', 'getFunctionType', null, null);
}
break;
case ObjectAccessTargetKind.never:
return const NeverType(Nullability.nonNullable);
case ObjectAccessTargetKind.callFunction:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
@ -1556,6 +1579,7 @@ class TypeInferrerImpl implements TypeInferrer {
case ObjectAccessTargetKind.callFunction:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.missing:
break;
@ -1614,6 +1638,7 @@ class TypeInferrerImpl implements TypeInferrer {
case ObjectAccessTargetKind.callFunction:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.missing:
break;
@ -1669,6 +1694,7 @@ class TypeInferrerImpl implements TypeInferrer {
case ObjectAccessTargetKind.callFunction:
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.missing:
break;
@ -1723,6 +1749,7 @@ class TypeInferrerImpl implements TypeInferrer {
switch (target.kind) {
case ObjectAccessTargetKind.unresolved:
case ObjectAccessTargetKind.dynamic:
case ObjectAccessTargetKind.never:
case ObjectAccessTargetKind.invalid:
case ObjectAccessTargetKind.missing:
return const DynamicType();
@ -2651,6 +2678,25 @@ class TypeInferrerImpl implements TypeInferrer {
nullAwareGuards);
}
ExpressionInferenceResult _inferNeverInvocation(
int fileOffset,
Link<NullAwareGuard> nullAwareGuards,
Expression receiver,
NeverType receiverType,
Name name,
Arguments arguments,
DartType typeContext) {
InvocationInferenceResult result = inferInvocation(
typeContext, fileOffset, unknownFunction, arguments, name,
receiverType: receiverType);
assert(name != equalsName);
return createNullAwareExpressionInferenceResult(
result.inferredType,
result.applyResult(new MethodInvocation(receiver, name, arguments)
..fileOffset = fileOffset),
nullAwareGuards);
}
ExpressionInferenceResult _inferMissingInvocation(
int fileOffset,
Link<NullAwareGuard> nullAwareGuards,
@ -3046,6 +3092,9 @@ class TypeInferrerImpl implements TypeInferrer {
case ObjectAccessTargetKind.unresolved:
return _inferDynamicInvocation(fileOffset, nullAwareGuards, receiver,
name, arguments, typeContext);
case ObjectAccessTargetKind.never:
return _inferNeverInvocation(fileOffset, nullAwareGuards, receiver,
receiverType, name, arguments, typeContext);
}
return unhandled(
'$target', 'inferMethodInvocation', fileOffset, uriForInstrumentation);
@ -3931,6 +3980,7 @@ enum ObjectAccessTargetKind {
callFunction,
extensionMember,
dynamic,
never,
invalid,
missing,
// TODO(johnniwinther): Remove this.
@ -3972,6 +4022,10 @@ class ObjectAccessTarget {
const ObjectAccessTarget.dynamic()
: this.internal(ObjectAccessTargetKind.dynamic, null);
/// Creates an access on a receiver of type Never with no known target.
const ObjectAccessTarget.never()
: this.internal(ObjectAccessTargetKind.never, null);
/// Creates an access with no target due to an invalid receiver type.
///
/// This is not in itself an error but a consequence of another error.

View file

@ -1704,6 +1704,10 @@ InternalProblemUnfinishedTypeVariable:
template: "Unfinished type variable '#name' found in non-source library '#uri'."
severity: INTERNAL_PROBLEM
InternalProblemUnsupportedNullability:
template: "Unsupported nullability value '#string' on type '#type'."
severity: INTERNAL_PROBLEM
LocalDefinitionHidesExport:
template: "Local definition of '#name' hides export from '#uri'."
severity: IGNORED

View file

@ -1912,6 +1912,7 @@ noticed
notifies
now
null
nullability
nullable
num
number

View file

@ -0,0 +1,34 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
foo(Never x, Never? y) {
var local0 = y.toString(); // Not an error.
var local1 = y.hashCode; // Not an error.
x.foo(); // Not an error.
x.bar; // Not an error.
x.baz = 42; // Not an error.
x(); // Not an error.
x[42]; // Not an error.
x[42] = 42; // Not an error.
x++; // Not an error.
x += 1; // Not an error.
y?.foo(); // Not an error.
y?.bar; // Not an error.
y?.baz = 42; // Not an error.
y?.call(); // Not an error.
y?.[42]; // Not an error.
y?.[42] = 42; // Not an error.
y.foo(); // Error.
y.bar; // Error.
y.baz = 42; // Error.
y(); // Error.
y++; // Error.
y += 1; // Error.
y[42]; // Error.
y[42] = 42; // Error.
}
main() {}

View file

@ -0,0 +1,7 @@
library;
import self as self;
static method foo(Neverx, Never? y) → dynamic
;
static method main() → dynamic
;

View file

@ -0,0 +1,146 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
// y.foo(); // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
// y.bar; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
// Try accessing using ?. instead.
// y.bar; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
// y.baz = 42; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
// Try accessing using ?. instead.
// y.baz = 42; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: Can't use an expression of type 'Never' as a function because it's potentially null.
// Try calling using ?.call instead.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The method '+' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '+'.
// y++; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
// y++; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The method '+' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '+'.
// y += 1; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
// y += 1; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The method '[]' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '[]'.
// y[42]; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
// y[42]; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The method '[]=' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '[]='.
// y[42] = 42; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
// y[42] = 42; // Error.
// ^
//
import self as self;
import "dart:core" as core;
static method foo(Neverx, Never? y) → dynamic {
core::String local0 = y.{core::Object::toString}();
core::int local1 = y.{core::Object::hashCode};
x.foo();
x.bar;
x.baz = 42;
x.call();
x.[](42);
x.[]=(42, 42);
x = x.+(1);
x = x.+(1);
let finalNever? #t1 = y in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{Never}.foo();
let finalNever? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar;
let finalNever? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42;
let finalNever? #t4 = y in #t4.{core::Object::==}(null) ?{dynamic} null : #t4{Never}.call();
let finalNever? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42);
let finalNever? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42);
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
y.foo(); // Error.
^^^";
let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
Try accessing using ?. instead.
y.bar; // Error.
^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
y.bar; // Error.
^^^";
let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
Try accessing using ?. instead.
y.baz = 42; // Error.
^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
y.baz = 42; // Error.
^^^";
let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: Can't use an expression of type 'Never' as a function because it's potentially null.
Try calling using ?.call instead.
y(); // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named 'call'.
y(); // Error.
^";
y = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
y++; // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The method '+' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
y++; // Error.
^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
y = (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
y += 1; // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The method '+' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
y += 1; // Error.
^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
y[42]; // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The method '[]' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '[]'.
y[42]; // Error.
^";
let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
y[42] = 42; // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The method '[]=' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '[]='.
y[42] = 42; // Error.
^";
}
static method main() → dynamic {}

View file

@ -0,0 +1,146 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
// y.foo(); // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
// y.bar; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
// Try accessing using ?. instead.
// y.bar; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
// y.baz = 42; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
// Try accessing using ?. instead.
// y.baz = 42; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: Can't use an expression of type 'Never' as a function because it's potentially null.
// Try calling using ?.call instead.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The method '+' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '+'.
// y++; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
// y++; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The method '+' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '+'.
// y += 1; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
// y += 1; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The method '[]' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '[]'.
// y[42]; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
// y[42]; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The method '[]=' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '[]='.
// y[42] = 42; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
// y[42] = 42; // Error.
// ^
//
import self as self;
import "dart:core" as core;
static method foo(Neverx, Never? y) → dynamic {
core::String local0 = y.{core::Object::toString}();
core::int local1 = y.{core::Object::hashCode};
x.foo();
x.bar;
x.baz = 42;
x.call();
x.[](42);
x.[]=(42, 42);
x = x.+(1);
x = x.+(1);
let finalNever? #t1 = y in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{Never}.foo();
let finalNever? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar;
let finalNever? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42;
let finalNever? #t4 = y in #t4.{core::Object::==}(null) ?{dynamic} null : #t4{Never}.call();
let finalNever? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42);
let finalNever? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42);
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
y.foo(); // Error.
^^^";
let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: Property 'bar' cannot be accessed on 'Never' because it is potentially null.
Try accessing using ?. instead.
y.bar; // Error.
^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
y.bar; // Error.
^^^";
let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: Property 'baz' cannot be accessed on 'Never' because it is potentially null.
Try accessing using ?. instead.
y.baz = 42; // Error.
^^^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
y.baz = 42; // Error.
^^^";
let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: Can't use an expression of type 'Never' as a function because it's potentially null.
Try calling using ?.call instead.
y(); // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named 'call'.
y(); // Error.
^";
y = (let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
y++; // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The method '+' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
y++; // Error.
^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
y = (let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: Operator '+' cannot be called on 'Never' because it is potentially null.
y += 1; // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The method '+' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
y += 1; // Error.
^") as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: Operator '[]' cannot be called on 'Never' because it is potentially null.
y[42]; // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The method '[]' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '[]'.
y[42]; // Error.
^";
let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: Operator '[]=' cannot be called on 'Never' because it is potentially null.
y[42] = 42; // Error.
^" in invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The method '[]=' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '[]='.
y[42] = 42; // Error.
^";
}
static method main() → dynamic {}

View file

@ -0,0 +1,139 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
// y.foo(); // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Warning: Method 'foo' is called on 'Never' which is potentially null.
// Try calling using ?. instead.
// y.foo(); // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
// y.bar; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Warning: Property 'bar' is accessed on 'Never' which is potentially null.
// Try accessing using ?. instead.
// y.bar; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
// y.baz = 42; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Warning: Property 'baz' is accessed on 'Never' which is potentially null.
// Try accessing using ?. instead.
// y.baz = 42; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Warning: Method 'call' is called on 'Never' which is potentially null.
// Try calling using ?. instead.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Warning: Expression of type 'Never' is used as a function, but it's potentially null.
// Try calling using ?.call instead.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The method '+' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '+'.
// y++; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Warning: Operator '+' is called on 'Never' which is potentially null.
// y++; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The method '+' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '+'.
// y += 1; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Warning: Operator '+' is called on 'Never' which is potentially null.
// y += 1; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The method '[]' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '[]'.
// y[42]; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Warning: Operator '[]' is called on 'Never' which is potentially null.
// y[42]; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The method '[]=' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '[]='.
// y[42] = 42; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Warning: Operator '[]=' is called on 'Never' which is potentially null.
// y[42] = 42; // Error.
// ^
//
import self as self;
import "dart:core" as core;
static method foo(Neverx, Never? y) → dynamic {
core::String local0 = y.{core::Object::toString}();
core::int local1 = y.{core::Object::hashCode};
x.foo();
x.bar;
x.baz = 42;
x.call();
x.[](42);
x.[]=(42, 42);
x = x.+(1);
x = x.+(1);
let finalNever? #t1 = y in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{Never}.foo();
let finalNever? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar;
let finalNever? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42;
let finalNever? #t4 = y in #t4.{core::Object::==}(null) ?{dynamic} null : #t4{Never}.call();
let finalNever? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42);
let finalNever? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42);
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
y.foo(); // Error.
^^^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
y.bar; // Error.
^^^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
y.baz = 42; // Error.
^^^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named 'call'.
y(); // Error.
^";
y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The method '+' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
y++; // Error.
^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The method '+' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
y += 1; // Error.
^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The method '[]' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '[]'.
y[42]; // Error.
^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The method '[]=' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '[]='.
y[42] = 42; // Error.
^";
}
static method main() → dynamic {}

View file

@ -0,0 +1,139 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'foo'.
// y.foo(); // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Warning: Method 'foo' is called on 'Never' which is potentially null.
// Try calling using ?. instead.
// y.foo(); // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
// y.bar; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Warning: Property 'bar' is accessed on 'Never' which is potentially null.
// Try accessing using ?. instead.
// y.bar; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
// y.baz = 42; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Warning: Property 'baz' is accessed on 'Never' which is potentially null.
// Try accessing using ?. instead.
// y.baz = 42; // Error.
// ^^^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named 'call'.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Warning: Method 'call' is called on 'Never' which is potentially null.
// Try calling using ?. instead.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Warning: Expression of type 'Never' is used as a function, but it's potentially null.
// Try calling using ?.call instead.
// y(); // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The method '+' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '+'.
// y++; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Warning: Operator '+' is called on 'Never' which is potentially null.
// y++; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The method '+' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '+'.
// y += 1; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Warning: Operator '+' is called on 'Never' which is potentially null.
// y += 1; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The method '[]' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '[]'.
// y[42]; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Warning: Operator '[]' is called on 'Never' which is potentially null.
// y[42]; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The method '[]=' isn't defined for the class 'Never'.
// Try correcting the name to the name of an existing method, or defining a method named '[]='.
// y[42] = 42; // Error.
// ^
//
// pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Warning: Operator '[]=' is called on 'Never' which is potentially null.
// y[42] = 42; // Error.
// ^
//
import self as self;
import "dart:core" as core;
static method foo(Neverx, Never? y) → dynamic {
core::String local0 = y.{core::Object::toString}();
core::int local1 = y.{core::Object::hashCode};
x.foo();
x.bar;
x.baz = 42;
x.call();
x.[](42);
x.[]=(42, 42);
x = x.+(1);
x = x.+(1);
let finalNever? #t1 = y in #t1.{core::Object::==}(null) ?{dynamic} null : #t1{Never}.foo();
let finalNever? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar;
let finalNever? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42;
let finalNever? #t4 = y in #t4.{core::Object::==}(null) ?{dynamic} null : #t4{Never}.call();
let finalNever? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42);
let finalNever? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42);
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:24:5: Error: The method 'foo' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named 'foo'.
y.foo(); // Error.
^^^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:25:5: Error: The getter 'bar' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'bar'.
y.bar; // Error.
^^^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:26:5: Error: The setter 'baz' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing setter, or defining a setter or field named 'baz'.
y.baz = 42; // Error.
^^^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:27:4: Error: The method 'call' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named 'call'.
y(); // Error.
^";
y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:28:4: Error: The method '+' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
y++; // Error.
^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
y = invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:29:5: Error: The method '+' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
y += 1; // Error.
^" as{TypeError,ForDynamic,ForNonNullableByDefault} Never?;
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30:4: Error: The method '[]' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '[]'.
y[42]; // Error.
^";
invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:31:4: Error: The method '[]=' isn't defined for the class 'Never'.
Try correcting the name to the name of an existing method, or defining a method named '[]='.
y[42] = 42; // Error.
^";
}
static method main() → dynamic {}

View file

@ -1241,6 +1241,7 @@ nnbd/member_inheritance_from_opt_out: TextSerializationFailure
nnbd/messages_with_types_opt_in: TypeCheckError
nnbd/messages_with_types_opt_out: TypeCheckError
nnbd/missing_required_named_parameter: TextSerializationFailure
nnbd/never_receiver: TextSerializationFailure
nnbd/nnbd_opt_out_language_version: TextSerializationFailure
nnbd/nnbd_opt_out_language_version_try_to_trick: TextSerializationFailure
nnbd/no_null_shorting: TextSerializationFailure

View file

@ -249,6 +249,10 @@ super method declares ${superParameter.type}
if (receiver is DynamicType) {
return;
}
if (receiver is NeverType &&
receiver.nullability == Nullability.nonNullable) {
return;
}
// Permit any invocation on Function type.
if (receiver == environment.coreTypes.functionLegacyRawType &&