From 2414b293e1a6756bd8e0b32d3fad4927ec38076f Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Fri, 25 Sep 2020 08:35:03 +0000 Subject: [PATCH 1/4] [cfe] Throw error on exhaustive switch and expression of type Never This requires a change to flow analysis that does not promote expressions to Never through is-tests and equality tests. Change-Id: Iec2ba5b78e61d205ad21dad6f07dbdb25fc746d3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/163380 Reviewed-by: Dmitry Stefantsov --- .../lib/src/flow_analysis/flow_analysis.dart | 37 +- .../lib/src/messages/codes_generated.dart | 39 ++ .../src/api_prototype/compiler_options.dart | 4 + .../lib/src/base/command_line_options.dart | 1 + .../lib/src/base/processed_options.dart | 2 + .../src/fasta/kernel/inference_visitor.dart | 62 +- .../lib/src/fasta/source/source_loader.dart | 3 + .../fasta/type_inference/type_inferrer.dart | 42 +- pkg/front_end/messages.status | 8 + pkg/front_end/messages.yaml | 14 + .../test/spell_checking_list_code.txt | 3 + .../test/spell_checking_list_common.txt | 1 + .../test/spell_checking_list_tests.txt | 5 + .../test/static_types/static_type_test.dart | 35 + .../nnbd/extension_never.dart.weak.expect | 7 +- ...tension_never.dart.weak.transformed.expect | 7 +- .../nnbd/issue39822.dart.weak.expect | 3 +- .../issue39822.dart.weak.transformed.expect | 3 +- .../nnbd/issue41156.dart.weak.expect | 37 +- .../issue41156.dart.weak.transformed.expect | 37 +- .../nnbd/issue41273.dart.weak.expect | 41 +- .../issue41273.dart.weak.transformed.expect | 41 +- .../nnbd/issue42758.dart.weak.expect | 313 ++++----- .../issue42758.dart.weak.transformed.expect | 355 +++++----- .../nnbd/never_calls.dart.weak.expect | 39 +- .../never_calls.dart.weak.transformed.expect | 39 +- .../nnbd/never_equals.dart.weak.expect | 3 +- .../never_equals.dart.weak.transformed.expect | 3 +- .../nnbd/never_receiver.dart.weak.expect | 39 +- ...ever_receiver.dart.weak.transformed.expect | 39 +- .../nnbd/return_null.dart.weak.expect | 19 +- .../return_null.dart.weak.transformed.expect | 39 +- .../switch_nullable_enum.dart.weak.expect | 12 +- ...nullable_enum.dart.weak.transformed.expect | 12 +- ...switch_redesign_fall_over.dart.weak.expect | 5 +- ...ign_fall_over.dart.weak.transformed.expect | 5 +- .../type_parameter_types.dart.weak.expect | 23 +- ...rameter_types.dart.weak.transformed.expect | 23 +- .../nnbd_mixed/never_opt_out.dart.weak.expect | 5 +- .../testcases/nnbd_mixed/unsound_checks.dart | 286 ++++++++ ...unsound_checks.dart.textual_outline.expect | 49 ++ .../unsound_checks.dart.weak.expect | 621 ++++++++++++++++++ ...nsound_checks.dart.weak.transformed.expect | 621 ++++++++++++++++++ .../nnbd_mixed/unsound_checks_lib.dart | 196 ++++++ .../testcases/textual_outline.status | 1 + pkg/front_end/tool/_fasta/command_line.dart | 6 +- pkg/kernel/lib/core_types.dart | 7 + sdk/lib/internal/errors.dart | 13 + 48 files changed, 2637 insertions(+), 568 deletions(-) create mode 100644 pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart create mode 100644 pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect create mode 100644 pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart index c2f43d8187f40..2db5055ccb4cf 100644 --- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart +++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart @@ -449,6 +449,26 @@ abstract class FlowAnalysis _wrapped.forEach_end()); } + @override + void forwardExpression(Expression newExpression, Expression oldExpression) { + return _wrap('forwardExpression($newExpression, $oldExpression)', + () => _wrapped.forwardExpression(newExpression, oldExpression)); + } + @override void functionExpression_begin(Node node) { _wrap('functionExpression_begin($node)', @@ -2655,6 +2681,13 @@ class _FlowAnalysisImpl info = @@ -2885,9 +2918,7 @@ class _FlowAnalysisImpl codeNeverReachableSwitchDefaultError = + messageNeverReachableSwitchDefaultError; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageNeverReachableSwitchDefaultError = const MessageCode( + "NeverReachableSwitchDefaultError", + message: + r"""`null` encountered as case in a switch expression with a non-nullable enum type."""); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeNeverReachableSwitchDefaultWarning = + messageNeverReachableSwitchDefaultWarning; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageNeverReachableSwitchDefaultWarning = const MessageCode( + "NeverReachableSwitchDefaultWarning", + severity: Severity.warning, + message: + r"""The default case is not reachable with sound null safety because the switch expression is non-nullable."""); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeNeverValueError = messageNeverValueError; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageNeverValueError = const MessageCode("NeverValueError", + message: + r"""`null` encountered as the result from expression with type `Never`."""); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeNeverValueWarning = messageNeverValueWarning; + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const MessageCode messageNeverValueWarning = const MessageCode( + "NeverValueWarning", + severity: Severity.warning, + message: + r"""The expression can not result in a value with sound null safety because the expression type is `Never`."""); + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Template< Message Function(Token token)> templateNoFormals = const Template< diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart index 7452b96741562..23cf4a13730d5 100644 --- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart +++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart @@ -233,6 +233,10 @@ class CompilerOptions { /// 'non-nullable' is enabled. NnbdMode nnbdMode = NnbdMode.Weak; + /// Whether to emit a warning when a ReachabilityError is thrown to ensure + /// soundness in mixed mode. + bool warnOnReachabilityCheck = false; + /// The current sdk version string, e.g. "2.6.0-edge.sha1hash". /// For instance used for language versioning (specifying the maximum /// version). diff --git a/pkg/front_end/lib/src/base/command_line_options.dart b/pkg/front_end/lib/src/base/command_line_options.dart index 776fc117c4abb..9640a433ac8ec 100644 --- a/pkg/front_end/lib/src/base/command_line_options.dart +++ b/pkg/front_end/lib/src/base/command_line_options.dart @@ -40,4 +40,5 @@ class Flags { static const String singleRootScheme = "--single-root-scheme"; static const String verbose = "--verbose"; static const String verify = "--verify"; + static const String warnOnReachabilityCheck = "--warn-on-reachability-check"; } diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart index ed2dc754652ab..6682c79958e34 100644 --- a/pkg/front_end/lib/src/base/processed_options.dart +++ b/pkg/front_end/lib/src/base/processed_options.dart @@ -181,6 +181,8 @@ class ProcessedOptions { NnbdMode get nnbdMode => _raw.nnbdMode; + bool get warnOnReachabilityCheck => _raw.warnOnReachabilityCheck; + /// The entry-points provided to the compiler. final List inputs; diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart index b053283061ba2..52fae8a003bd6 100644 --- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart +++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart @@ -355,7 +355,7 @@ class InferenceVisitor for (Expression expression in node.expressions) { expressionResults.add(inferrer.inferExpression( expression, const UnknownType(), !inferrer.isTopLevel, - isVoidAllowed: true)); + isVoidAllowed: true, forEffect: true)); } List body = []; for (int index = 0; index < expressionResults.length; index++) { @@ -711,7 +711,7 @@ class InferenceVisitor StatementInferenceResult visitExpressionStatement(ExpressionStatement node) { ExpressionInferenceResult result = inferrer.inferExpression( node.expression, const UnknownType(), !inferrer.isTopLevel, - isVoidAllowed: true); + isVoidAllowed: true, forEffect: true); node.expression = result.expression..parent = node; return const StatementInferenceResult(); } @@ -5083,7 +5083,11 @@ class InferenceVisitor @override ExpressionInferenceResult visitRethrow(Rethrow node, DartType typeContext) { inferrer.flowAnalysis.handleExit(); - return new ExpressionInferenceResult(const BottomType(), node); + return new ExpressionInferenceResult( + inferrer.isNonNullableByDefault + ? const NeverType(Nullability.nonNullable) + : const BottomType(), + node); } @override @@ -5375,6 +5379,7 @@ class InferenceVisitor inferrer.flowAnalysis.switchStatement_expressionEnd(node); bool hasDefault = false; + bool lastCaseTerminates = true; for (int caseIndex = 0; caseIndex < node.cases.length; ++caseIndex) { SwitchCaseImpl switchCase = node.cases[caseIndex]; hasDefault = hasDefault || switchCase.isDefault; @@ -5441,19 +5446,56 @@ class InferenceVisitor switchCase.body = bodyResult.statement..parent = switchCase; } - if (!inferrer.isTopLevel && inferrer.isNonNullableByDefault) { - // The last case block is allowed to complete normally. - if (caseIndex < node.cases.length - 1 && - inferrer.flowAnalysis.isReachable) { - inferrer.library.addProblem(messageSwitchCaseFallThrough, - switchCase.fileOffset, noLength, inferrer.helper.uri); + if (inferrer.isNonNullableByDefault) { + lastCaseTerminates = !inferrer.flowAnalysis.isReachable; + if (!inferrer.isTopLevel) { + // The last case block is allowed to complete normally. + if (caseIndex < node.cases.length - 1 && + inferrer.flowAnalysis.isReachable) { + inferrer.library.addProblem(messageSwitchCaseFallThrough, + switchCase.fileOffset, noLength, inferrer.helper.uri); + } } } } bool isExhaustive = hasDefault || (enumFields != null && enumFields.isEmpty); inferrer.flowAnalysis.switchStatement_end(isExhaustive); - return const StatementInferenceResult(); + Statement replacement; + if (isExhaustive && + !hasDefault && + inferrer.shouldThrowUnsoundnessException) { + if (!lastCaseTerminates) { + LabeledStatement breakTarget; + if (node.parent is LabeledStatement) { + breakTarget = node.parent; + } else { + replacement = breakTarget = new LabeledStatement(node); + } + + SwitchCase lastCase = node.cases.last; + Statement body = lastCase.body; + if (body is Block) { + body.statements.add(new BreakStatementImpl(isContinue: false) + ..target = breakTarget + ..targetStatement = node + ..fileOffset = node.fileOffset); + } + } + node.cases.add(new SwitchCase( + [], + [], + _createExpressionStatement(inferrer.createReachabilityError( + node.fileOffset, + messageNeverReachableSwitchDefaultError, + messageNeverReachableSwitchDefaultWarning)), + isDefault: true) + ..fileOffset = node.fileOffset + ..parent = node); + } + return replacement != null + ? new StatementInferenceResult.single(replacement) + : const StatementInferenceResult(); } @override diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart index f5f0588fe26a0..b47a385269430 100644 --- a/pkg/front_end/lib/src/fasta/source/source_loader.dart +++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart @@ -1486,6 +1486,9 @@ class Symbol { } T unsafeCast(Object v) {} +class ReachabilityError { + ReachabilityError([message]); +} """; /// A minimal implementation of dart:typed_data that is sufficient to create an diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart index e6cee2a10f76d..88de58db58344 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart @@ -275,6 +275,33 @@ class TypeInferrerImpl implements TypeInferrer { return type.withDeclaredNullability(library.nonNullable); } + Expression createReachabilityError( + int fileOffset, Message errorMessage, Message warningMessage) { + if (library.loader.target.context.options.warnOnReachabilityCheck && + warningMessage != null) { + helper?.addProblem(warningMessage, fileOffset, noLength); + } + Arguments arguments; + if (errorMessage != null) { + arguments = new Arguments( + [new StringLiteral(errorMessage.message)..fileOffset = fileOffset]) + ..fileOffset = fileOffset; + } else { + arguments = new Arguments([])..fileOffset = fileOffset; + } + assert(coreTypes.reachabilityErrorConstructor != null); + return new Throw( + new ConstructorInvocation( + coreTypes.reachabilityErrorConstructor, arguments) + ..fileOffset = fileOffset) + ..fileOffset = fileOffset; + } + + /// Returns `true` if exceptions should be thrown in paths reachable only due + /// to unsoundness in flow analysis in mixed mode. + bool get shouldThrowUnsoundnessException => + isNonNullableByDefault && nnbdMode != NnbdMode.Strong; + void registerIfUnreachableForTesting(TreeNode node, {bool isReachable}) { if (dataForTesting == null) return; isReachable ??= flowAnalysis.isReachable; @@ -1561,7 +1588,7 @@ class TypeInferrerImpl implements TypeInferrer { /// the expression type and calls the appropriate specialized "infer" method. ExpressionInferenceResult inferExpression( Expression expression, DartType typeContext, bool typeNeeded, - {bool isVoidAllowed: false}) { + {bool isVoidAllowed: false, bool forEffect: false}) { registerIfUnreachableForTesting(expression); // `null` should never be used as the type context. An instance of @@ -1597,6 +1624,19 @@ class TypeInferrerImpl implements TypeInferrer { } if (coreTypes.isBottom(result.inferredType)) { flowAnalysis.handleExit(); + if (shouldThrowUnsoundnessException && + // Don't throw on expressions that inherently return the bottom type. + !(result.nullAwareAction is Throw || + result.nullAwareAction is Rethrow || + result.nullAwareAction is InvalidExpression)) { + Expression replacement = createLet( + createVariable(result.expression, result.inferredType), + createReachabilityError(expression.fileOffset, + messageNeverValueError, messageNeverValueWarning)); + flowAnalysis.forwardExpression(replacement, result.expression); + result = + new ExpressionInferenceResult(result.inferredType, replacement); + } } return result; } diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status index 2db105d16e519..3a3eecabf9534 100644 --- a/pkg/front_end/messages.status +++ b/pkg/front_end/messages.status @@ -497,6 +497,14 @@ NamedFunctionExpression/example: Fail NamedMixinOverride/analyzerCode: Fail NamedMixinOverride/example: Fail NativeClauseShouldBeAnnotation/example: Fail +NeverReachableSwitchDefaultError/analyzerCode: Fail +NeverReachableSwitchDefaultError/example: Fail +NeverReachableSwitchDefaultWarning/analyzerCode: Fail +NeverReachableSwitchDefaultWarning/example: Fail +NeverValueError/analyzerCode: Fail +NeverValueError/example: Fail +NeverValueWarning/analyzerCode: Fail +NeverValueWarning/example: Fail NoFormals/example: Fail NonAgnosticConstant/analyzerCode: Fail NonAgnosticConstant/example: Fail diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index 4adf9144c6c07..7d1d99786b0e2 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -4307,3 +4307,17 @@ NonVoidReturnSetter: script: - int set setter(_) {} - dynamic set setter(_) {} + +NeverReachableSwitchDefaultError: + template: "`null` encountered as case in a switch expression with a non-nullable enum type." + +NeverReachableSwitchDefaultWarning: + template: "The default case is not reachable with sound null safety because the switch expression is non-nullable." + severity: WARNING + +NeverValueError: + template: "`null` encountered as the result from expression with type `Never`." + +NeverValueWarning: + template: "The expression can not result in a value with sound null safety because the expression type is `Never`." + severity: WARNING diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt index fc4f4d0b2e4bf..13b507da1fbc1 100644 --- a/pkg/front_end/test/spell_checking_list_code.txt +++ b/pkg/front_end/test/spell_checking_list_code.txt @@ -863,6 +863,7 @@ rb rc re reach +reachability react realign realise @@ -1203,6 +1204,8 @@ unreachable unseen unshadowed unsortable +unsound +unsoundness unwrapper unwraps unwritten diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt index 0ca4f6dc81681..77a6578a62454 100644 --- a/pkg/front_end/test/spell_checking_list_common.txt +++ b/pkg/front_end/test/spell_checking_list_common.txt @@ -1484,6 +1484,7 @@ informally information informational informs +inherently inherit inheritable inheritance diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt index 5aa51163c9c64..db45c6e080036 100644 --- a/pkg/front_end/test/spell_checking_list_tests.txt +++ b/pkg/front_end/test/spell_checking_list_tests.txt @@ -272,6 +272,7 @@ gallery gamma gave gc +gcd goo google graphic @@ -302,6 +303,8 @@ illustrate image images implementor +in1 +in2 inclosure increased incrementally @@ -437,6 +440,8 @@ operate ops optimal oracle +out1 +out2 outbound overlay pack diff --git a/pkg/front_end/test/static_types/static_type_test.dart b/pkg/front_end/test/static_types/static_type_test.dart index d67f46504a639..0bed0cc634cd0 100644 --- a/pkg/front_end/test/static_types/static_type_test.dart +++ b/pkg/front_end/test/static_types/static_type_test.dart @@ -103,6 +103,9 @@ class StaticTypeDataExtractor extends CfeDataExtractor { @override String computeNodeValue(Id id, TreeNode node) { + if (isSkippedExpression(node)) { + return null; + } if (node is Expression) { DartType type = node.getStaticType(_staticTypeContext); return typeToText(type); @@ -120,6 +123,37 @@ class StaticTypeDataExtractor extends CfeDataExtractor { return null; } + bool isNewReachabilityError(object) { + if (object is ConstructorInvocation) { + Class cls = object.target.enclosingClass; + return cls.name == 'ReachabilityError' && + cls.enclosingLibrary.importUri.scheme == 'dart' && + cls.enclosingLibrary.importUri.path == '_internal'; + } + return false; + } + + bool isNewReachabilityErrorArgument(object) { + return object is StringLiteral && + isNewReachabilityError(object.parent.parent); + } + + bool isThrowReachabilityError(object) { + return object is Throw && isNewReachabilityError(object.expression); + } + + bool isReachabilityErrorLet(object) { + return object is Let && + (isThrowReachabilityError(object.variable.initializer) || + isThrowReachabilityError(object.body)); + } + + bool isSkippedExpression(object) => + isReachabilityErrorLet(object) || + isThrowReachabilityError(object) || + isNewReachabilityErrorArgument(object) || + isNewReachabilityError(object); + ActualData mergeData( ActualData value1, ActualData value2) { if (value1.object is NullLiteral && value2.object is! NullLiteral) { @@ -129,6 +163,7 @@ class StaticTypeDataExtractor extends CfeDataExtractor { // Skip `null` literals from null-aware operations. return value1; } + return new ActualData(value1.id, '${value1.value}|${value2.value}', value1.uri, value1.offset, value1.object); } diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.weak.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.weak.expect index 5c20141ece8d8..5c94642ee157b 100644 --- a/pkg/front_end/testcases/nnbd/extension_never.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/extension_never.dart.weak.expect @@ -1,5 +1,6 @@ library /*isNonNullableByDefault*/; import self as self; +import "dart:_internal" as _in; extension Extension on Never { method extensionMethod = self::Extension|extensionMethod; @@ -9,10 +10,10 @@ static method Extension|extensionMethod(final Never #this) → dynamic {} static method Extension|get#extensionMethod(final Never #this) → () → dynamic return () → dynamic => self::Extension|extensionMethod(#this); static method implicitAccess(Never never) → dynamic { - never.extensionMethod(); - never.missingMethod(); + let final Never #t1 = (let final Never #t2 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).extensionMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t3 = (let final Never #t4 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).missingMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method explicitAccess(Never never) → dynamic { - self::Extension|extensionMethod(never); + self::Extension|extensionMethod(let final Never #t5 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/extension_never.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/extension_never.dart.weak.transformed.expect index 5c20141ece8d8..5c94642ee157b 100644 --- a/pkg/front_end/testcases/nnbd/extension_never.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/extension_never.dart.weak.transformed.expect @@ -1,5 +1,6 @@ library /*isNonNullableByDefault*/; import self as self; +import "dart:_internal" as _in; extension Extension on Never { method extensionMethod = self::Extension|extensionMethod; @@ -9,10 +10,10 @@ static method Extension|extensionMethod(final Never #this) → dynamic {} static method Extension|get#extensionMethod(final Never #this) → () → dynamic return () → dynamic => self::Extension|extensionMethod(#this); static method implicitAccess(Never never) → dynamic { - never.extensionMethod(); - never.missingMethod(); + let final Never #t1 = (let final Never #t2 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).extensionMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t3 = (let final Never #t4 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).missingMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method explicitAccess(Never never) → dynamic { - self::Extension|extensionMethod(never); + self::Extension|extensionMethod(let final Never #t5 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/issue39822.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue39822.dart.weak.expect index 14a65982f9c01..43043890f900d 100644 --- a/pkg/front_end/testcases/nnbd/issue39822.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/issue39822.dart.weak.expect @@ -1,9 +1,10 @@ library /*isNonNullableByDefault*/; import self as self; import "dart:core" as core; +import "dart:_internal" as _in; static method foo(core::Null? x) → dynamic { - self::bar(x!); + self::bar(let final Never #t1 = x! in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); } static method bar(core::int y) → dynamic {} static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/issue39822.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue39822.dart.weak.transformed.expect index 14a65982f9c01..43043890f900d 100644 --- a/pkg/front_end/testcases/nnbd/issue39822.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/issue39822.dart.weak.transformed.expect @@ -1,9 +1,10 @@ library /*isNonNullableByDefault*/; import self as self; import "dart:core" as core; +import "dart:_internal" as _in; static method foo(core::Null? x) → dynamic { - self::bar(x!); + self::bar(let final Never #t1 = x! in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); } static method bar(core::int y) → dynamic {} static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect index 11217a114c893..3ced12689e0b1 100644 --- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect @@ -36,6 +36,7 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; import "dart:async" as asy; static method throwing() → Never @@ -48,12 +49,12 @@ static method main() → void { (core::int) → core::String x3 = (core::int v) → Never { return throw v; }; - (core::int) → core::String x4 = (core::int v) → Never => self::throwing(); + (core::int) → core::String x4 = (core::int v) → Never => let final Never #t1 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); (core::int) → core::String x5 = (core::int v) → Never { - self::throwing(); + let final Never #t2 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); }; (core::int) → core::String x6 = (core::int v) → Never { - return self::throwing(); + return let final Never #t3 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); }; (core::int) → asy::Future y1 = (core::int v) → asy::Future async => throw v; (core::int) → asy::Future y2 = (core::int v) → asy::Future async { @@ -62,12 +63,12 @@ static method main() → void { (core::int) → asy::Future y3 = (core::int v) → asy::Future async { return throw v; }; - (core::int) → asy::Future y4 = (core::int v) → asy::Future async => self::throwing(); + (core::int) → asy::Future y4 = (core::int v) → asy::Future async => let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); (core::int) → asy::Future y5 = (core::int v) → asy::Future async { - self::throwing(); + let final Never #t5 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); }; (core::int) → asy::Future y6 = (core::int v) → asy::Future async { - return self::throwing(); + return let final Never #t6 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); }; } static method errors() → void async { @@ -77,7 +78,7 @@ static method errors() → void async { } on core::Object catch(final core::Object _) { } - return let final #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. String Function(int) x2 = (int v) /* error */ { ^" in null; }; @@ -87,27 +88,27 @@ static method errors() → void async { } on core::Object catch(final core::Object _) { } - return let final #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. String Function(int) x3 = (int v) /* error */ { ^" in null; }; (core::int) → core::String x5 = (core::int v) → core::String { try { - self::throwing(); + let final Never #t9 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } on core::Object catch(final core::Object _) { } - return let final #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. String Function(int) x5 = (int v) /* error */ { ^" in null; }; (core::int) → core::String x6 = (core::int v) → core::String { try { - return self::throwing(); + return let final Never #t11 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } on core::Object catch(final core::Object _) { } - return let final #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. String Function(int) x6 = (int v) /* error */ { ^" in null; }; @@ -117,7 +118,7 @@ static method errors() → void async { } on core::Object catch(final core::Object _) { } - return let final #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. Future Function(int) y2 = (int v) async /* error */ { ^" in null; }; @@ -127,27 +128,27 @@ static method errors() → void async { } on core::Object catch(final core::Object _) { } - return let final #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. Future Function(int) y3 = (int v) async /* error */ { ^" in null; }; (core::int) → asy::Future y5 = (core::int v) → asy::Future async { try { - self::throwing(); + let final Never #t15 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } on core::Object catch(final core::Object _) { } - return let final #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t16 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. Future Function(int) y5 = (int v) async /* error */ { ^" in null; }; (core::int) → asy::Future y6 = (core::int v) → asy::Future async { try { - return self::throwing(); + return let final Never #t17 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } on core::Object catch(final core::Object _) { } - return let final #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t18 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. Future Function(int) y6 = (int v) async /* error */ { ^" in null; }; diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect index 07174dc9ec03b..73ca4fafe2303 100644 --- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect @@ -36,6 +36,7 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; import "dart:async" as asy; static method throwing() → Never @@ -48,12 +49,12 @@ static method main() → void { (core::int) → core::String x3 = (core::int v) → Never { return throw v; }; - (core::int) → core::String x4 = (core::int v) → Never => self::throwing(); + (core::int) → core::String x4 = (core::int v) → Never => let final Never #t1 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); (core::int) → core::String x5 = (core::int v) → Never { - self::throwing(); + let final Never #t2 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); }; (core::int) → core::String x6 = (core::int v) → Never { - return self::throwing(); + return let final Never #t3 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); }; (core::int) → asy::Future y1 = (core::int v) → asy::Future /* originally async */ { final asy::_AsyncAwaitCompleter :async_completer = new asy::_AsyncAwaitCompleter::•(); @@ -147,7 +148,7 @@ static method main() → void { try { #L4: { - :return_value = self::throwing(); + :return_value = let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); break #L4; } asy::_completeOnAsyncReturn(:async_completer, :return_value); @@ -174,7 +175,7 @@ static method main() → void { try { #L5: { - self::throwing(); + let final Never #t5 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -200,7 +201,7 @@ static method main() → void { try { #L6: { - :return_value = self::throwing(); + :return_value = let final Never #t6 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); break #L6; } asy::_completeOnAsyncReturn(:async_completer, :return_value); @@ -234,7 +235,7 @@ static method errors() → void /* originally async */ { } on core::Object catch(final core::Object _) { } - return let final #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. String Function(int) x2 = (int v) /* error */ { ^" in null; }; @@ -244,27 +245,27 @@ static method errors() → void /* originally async */ { } on core::Object catch(final core::Object _) { } - return let final #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. String Function(int) x3 = (int v) /* error */ { ^" in null; }; (core::int) → core::String x5 = (core::int v) → core::String { try { - self::throwing(); + let final Never #t9 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } on core::Object catch(final core::Object _) { } - return let final #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. String Function(int) x5 = (int v) /* error */ { ^" in null; }; (core::int) → core::String x6 = (core::int v) → core::String { try { - return self::throwing(); + return let final Never #t11 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } on core::Object catch(final core::Object _) { } - return let final #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + return let final #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null. String Function(int) x6 = (int v) /* error */ { ^" in null; }; @@ -285,7 +286,7 @@ static method errors() → void /* originally async */ { } on core::Object catch(final core::Object _) { } - :return_value = let final #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + :return_value = let final #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. Future Function(int) y2 = (int v) async /* error */ { ^" in null; break #L8; @@ -320,7 +321,7 @@ static method errors() → void /* originally async */ { } on core::Object catch(final core::Object _) { } - :return_value = let final #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + :return_value = let final #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. Future Function(int) y3 = (int v) async /* error */ { ^" in null; break #L9; @@ -350,11 +351,11 @@ static method errors() → void /* originally async */ { #L10: { try { - self::throwing(); + let final Never #t15 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } on core::Object catch(final core::Object _) { } - :return_value = let final #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + :return_value = let final #t16 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. Future Function(int) y5 = (int v) async /* error */ { ^" in null; break #L10; @@ -384,12 +385,12 @@ static method errors() → void /* originally async */ { #L11: { try { - :return_value = self::throwing(); + :return_value = let final Never #t17 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); break #L11; } on core::Object catch(final core::Object _) { } - :return_value = let final #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. + :return_value = let final #t18 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null. Future Function(int) y6 = (int v) async /* error */ { ^" in null; break #L11; diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.weak.expect index eff260bc634cd..8c49c0f274d5e 100644 --- a/pkg/front_end/testcases/nnbd/issue41273.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/issue41273.dart.weak.expect @@ -1,29 +1,30 @@ library /*isNonNullableByDefault*/; import self as self; +import "dart:_internal" as _in; import "dart:core" as core; static method test(dynamic x) → void { if(x is{ForNonNullableByDefault} Never) { - Never n1 = x{Never}.toString(); - Never n2 = x{Never}.runtimeType; - Never n3 = x{Never}.someGetter; - Never n4 = x{Never}.someMethod(); - Never n5 = x{Never}.+(x{Never}); - Never n6 = x{Never}.[](x{Never}); - Never n7 = x{Never}.call(); - Never n8 = x{Never}.runtimeType(); - Never n9 = x{Never}.toString; - x{Never}.runtimeType = core::Object; - x{Never}.toString = () → core::String => ""; - Never v1 = x{Never}.toString(); - Never v2 = x{Never}.runtimeType; - Never v3 = x{Never}.someGetter; - Never v4 = x{Never}.someMethod(); - Never v5 = x{Never}.+(x{Never}); - Never v6 = x{Never}.[](x{Never}); - Never v7 = x{Never}.call(); - Never v8 = x{Never}.runtimeType(); - Never v9 = x{Never}.toString; + Never n1 = let final Never #t1 = (let final Never #t2 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n2 = let final Never #t3 = (let final Never #t4 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n3 = let final Never #t5 = (let final Never #t6 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n4 = let final Never #t7 = (let final Never #t8 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n5 = let final Never #t9 = (let final Never #t10 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(let final Never #t11 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n6 = let final Never #t12 = (let final Never #t13 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](let final Never #t14 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n7 = let final Never #t15 = (let final Never #t16 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n8 = let final Never #t17 = (let final Never #t18 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n9 = let final Never #t19 = (let final Never #t20 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + (let final Never #t21 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType = core::Object; + (let final Never #t22 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString = () → core::String => ""; + Never v1 = let final Never #t23 = (let final Never #t24 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t25 = (let final Never #t26 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v3 = let final Never #t27 = (let final Never #t28 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v4 = let final Never #t29 = (let final Never #t30 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v5 = let final Never #t31 = (let final Never #t32 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(let final Never #t33 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v6 = let final Never #t34 = (let final Never #t35 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](let final Never #t36 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v7 = let final Never #t37 = (let final Never #t38 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v8 = let final Never #t39 = (let final Never #t40 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v9 = let final Never #t41 = (let final Never #t42 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } } static method main() → dynamic { diff --git a/pkg/front_end/testcases/nnbd/issue41273.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41273.dart.weak.transformed.expect index eff260bc634cd..8c49c0f274d5e 100644 --- a/pkg/front_end/testcases/nnbd/issue41273.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/issue41273.dart.weak.transformed.expect @@ -1,29 +1,30 @@ library /*isNonNullableByDefault*/; import self as self; +import "dart:_internal" as _in; import "dart:core" as core; static method test(dynamic x) → void { if(x is{ForNonNullableByDefault} Never) { - Never n1 = x{Never}.toString(); - Never n2 = x{Never}.runtimeType; - Never n3 = x{Never}.someGetter; - Never n4 = x{Never}.someMethod(); - Never n5 = x{Never}.+(x{Never}); - Never n6 = x{Never}.[](x{Never}); - Never n7 = x{Never}.call(); - Never n8 = x{Never}.runtimeType(); - Never n9 = x{Never}.toString; - x{Never}.runtimeType = core::Object; - x{Never}.toString = () → core::String => ""; - Never v1 = x{Never}.toString(); - Never v2 = x{Never}.runtimeType; - Never v3 = x{Never}.someGetter; - Never v4 = x{Never}.someMethod(); - Never v5 = x{Never}.+(x{Never}); - Never v6 = x{Never}.[](x{Never}); - Never v7 = x{Never}.call(); - Never v8 = x{Never}.runtimeType(); - Never v9 = x{Never}.toString; + Never n1 = let final Never #t1 = (let final Never #t2 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n2 = let final Never #t3 = (let final Never #t4 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n3 = let final Never #t5 = (let final Never #t6 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n4 = let final Never #t7 = (let final Never #t8 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n5 = let final Never #t9 = (let final Never #t10 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(let final Never #t11 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n6 = let final Never #t12 = (let final Never #t13 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](let final Never #t14 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n7 = let final Never #t15 = (let final Never #t16 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n8 = let final Never #t17 = (let final Never #t18 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never n9 = let final Never #t19 = (let final Never #t20 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + (let final Never #t21 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType = core::Object; + (let final Never #t22 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString = () → core::String => ""; + Never v1 = let final Never #t23 = (let final Never #t24 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t25 = (let final Never #t26 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v3 = let final Never #t27 = (let final Never #t28 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).someGetter in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v4 = let final Never #t29 = (let final Never #t30 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).someMethod() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v5 = let final Never #t31 = (let final Never #t32 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(let final Never #t33 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v6 = let final Never #t34 = (let final Never #t35 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](let final Never #t36 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v7 = let final Never #t37 = (let final Never #t38 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v8 = let final Never #t39 = (let final Never #t40 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v9 = let final Never #t41 = (let final Never #t42 = x{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } } static method main() → dynamic { diff --git a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.expect index 6e4b63d00b6db..ffb6307abf7f9 100644 --- a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.expect @@ -76,218 +76,219 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; import "dart:collection" as col; static method test1(Never n1, Never? n2, core::Null? n3) → dynamic { core::List l1 = block { final core::List #t1 = []; - for (final Never #t2 in n1) + for (final Never #t2 in let final Never #t3 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) #t1.{core::List::add}(#t2); } =>#t1; core::List l2 = block { - final core::List #t3 = []; - final core::Iterable? #t4 = n1; - if(!#t4.{core::Object::==}(null)) - for (final Never #t5 in #t4{core::Iterable}) - #t3.{core::List::add}(#t5); - } =>#t3; + final core::List #t4 = []; + final core::Iterable? #t5 = let final Never #t6 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t5.{core::Object::==}(null)) + for (final Never #t7 in #t5{core::Iterable}) + #t4.{core::List::add}(#t7); + } =>#t4; core::List l3 = [invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:8:16: Error: Can't spread a value with static type 'Never?'. var l3 = [...n2]; ^"]; core::List l4 = block { - final core::List #t6 = []; - final core::Iterable? #t7 = n2; - if(!#t7.{core::Object::==}(null)) - for (final Never #t8 in #t7{core::Iterable}) - #t6.{core::List::add}(#t8); - } =>#t6; + final core::List #t8 = []; + final core::Iterable? #t9 = n2; + if(!#t9.{core::Object::==}(null)) + for (final Never #t10 in #t9{core::Iterable}) + #t8.{core::List::add}(#t10); + } =>#t8; core::List l5 = [invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:10:16: Error: Can't spread a value with static type 'Null'. var l5 = [...n3]; ^"]; core::List l6 = block { - final core::List #t9 = []; - final core::Iterable? #t10 = n3; - if(!#t10.{core::Object::==}(null)) - for (final Never #t11 in #t10{core::Iterable}) - #t9.{core::List::add}(#t11); - } =>#t9; + final core::List #t11 = []; + final core::Iterable? #t12 = n3; + if(!#t12.{core::Object::==}(null)) + for (final Never #t13 in #t12{core::Iterable}) + #t11.{core::List::add}(#t13); + } =>#t11; core::Set s1 = block { - final core::Set #t12 = col::LinkedHashSet::•(); - for (final Never #t13 in n1) - #t12.{core::Set::add}(#t13); - #t12.{core::Set::add}(n1); - } =>#t12; - core::Set s2 = block { final core::Set #t14 = col::LinkedHashSet::•(); - final core::Iterable? #t15 = n1; - if(!#t15.{core::Object::==}(null)) - for (final Never #t16 in #t15{core::Iterable}) - #t14.{core::Set::add}(#t16); - #t14.{core::Set::add}(n1); + for (final Never #t15 in let final Never #t16 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) + #t14.{core::Set::add}(#t15); + #t14.{core::Set::add}(let final Never #t17 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); } =>#t14; - core::Set s3 = let final core::Set #t17 = col::LinkedHashSet::•() in let final dynamic #t18 = #t17.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'. + core::Set s2 = block { + final core::Set #t18 = col::LinkedHashSet::•(); + final core::Iterable? #t19 = let final Never #t20 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t19.{core::Object::==}(null)) + for (final Never #t21 in #t19{core::Iterable}) + #t18.{core::Set::add}(#t21); + #t18.{core::Set::add}(let final Never #t22 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t18; + core::Set s3 = let final core::Set #t23 = col::LinkedHashSet::•() in let final dynamic #t24 = #t23.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'. var s3 = {...n2, n1}; - ^") in let final dynamic #t19 = #t17.{core::Set::add}(n1) in #t17; + ^") in let final dynamic #t25 = #t23.{core::Set::add}(let final Never #t26 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in #t23; core::Set s4 = block { - final core::Set #t20 = col::LinkedHashSet::•(); - final core::Iterable? #t21 = n2; - if(!#t21.{core::Object::==}(null)) - for (final Never #t22 in #t21{core::Iterable}) - #t20.{core::Set::add}(#t22); - #t20.{core::Set::add}(n1); - } =>#t20; - core::Set s5 = let final core::Set #t23 = col::LinkedHashSet::•() in let final dynamic #t24 = #t23.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'. + final core::Set #t27 = col::LinkedHashSet::•(); + final core::Iterable? #t28 = n2; + if(!#t28.{core::Object::==}(null)) + for (final Never #t29 in #t28{core::Iterable}) + #t27.{core::Set::add}(#t29); + #t27.{core::Set::add}(let final Never #t30 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t27; + core::Set s5 = let final core::Set #t31 = col::LinkedHashSet::•() in let final dynamic #t32 = #t31.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'. var s5 = {...n3, n1}; - ^") in let final dynamic #t25 = #t23.{core::Set::add}(n1) in #t23; + ^") in let final dynamic #t33 = #t31.{core::Set::add}(let final Never #t34 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in #t31; core::Set s6 = block { - final core::Set #t26 = col::LinkedHashSet::•(); - final core::Iterable? #t27 = n3; - if(!#t27.{core::Object::==}(null)) - for (final Never #t28 in #t27{core::Iterable}) - #t26.{core::Set::add}(#t28); - #t26.{core::Set::add}(n1); - } =>#t26; + final core::Set #t35 = col::LinkedHashSet::•(); + final core::Iterable? #t36 = n3; + if(!#t36.{core::Object::==}(null)) + for (final Never #t37 in #t36{core::Iterable}) + #t35.{core::Set::add}(#t37); + #t35.{core::Set::add}(let final Never #t38 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t35; core::Map m1 = block { - final core::Map #t29 = {}; - for (final core::MapEntry #t30 in n1.{core::Map::entries}) - #t29.{core::Map::[]=}(#t30.{core::MapEntry::key}, #t30.{core::MapEntry::value}); - #t29.{core::Map::[]=}(n1, n1); - } =>#t29; + final core::Map #t39 = {}; + for (final core::MapEntry #t40 in (let final Never #t41 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries}) + #t39.{core::Map::[]=}(#t40.{core::MapEntry::key}, #t40.{core::MapEntry::value}); + #t39.{core::Map::[]=}(let final Never #t42 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t43 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t39; core::Map m2 = block { - final core::Map #t31 = {}; - final core::Map? #t32 = n1; - if(!#t32.{core::Object::==}(null)) - for (final core::MapEntry #t33 in #t32{core::Map}.{core::Map::entries}) - #t31.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value}); - #t31.{core::Map::[]=}(n1, n1); - } =>#t31; + final core::Map #t44 = {}; + final core::Map? #t45 = let final Never #t46 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t45.{core::Object::==}(null)) + for (final core::MapEntry #t47 in #t45{core::Map}.{core::Map::entries}) + #t44.{core::Map::[]=}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value}); + #t44.{core::Map::[]=}(let final Never #t48 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t49 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t44; core::Map m3 = {invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:20:16: Error: Can't spread a value with static type 'Never?'. var m3 = {...n2, n1: n1}; - ^": null, n1: n1}; + ^": null, let final Never #t50 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t51 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")}; core::Map m4 = block { - final core::Map #t34 = {}; - final core::Map? #t35 = n2; - if(!#t35.{core::Object::==}(null)) - for (final core::MapEntry #t36 in #t35{core::Map}.{core::Map::entries}) - #t34.{core::Map::[]=}(#t36.{core::MapEntry::key}, #t36.{core::MapEntry::value}); - #t34.{core::Map::[]=}(n1, n1); - } =>#t34; + final core::Map #t52 = {}; + final core::Map? #t53 = n2; + if(!#t53.{core::Object::==}(null)) + for (final core::MapEntry #t54 in #t53{core::Map}.{core::Map::entries}) + #t52.{core::Map::[]=}(#t54.{core::MapEntry::key}, #t54.{core::MapEntry::value}); + #t52.{core::Map::[]=}(let final Never #t55 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t56 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t52; core::Map m5 = {invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:22:16: Error: Can't spread a value with static type 'Null'. var m5 = {...n3, n1: n1}; - ^": null, n1: n1}; + ^": null, let final Never #t57 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t58 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")}; core::Map m6 = block { - final core::Map #t37 = {}; - final core::Map? #t38 = n3; - if(!#t38.{core::Object::==}(null)) - for (final core::MapEntry #t39 in #t38{core::Map}.{core::Map::entries}) - #t37.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value}); - #t37.{core::Map::[]=}(n1, n1); - } =>#t37; + final core::Map #t59 = {}; + final core::Map? #t60 = n3; + if(!#t60.{core::Object::==}(null)) + for (final core::MapEntry #t61 in #t60{core::Map}.{core::Map::entries}) + #t59.{core::Map::[]=}(#t61.{core::MapEntry::key}, #t61.{core::MapEntry::value}); + #t59.{core::Map::[]=}(let final Never #t62 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t63 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t59; } static method test2(self::test2::N1 n1, self::test2::N2% n2, self::test2::N3% n3) → dynamic { core::List l1 = block { - final core::List #t40 = []; - for (final Never #t41 in n1) - #t40.{core::List::add}(#t41); - } =>#t40; + final core::List #t64 = []; + for (final Never #t65 in let final self::test2::N1 #t66 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) + #t64.{core::List::add}(#t65); + } =>#t64; core::List l2 = block { - final core::List #t42 = []; - final core::Iterable? #t43 = n1; - if(!#t43.{core::Object::==}(null)) - for (final Never #t44 in #t43{core::Iterable}) - #t42.{core::List::add}(#t44); - } =>#t42; + final core::List #t67 = []; + final core::Iterable? #t68 = let final self::test2::N1 #t69 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t68.{core::Object::==}(null)) + for (final Never #t70 in #t68{core::Iterable}) + #t67.{core::List::add}(#t70); + } =>#t67; core::List l3 = [invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:30:16: Error: Can't spread a value with static type 'N2'. var l3 = [...n2]; ^"]; core::List l4 = block { - final core::List #t45 = []; - final core::Iterable? #t46 = n2; - if(!#t46.{core::Object::==}(null)) - for (final Never #t47 in #t46{core::Iterable}) - #t45.{core::List::add}(#t47); - } =>#t45; + final core::List #t71 = []; + final core::Iterable? #t72 = n2; + if(!#t72.{core::Object::==}(null)) + for (final Never #t73 in #t72{core::Iterable}) + #t71.{core::List::add}(#t73); + } =>#t71; core::List l5 = [invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:32:16: Error: Can't spread a value with static type 'N3'. var l5 = [...n3]; ^"]; core::List l6 = block { - final core::List #t48 = []; - final core::Iterable? #t49 = n3; - if(!#t49.{core::Object::==}(null)) - for (final Never #t50 in #t49{core::Iterable}) - #t48.{core::List::add}(#t50); - } =>#t48; + final core::List #t74 = []; + final core::Iterable? #t75 = n3; + if(!#t75.{core::Object::==}(null)) + for (final Never #t76 in #t75{core::Iterable}) + #t74.{core::List::add}(#t76); + } =>#t74; core::Set s1 = block { - final core::Set #t51 = col::LinkedHashSet::•(); - for (final self::test2::N1 #t52 in n1) - #t51.{core::Set::add}(#t52); - #t51.{core::Set::add}(n1); - } =>#t51; + final core::Set #t77 = col::LinkedHashSet::•(); + for (final self::test2::N1 #t78 in let final self::test2::N1 #t79 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) + #t77.{core::Set::add}(#t78); + #t77.{core::Set::add}(let final self::test2::N1 #t80 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t77; core::Set s2 = block { - final core::Set #t53 = col::LinkedHashSet::•(); - final core::Iterable? #t54 = n1; - if(!#t54.{core::Object::==}(null)) - for (final self::test2::N1 #t55 in #t54{core::Iterable}) - #t53.{core::Set::add}(#t55); - #t53.{core::Set::add}(n1); - } =>#t53; - core::Set s3 = let final core::Set #t56 = col::LinkedHashSet::•() in let final dynamic #t57 = #t56.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'. + final core::Set #t81 = col::LinkedHashSet::•(); + final core::Iterable? #t82 = let final self::test2::N1 #t83 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t82.{core::Object::==}(null)) + for (final self::test2::N1 #t84 in #t82{core::Iterable}) + #t81.{core::Set::add}(#t84); + #t81.{core::Set::add}(let final self::test2::N1 #t85 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t81; + core::Set s3 = let final core::Set #t86 = col::LinkedHashSet::•() in let final dynamic #t87 = #t86.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'. var s3 = {...n2, n1}; - ^") in let final dynamic #t58 = #t56.{core::Set::add}(n1) in #t56; + ^") in let final dynamic #t88 = #t86.{core::Set::add}(let final self::test2::N1 #t89 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in #t86; core::Set s4 = block { - final core::Set #t59 = col::LinkedHashSet::•(); - final core::Iterable? #t60 = n2; - if(!#t60.{core::Object::==}(null)) - for (final self::test2::N1 #t61 in #t60{core::Iterable}) - #t59.{core::Set::add}(#t61); - #t59.{core::Set::add}(n1); - } =>#t59; - core::Set s5 = let final core::Set #t62 = col::LinkedHashSet::•() in let final dynamic #t63 = #t62.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'. + final core::Set #t90 = col::LinkedHashSet::•(); + final core::Iterable? #t91 = n2; + if(!#t91.{core::Object::==}(null)) + for (final self::test2::N1 #t92 in #t91{core::Iterable}) + #t90.{core::Set::add}(#t92); + #t90.{core::Set::add}(let final self::test2::N1 #t93 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t90; + core::Set s5 = let final core::Set #t94 = col::LinkedHashSet::•() in let final dynamic #t95 = #t94.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'. var s5 = {...n3, n1}; - ^") in let final dynamic #t64 = #t62.{core::Set::add}(n1) in #t62; + ^") in let final dynamic #t96 = #t94.{core::Set::add}(let final self::test2::N1 #t97 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in #t94; core::Set s6 = block { - final core::Set #t65 = col::LinkedHashSet::•(); - final core::Iterable? #t66 = n3; - if(!#t66.{core::Object::==}(null)) - for (final self::test2::N1 #t67 in #t66{core::Iterable}) - #t65.{core::Set::add}(#t67); - #t65.{core::Set::add}(n1); - } =>#t65; + final core::Set #t98 = col::LinkedHashSet::•(); + final core::Iterable? #t99 = n3; + if(!#t99.{core::Object::==}(null)) + for (final self::test2::N1 #t100 in #t99{core::Iterable}) + #t98.{core::Set::add}(#t100); + #t98.{core::Set::add}(let final self::test2::N1 #t101 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t98; core::Map m1 = block { - final core::Map #t68 = {}; - for (final core::MapEntry #t69 in n1.{core::Map::entries}) - #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value}); - #t68.{core::Map::[]=}(n1, n1); - } =>#t68; + final core::Map #t102 = {}; + for (final core::MapEntry #t103 in (let final self::test2::N1 #t104 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries}) + #t102.{core::Map::[]=}(#t103.{core::MapEntry::key}, #t103.{core::MapEntry::value}); + #t102.{core::Map::[]=}(let final self::test2::N1 #t105 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t106 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t102; core::Map m2 = block { - final core::Map #t70 = {}; - final core::Map? #t71 = n1; - if(!#t71.{core::Object::==}(null)) - for (final core::MapEntry #t72 in #t71{core::Map}.{core::Map::entries}) - #t70.{core::Map::[]=}(#t72.{core::MapEntry::key}, #t72.{core::MapEntry::value}); - #t70.{core::Map::[]=}(n1, n1); - } =>#t70; + final core::Map #t107 = {}; + final core::Map? #t108 = let final self::test2::N1 #t109 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t108.{core::Object::==}(null)) + for (final core::MapEntry #t110 in #t108{core::Map}.{core::Map::entries}) + #t107.{core::Map::[]=}(#t110.{core::MapEntry::key}, #t110.{core::MapEntry::value}); + #t107.{core::Map::[]=}(let final self::test2::N1 #t111 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t112 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t107; core::Map m3 = {invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:42:16: Error: Can't spread a value with static type 'N2'. var m3 = {...n2, n1: n1}; - ^": null, n1: n1}; + ^": null, let final self::test2::N1 #t113 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t114 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")}; core::Map m4 = block { - final core::Map #t73 = {}; - final core::Map? #t74 = n2; - if(!#t74.{core::Object::==}(null)) - for (final core::MapEntry #t75 in #t74{core::Map}.{core::Map::entries}) - #t73.{core::Map::[]=}(#t75.{core::MapEntry::key}, #t75.{core::MapEntry::value}); - #t73.{core::Map::[]=}(n1, n1); - } =>#t73; + final core::Map #t115 = {}; + final core::Map? #t116 = n2; + if(!#t116.{core::Object::==}(null)) + for (final core::MapEntry #t117 in #t116{core::Map}.{core::Map::entries}) + #t115.{core::Map::[]=}(#t117.{core::MapEntry::key}, #t117.{core::MapEntry::value}); + #t115.{core::Map::[]=}(let final self::test2::N1 #t118 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t119 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t115; core::Map m5 = {invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:44:16: Error: Can't spread a value with static type 'N3'. var m5 = {...n3, n1: n1}; - ^": null, n1: n1}; + ^": null, let final self::test2::N1 #t120 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t121 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")}; core::Map m6 = block { - final core::Map #t76 = {}; - final core::Map? #t77 = n3; - if(!#t77.{core::Object::==}(null)) - for (final core::MapEntry #t78 in #t77{core::Map}.{core::Map::entries}) - #t76.{core::Map::[]=}(#t78.{core::MapEntry::key}, #t78.{core::MapEntry::value}); - #t76.{core::Map::[]=}(n1, n1); - } =>#t76; + final core::Map #t122 = {}; + final core::Map? #t123 = n3; + if(!#t123.{core::Object::==}(null)) + for (final core::MapEntry #t124 in #t123{core::Map}.{core::Map::entries}) + #t122.{core::Map::[]=}(#t124.{core::MapEntry::key}, #t124.{core::MapEntry::value}); + #t122.{core::Map::[]=}(let final self::test2::N1 #t125 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t126 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t122; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect index 97d6ebf07e9d1..1e59eaeba9a05 100644 --- a/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/issue42758.dart.weak.transformed.expect @@ -76,300 +76,301 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; import "dart:collection" as col; static method test1(Never n1, Never? n2, core::Null? n3) → dynamic { core::List l1 = block { final core::List #t1 = []; - for (final Never #t2 in n1) + for (final Never #t2 in let final Never #t3 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) #t1.{core::List::add}(#t2); } =>#t1; core::List l2 = block { - final core::List #t3 = []; - final core::Iterable? #t4 = n1; - if(!#t4.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t4{core::Iterable}.{core::Iterable::iterator}; + final core::List #t4 = []; + final core::Iterable? #t5 = let final Never #t6 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t5.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t5{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t5 = :sync-for-iterator.{core::Iterator::current}; - #t3.{core::List::add}(#t5); + final Never #t7 = :sync-for-iterator.{core::Iterator::current}; + #t4.{core::List::add}(#t7); } } - } =>#t3; + } =>#t4; core::List l3 = [invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:8:16: Error: Can't spread a value with static type 'Never?'. var l3 = [...n2]; ^"]; core::List l4 = block { - final core::List #t6 = []; - final core::Iterable? #t7 = n2; - if(!#t7.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t7{core::Iterable}.{core::Iterable::iterator}; + final core::List #t8 = []; + final core::Iterable? #t9 = n2; + if(!#t9.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t9{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t8 = :sync-for-iterator.{core::Iterator::current}; - #t6.{core::List::add}(#t8); + final Never #t10 = :sync-for-iterator.{core::Iterator::current}; + #t8.{core::List::add}(#t10); } } - } =>#t6; + } =>#t8; core::List l5 = [invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:10:16: Error: Can't spread a value with static type 'Null'. var l5 = [...n3]; ^"]; core::List l6 = block { - final core::List #t9 = []; - final core::Iterable? #t10 = n3; - if(!#t10.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t10{core::Iterable}.{core::Iterable::iterator}; + final core::List #t11 = []; + final core::Iterable? #t12 = n3; + if(!#t12.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t12{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t11 = :sync-for-iterator.{core::Iterator::current}; - #t9.{core::List::add}(#t11); + final Never #t13 = :sync-for-iterator.{core::Iterator::current}; + #t11.{core::List::add}(#t13); } } - } =>#t9; + } =>#t11; core::Set s1 = block { - final core::Set #t12 = new col::_CompactLinkedHashSet::•(); - for (final Never #t13 in n1) - #t12.{core::Set::add}(#t13); - #t12.{core::Set::add}(n1); - } =>#t12; - core::Set s2 = block { final core::Set #t14 = new col::_CompactLinkedHashSet::•(); - final core::Iterable? #t15 = n1; - if(!#t15.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t15{core::Iterable}.{core::Iterable::iterator}; + for (final Never #t15 in let final Never #t16 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) + #t14.{core::Set::add}(#t15); + #t14.{core::Set::add}(let final Never #t17 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t14; + core::Set s2 = block { + final core::Set #t18 = new col::_CompactLinkedHashSet::•(); + final core::Iterable? #t19 = let final Never #t20 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t19.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t19{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t16 = :sync-for-iterator.{core::Iterator::current}; - #t14.{core::Set::add}(#t16); + final Never #t21 = :sync-for-iterator.{core::Iterator::current}; + #t18.{core::Set::add}(#t21); } } - #t14.{core::Set::add}(n1); - } =>#t14; - core::Set s3 = let final core::Set #t17 = new col::_CompactLinkedHashSet::•() in let final core::bool #t18 = #t17.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'. + #t18.{core::Set::add}(let final Never #t22 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t18; + core::Set s3 = let final core::Set #t23 = new col::_CompactLinkedHashSet::•() in let final core::bool #t24 = #t23.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:14:16: Error: Can't spread a value with static type 'Never?'. var s3 = {...n2, n1}; - ^") in let final core::bool #t19 = #t17.{core::Set::add}(n1) in #t17; + ^") in let final core::bool #t25 = #t23.{core::Set::add}(let final Never #t26 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in #t23; core::Set s4 = block { - final core::Set #t20 = new col::_CompactLinkedHashSet::•(); - final core::Iterable? #t21 = n2; - if(!#t21.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t21{core::Iterable}.{core::Iterable::iterator}; + final core::Set #t27 = new col::_CompactLinkedHashSet::•(); + final core::Iterable? #t28 = n2; + if(!#t28.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t28{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t22 = :sync-for-iterator.{core::Iterator::current}; - #t20.{core::Set::add}(#t22); + final Never #t29 = :sync-for-iterator.{core::Iterator::current}; + #t27.{core::Set::add}(#t29); } } - #t20.{core::Set::add}(n1); - } =>#t20; - core::Set s5 = let final core::Set #t23 = new col::_CompactLinkedHashSet::•() in let final core::bool #t24 = #t23.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'. + #t27.{core::Set::add}(let final Never #t30 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t27; + core::Set s5 = let final core::Set #t31 = new col::_CompactLinkedHashSet::•() in let final core::bool #t32 = #t31.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:16:16: Error: Can't spread a value with static type 'Null'. var s5 = {...n3, n1}; - ^") in let final core::bool #t25 = #t23.{core::Set::add}(n1) in #t23; + ^") in let final core::bool #t33 = #t31.{core::Set::add}(let final Never #t34 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in #t31; core::Set s6 = block { - final core::Set #t26 = new col::_CompactLinkedHashSet::•(); - final core::Iterable? #t27 = n3; - if(!#t27.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t27{core::Iterable}.{core::Iterable::iterator}; + final core::Set #t35 = new col::_CompactLinkedHashSet::•(); + final core::Iterable? #t36 = n3; + if(!#t36.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t36{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t28 = :sync-for-iterator.{core::Iterator::current}; - #t26.{core::Set::add}(#t28); + final Never #t37 = :sync-for-iterator.{core::Iterator::current}; + #t35.{core::Set::add}(#t37); } } - #t26.{core::Set::add}(n1); - } =>#t26; + #t35.{core::Set::add}(let final Never #t38 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t35; core::Map m1 = block { - final core::Map #t29 = {}; + final core::Map #t39 = {}; { - core::Iterator, >> :sync-for-iterator = n1.{core::Map::entries}.{core::Iterable::iterator}; + core::Iterator, >> :sync-for-iterator = (let final Never #t40 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final core::MapEntry #t30 = :sync-for-iterator.{core::Iterator::current}; - #t29.{core::Map::[]=}(#t30.{core::MapEntry::key}, #t30.{core::MapEntry::value}); + final core::MapEntry #t41 = :sync-for-iterator.{core::Iterator::current}; + #t39.{core::Map::[]=}(#t41.{core::MapEntry::key}, #t41.{core::MapEntry::value}); } } - #t29.{core::Map::[]=}(n1, n1); - } =>#t29; + #t39.{core::Map::[]=}(let final Never #t42 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t43 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t39; core::Map m2 = block { - final core::Map #t31 = {}; - final core::Map? #t32 = n1; - if(!#t32.{core::Object::==}(null)) { - core::Iterator> :sync-for-iterator = #t32{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; + final core::Map #t44 = {}; + final core::Map? #t45 = let final Never #t46 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t45.{core::Object::==}(null)) { + core::Iterator> :sync-for-iterator = #t45{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final core::MapEntry #t33 = :sync-for-iterator.{core::Iterator::current}; - #t31.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value}); + final core::MapEntry #t47 = :sync-for-iterator.{core::Iterator::current}; + #t44.{core::Map::[]=}(#t47.{core::MapEntry::key}, #t47.{core::MapEntry::value}); } } - #t31.{core::Map::[]=}(n1, n1); - } =>#t31; + #t44.{core::Map::[]=}(let final Never #t48 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t49 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t44; core::Map m3 = {invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:20:16: Error: Can't spread a value with static type 'Never?'. var m3 = {...n2, n1: n1}; - ^": null, n1: n1}; + ^": null, let final Never #t50 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t51 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")}; core::Map m4 = block { - final core::Map #t34 = {}; - final core::Map? #t35 = n2; - if(!#t35.{core::Object::==}(null)) { - core::Iterator> :sync-for-iterator = #t35{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; + final core::Map #t52 = {}; + final core::Map? #t53 = n2; + if(!#t53.{core::Object::==}(null)) { + core::Iterator> :sync-for-iterator = #t53{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final core::MapEntry #t36 = :sync-for-iterator.{core::Iterator::current}; - #t34.{core::Map::[]=}(#t36.{core::MapEntry::key}, #t36.{core::MapEntry::value}); + final core::MapEntry #t54 = :sync-for-iterator.{core::Iterator::current}; + #t52.{core::Map::[]=}(#t54.{core::MapEntry::key}, #t54.{core::MapEntry::value}); } } - #t34.{core::Map::[]=}(n1, n1); - } =>#t34; + #t52.{core::Map::[]=}(let final Never #t55 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t56 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t52; core::Map m5 = {invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:22:16: Error: Can't spread a value with static type 'Null'. var m5 = {...n3, n1: n1}; - ^": null, n1: n1}; + ^": null, let final Never #t57 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final Never #t58 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")}; core::Map m6 = block { - final core::Map #t37 = {}; - final core::Map? #t38 = n3; - if(!#t38.{core::Object::==}(null)) { - core::Iterator> :sync-for-iterator = #t38{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; + final core::Map #t59 = {}; + final core::Map? #t60 = n3; + if(!#t60.{core::Object::==}(null)) { + core::Iterator> :sync-for-iterator = #t60{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final core::MapEntry #t39 = :sync-for-iterator.{core::Iterator::current}; - #t37.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value}); + final core::MapEntry #t61 = :sync-for-iterator.{core::Iterator::current}; + #t59.{core::Map::[]=}(#t61.{core::MapEntry::key}, #t61.{core::MapEntry::value}); } } - #t37.{core::Map::[]=}(n1, n1); - } =>#t37; + #t59.{core::Map::[]=}(let final Never #t62 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final Never #t63 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t59; } static method test2(self::test2::N1 n1, self::test2::N2% n2, self::test2::N3% n3) → dynamic { core::List l1 = block { - final core::List #t40 = []; - for (final Never #t41 in n1) - #t40.{core::List::add}(#t41); - } =>#t40; + final core::List #t64 = []; + for (final Never #t65 in let final self::test2::N1 #t66 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) + #t64.{core::List::add}(#t65); + } =>#t64; core::List l2 = block { - final core::List #t42 = []; - final core::Iterable? #t43 = n1; - if(!#t43.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t43{core::Iterable}.{core::Iterable::iterator}; + final core::List #t67 = []; + final core::Iterable? #t68 = let final self::test2::N1 #t69 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t68.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t68{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t44 = :sync-for-iterator.{core::Iterator::current}; - #t42.{core::List::add}(#t44); + final Never #t70 = :sync-for-iterator.{core::Iterator::current}; + #t67.{core::List::add}(#t70); } } - } =>#t42; + } =>#t67; core::List l3 = [invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:30:16: Error: Can't spread a value with static type 'N2'. var l3 = [...n2]; ^"]; core::List l4 = block { - final core::List #t45 = []; - final core::Iterable? #t46 = n2; - if(!#t46.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t46{core::Iterable}.{core::Iterable::iterator}; + final core::List #t71 = []; + final core::Iterable? #t72 = n2; + if(!#t72.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t72{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t47 = :sync-for-iterator.{core::Iterator::current}; - #t45.{core::List::add}(#t47); + final Never #t73 = :sync-for-iterator.{core::Iterator::current}; + #t71.{core::List::add}(#t73); } } - } =>#t45; + } =>#t71; core::List l5 = [invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:32:16: Error: Can't spread a value with static type 'N3'. var l5 = [...n3]; ^"]; core::List l6 = block { - final core::List #t48 = []; - final core::Iterable? #t49 = n3; - if(!#t49.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t49{core::Iterable}.{core::Iterable::iterator}; + final core::List #t74 = []; + final core::Iterable? #t75 = n3; + if(!#t75.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t75{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final Never #t50 = :sync-for-iterator.{core::Iterator::current}; - #t48.{core::List::add}(#t50); + final Never #t76 = :sync-for-iterator.{core::Iterator::current}; + #t74.{core::List::add}(#t76); } } - } =>#t48; + } =>#t74; core::Set s1 = block { - final core::Set #t51 = new col::_CompactLinkedHashSet::•(); - for (final self::test2::N1 #t52 in n1) - #t51.{core::Set::add}(#t52); - #t51.{core::Set::add}(n1); - } =>#t51; + final core::Set #t77 = new col::_CompactLinkedHashSet::•(); + for (final self::test2::N1 #t78 in let final self::test2::N1 #t79 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) + #t77.{core::Set::add}(#t78); + #t77.{core::Set::add}(let final self::test2::N1 #t80 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t77; core::Set s2 = block { - final core::Set #t53 = new col::_CompactLinkedHashSet::•(); - final core::Iterable? #t54 = n1; - if(!#t54.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t54{core::Iterable}.{core::Iterable::iterator}; + final core::Set #t81 = new col::_CompactLinkedHashSet::•(); + final core::Iterable? #t82 = let final self::test2::N1 #t83 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t82.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t82{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final self::test2::N1 #t55 = :sync-for-iterator.{core::Iterator::current}; - #t53.{core::Set::add}(#t55); + final self::test2::N1 #t84 = :sync-for-iterator.{core::Iterator::current}; + #t81.{core::Set::add}(#t84); } } - #t53.{core::Set::add}(n1); - } =>#t53; - core::Set s3 = let final core::Set #t56 = new col::_CompactLinkedHashSet::•() in let final core::bool #t57 = #t56.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'. + #t81.{core::Set::add}(let final self::test2::N1 #t85 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t81; + core::Set s3 = let final core::Set #t86 = new col::_CompactLinkedHashSet::•() in let final core::bool #t87 = #t86.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:36:16: Error: Can't spread a value with static type 'N2'. var s3 = {...n2, n1}; - ^") in let final core::bool #t58 = #t56.{core::Set::add}(n1) in #t56; + ^") in let final core::bool #t88 = #t86.{core::Set::add}(let final self::test2::N1 #t89 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in #t86; core::Set s4 = block { - final core::Set #t59 = new col::_CompactLinkedHashSet::•(); - final core::Iterable? #t60 = n2; - if(!#t60.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t60{core::Iterable}.{core::Iterable::iterator}; + final core::Set #t90 = new col::_CompactLinkedHashSet::•(); + final core::Iterable? #t91 = n2; + if(!#t91.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t91{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final self::test2::N1 #t61 = :sync-for-iterator.{core::Iterator::current}; - #t59.{core::Set::add}(#t61); + final self::test2::N1 #t92 = :sync-for-iterator.{core::Iterator::current}; + #t90.{core::Set::add}(#t92); } } - #t59.{core::Set::add}(n1); - } =>#t59; - core::Set s5 = let final core::Set #t62 = new col::_CompactLinkedHashSet::•() in let final core::bool #t63 = #t62.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'. + #t90.{core::Set::add}(let final self::test2::N1 #t93 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t90; + core::Set s5 = let final core::Set #t94 = new col::_CompactLinkedHashSet::•() in let final core::bool #t95 = #t94.{core::Set::add}(invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:38:16: Error: Can't spread a value with static type 'N3'. var s5 = {...n3, n1}; - ^") in let final core::bool #t64 = #t62.{core::Set::add}(n1) in #t62; + ^") in let final core::bool #t96 = #t94.{core::Set::add}(let final self::test2::N1 #t97 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in #t94; core::Set s6 = block { - final core::Set #t65 = new col::_CompactLinkedHashSet::•(); - final core::Iterable? #t66 = n3; - if(!#t66.{core::Object::==}(null)) { - core::Iterator :sync-for-iterator = #t66{core::Iterable}.{core::Iterable::iterator}; + final core::Set #t98 = new col::_CompactLinkedHashSet::•(); + final core::Iterable? #t99 = n3; + if(!#t99.{core::Object::==}(null)) { + core::Iterator :sync-for-iterator = #t99{core::Iterable}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final self::test2::N1 #t67 = :sync-for-iterator.{core::Iterator::current}; - #t65.{core::Set::add}(#t67); + final self::test2::N1 #t100 = :sync-for-iterator.{core::Iterator::current}; + #t98.{core::Set::add}(#t100); } } - #t65.{core::Set::add}(n1); - } =>#t65; + #t98.{core::Set::add}(let final self::test2::N1 #t101 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t98; core::Map m1 = block { - final core::Map #t68 = {}; + final core::Map #t102 = {}; { - core::Iterator, >> :sync-for-iterator = n1.{core::Map::entries}.{core::Iterable::iterator}; + core::Iterator, >> :sync-for-iterator = (let final self::test2::N1 #t103 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).{core::Map::entries}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final core::MapEntry #t69 = :sync-for-iterator.{core::Iterator::current}; - #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value}); + final core::MapEntry #t104 = :sync-for-iterator.{core::Iterator::current}; + #t102.{core::Map::[]=}(#t104.{core::MapEntry::key}, #t104.{core::MapEntry::value}); } } - #t68.{core::Map::[]=}(n1, n1); - } =>#t68; + #t102.{core::Map::[]=}(let final self::test2::N1 #t105 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t106 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t102; core::Map m2 = block { - final core::Map #t70 = {}; - final core::Map? #t71 = n1; - if(!#t71.{core::Object::==}(null)) { - core::Iterator> :sync-for-iterator = #t71{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; + final core::Map #t107 = {}; + final core::Map? #t108 = let final self::test2::N1 #t109 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + if(!#t108.{core::Object::==}(null)) { + core::Iterator> :sync-for-iterator = #t108{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final core::MapEntry #t72 = :sync-for-iterator.{core::Iterator::current}; - #t70.{core::Map::[]=}(#t72.{core::MapEntry::key}, #t72.{core::MapEntry::value}); + final core::MapEntry #t110 = :sync-for-iterator.{core::Iterator::current}; + #t107.{core::Map::[]=}(#t110.{core::MapEntry::key}, #t110.{core::MapEntry::value}); } } - #t70.{core::Map::[]=}(n1, n1); - } =>#t70; + #t107.{core::Map::[]=}(let final self::test2::N1 #t111 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t112 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t107; core::Map m3 = {invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:42:16: Error: Can't spread a value with static type 'N2'. var m3 = {...n2, n1: n1}; - ^": null, n1: n1}; + ^": null, let final self::test2::N1 #t113 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t114 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")}; core::Map m4 = block { - final core::Map #t73 = {}; - final core::Map? #t74 = n2; - if(!#t74.{core::Object::==}(null)) { - core::Iterator> :sync-for-iterator = #t74{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; + final core::Map #t115 = {}; + final core::Map? #t116 = n2; + if(!#t116.{core::Object::==}(null)) { + core::Iterator> :sync-for-iterator = #t116{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final core::MapEntry #t75 = :sync-for-iterator.{core::Iterator::current}; - #t73.{core::Map::[]=}(#t75.{core::MapEntry::key}, #t75.{core::MapEntry::value}); + final core::MapEntry #t117 = :sync-for-iterator.{core::Iterator::current}; + #t115.{core::Map::[]=}(#t117.{core::MapEntry::key}, #t117.{core::MapEntry::value}); } } - #t73.{core::Map::[]=}(n1, n1); - } =>#t73; + #t115.{core::Map::[]=}(let final self::test2::N1 #t118 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t119 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t115; core::Map m5 = {invalid-expression "pkg/front_end/testcases/nnbd/issue42758.dart:44:16: Error: Can't spread a value with static type 'N3'. var m5 = {...n3, n1: n1}; - ^": null, n1: n1}; + ^": null, let final self::test2::N1 #t120 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."): let final self::test2::N1 #t121 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")}; core::Map m6 = block { - final core::Map #t76 = {}; - final core::Map? #t77 = n3; - if(!#t77.{core::Object::==}(null)) { - core::Iterator> :sync-for-iterator = #t77{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; + final core::Map #t122 = {}; + final core::Map? #t123 = n3; + if(!#t123.{core::Object::==}(null)) { + core::Iterator> :sync-for-iterator = #t123{core::Map}.{core::Map::entries}.{core::Iterable::iterator}; for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) { - final core::MapEntry #t78 = :sync-for-iterator.{core::Iterator::current}; - #t76.{core::Map::[]=}(#t78.{core::MapEntry::key}, #t78.{core::MapEntry::value}); + final core::MapEntry #t124 = :sync-for-iterator.{core::Iterator::current}; + #t122.{core::Map::[]=}(#t124.{core::MapEntry::key}, #t124.{core::MapEntry::value}); } } - #t76.{core::Map::[]=}(n1, n1); - } =>#t76; + #t122.{core::Map::[]=}(let final self::test2::N1 #t125 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."), let final self::test2::N1 #t126 = n1 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")); + } =>#t122; } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/never_calls.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_calls.dart.weak.expect index 33ac05b5a3392..242bb800fcdfd 100644 --- a/pkg/front_end/testcases/nnbd/never_calls.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/never_calls.dart.weak.expect @@ -1,34 +1,35 @@ library /*isNonNullableByDefault*/; import self as self; +import "dart:_internal" as _in; import "dart:core" as core; static method propertyGet(Never never) → dynamic { - Never v1 = never.foo; - Never v2 = never.hashCode; - Never v3 = never.runtimeType; - Never v4 = never.toString; - Never v5 = never.noSuchMethod; + Never v1 = let final Never #t1 = (let final Never #t2 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t3 = (let final Never #t4 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).hashCode in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v3 = let final Never #t5 = (let final Never #t6 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v4 = let final Never #t7 = (let final Never #t8 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v5 = let final Never #t9 = (let final Never #t10 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).noSuchMethod in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method propertySet(Never never) → dynamic { - core::int v1 = never.foo = 42; + core::int v1 = (let final Never #t11 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo = 42; } static method methodInvocation(Never never, core::Invocation invocation) → dynamic { - Never v1 = never.foo(); - Never v2 = never.hashCode(); - Never v3 = never.runtimeType(); - Never v4 = never.toString(); - Never v5 = never.toString(foo: 42); - Never v6 = never.noSuchMethod(invocation); - Never v7 = never.noSuchMethod(42); + Never v1 = let final Never #t12 = (let final Never #t13 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t14 = (let final Never #t15 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).hashCode() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v3 = let final Never #t16 = (let final Never #t17 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v4 = let final Never #t18 = (let final Never #t19 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v5 = let final Never #t20 = (let final Never #t21 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString(foo: 42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v6 = let final Never #t22 = (let final Never #t23 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).noSuchMethod(invocation) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v7 = let final Never #t24 = (let final Never #t25 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).noSuchMethod(42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method equals(Never never) → dynamic { - Never v1 = never.==(null); - Never v2 = never.==(never); + Never v1 = let final Never #t26 = (let final Never #t27 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).==(null) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t28 = (let final Never #t29 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).==(let final Never #t30 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method operator(Never never) → dynamic { - Never v1 = never.+(never); - Never v2 = never.unary-(); - Never v3 = never.[](never); - Never v4 = let final Never #t1 = never in let final Never #t2 = never in let final Never #t3 = never in let final void #t4 = #t1.[]=(#t2, #t3) in #t3; + Never v1 = let final Never #t31 = (let final Never #t32 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(let final Never #t33 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t34 = (let final Never #t35 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).unary-() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v3 = let final Never #t36 = (let final Never #t37 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](let final Never #t38 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v4 = let final Never #t39 = let final Never #t40 = let final Never #t41 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in let final Never #t42 = let final Never #t43 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in let final Never #t44 = let final Never #t45 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in let final void #t46 = #t40.[]=(#t42, #t44) in #t44 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/never_calls.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_calls.dart.weak.transformed.expect index 33ac05b5a3392..242bb800fcdfd 100644 --- a/pkg/front_end/testcases/nnbd/never_calls.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/never_calls.dart.weak.transformed.expect @@ -1,34 +1,35 @@ library /*isNonNullableByDefault*/; import self as self; +import "dart:_internal" as _in; import "dart:core" as core; static method propertyGet(Never never) → dynamic { - Never v1 = never.foo; - Never v2 = never.hashCode; - Never v3 = never.runtimeType; - Never v4 = never.toString; - Never v5 = never.noSuchMethod; + Never v1 = let final Never #t1 = (let final Never #t2 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t3 = (let final Never #t4 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).hashCode in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v3 = let final Never #t5 = (let final Never #t6 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v4 = let final Never #t7 = (let final Never #t8 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v5 = let final Never #t9 = (let final Never #t10 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).noSuchMethod in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method propertySet(Never never) → dynamic { - core::int v1 = never.foo = 42; + core::int v1 = (let final Never #t11 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo = 42; } static method methodInvocation(Never never, core::Invocation invocation) → dynamic { - Never v1 = never.foo(); - Never v2 = never.hashCode(); - Never v3 = never.runtimeType(); - Never v4 = never.toString(); - Never v5 = never.toString(foo: 42); - Never v6 = never.noSuchMethod(invocation); - Never v7 = never.noSuchMethod(42); + Never v1 = let final Never #t12 = (let final Never #t13 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t14 = (let final Never #t15 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).hashCode() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v3 = let final Never #t16 = (let final Never #t17 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).runtimeType() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v4 = let final Never #t18 = (let final Never #t19 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v5 = let final Never #t20 = (let final Never #t21 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).toString(foo: 42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v6 = let final Never #t22 = (let final Never #t23 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).noSuchMethod(invocation) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v7 = let final Never #t24 = (let final Never #t25 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).noSuchMethod(42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method equals(Never never) → dynamic { - Never v1 = never.==(null); - Never v2 = never.==(never); + Never v1 = let final Never #t26 = (let final Never #t27 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).==(null) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t28 = (let final Never #t29 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).==(let final Never #t30 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method operator(Never never) → dynamic { - Never v1 = never.+(never); - Never v2 = never.unary-(); - Never v3 = never.[](never); - Never v4 = let final Never #t1 = never in let final Never #t2 = never in let final Never #t3 = never in let final void #t4 = #t1.[]=(#t2, #t3) in #t3; + Never v1 = let final Never #t31 = (let final Never #t32 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(let final Never #t33 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v2 = let final Never #t34 = (let final Never #t35 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).unary-() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v3 = let final Never #t36 = (let final Never #t37 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](let final Never #t38 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + Never v4 = let final Never #t39 = let final Never #t40 = let final Never #t41 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in let final Never #t42 = let final Never #t43 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in let final Never #t44 = let final Never #t45 = never in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in let final void #t46 = #t40.[]=(#t42, #t44) in #t44 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/never_equals.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_equals.dart.weak.expect index eafd6079452b1..52cfdacafa7dd 100644 --- a/pkg/front_end/testcases/nnbd/never_equals.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/never_equals.dart.weak.expect @@ -1,9 +1,10 @@ library /*isNonNullableByDefault*/; import self as self; +import "dart:_internal" as _in; import "dart:core" as core; static method test(Never nonNullableNever, Never? nullableNever) → dynamic { - Never v1 = nonNullableNever.==(nonNullableNever); + Never v1 = let final Never #t1 = (let final Never #t2 = nonNullableNever in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).==(let final Never #t3 = nonNullableNever in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); core::bool v2 = nullableNever.{core::Object::==}(nullableNever); } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/never_equals.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_equals.dart.weak.transformed.expect index eafd6079452b1..52cfdacafa7dd 100644 --- a/pkg/front_end/testcases/nnbd/never_equals.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/never_equals.dart.weak.transformed.expect @@ -1,9 +1,10 @@ library /*isNonNullableByDefault*/; import self as self; +import "dart:_internal" as _in; import "dart:core" as core; static method test(Never nonNullableNever, Never? nullableNever) → dynamic { - Never v1 = nonNullableNever.==(nonNullableNever); + Never v1 = let final Never #t1 = (let final Never #t2 = nonNullableNever in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).==(let final Never #t3 = nonNullableNever in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); core::bool v2 = nullableNever.{core::Object::==}(nullableNever); } static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect index 8a67b5aa8a5a2..ea4279db77ded 100644 --- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.expect @@ -64,29 +64,30 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; static method foo(Never x, 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 final Never? #t1 = y in #t1.{core::Object::==}(null) ?{core::Null?} null : #t1{Never}.foo(); - let final Never? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar; - let final Never? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42; - let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{core::Null?} null : #t4{Never}.call(); - let final Never? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42); - let final Never? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42); - let final Never #t7 = x in #t7.{core::Object::==}(null) ?{core::Null?} null : #t7.foo(); - let final Never #t8 = x in #t8.{core::Object::==}(null) ?{core::Null?} null : #t8.bar; - let final Never #t9 = x in #t9.{core::Object::==}(null) ?{core::int?} null : #t9.baz = 42; - let final Never #t10 = x in #t10.{core::Object::==}(null) ?{core::Null?} null : #t10.[](42); - let final Never #t11 = x in #t11.{core::Object::==}(null) ?{core::int?} null : #t11.[]=(42, 42); + let final Never #t1 = (let final Never #t2 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t3 = (let final Never #t4 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).bar in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + (let final Never #t5 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).baz = 42; + let final Never #t6 = (let final Never #t7 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t8 = (let final Never #t9 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + (let final Never #t10 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[]=(42, 42); + let final Never #t11 = x = let final Never #t12 = (let final Never #t13 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(1) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t14 = x = let final Never #t15 = (let final Never #t16 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(1) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t17 = y in #t17.{core::Object::==}(null) ?{core::Null?} null : let final Never #t18 = (let final Never #t19 = #t17{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t20 = y in #t20.{core::Object::==}(null) ?{core::Null?} null : let final Never #t21 = (let final Never #t22 = #t20{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).bar in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t23 = y in #t23.{core::Object::==}(null) ?{core::int?} null : (let final Never #t24 = #t23{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).baz = 42; + let final Never? #t25 = y in #t25.{core::Object::==}(null) ?{core::Null?} null : let final Never #t26 = (let final Never #t27 = #t25{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t28 = y in #t28.{core::Object::==}(null) ?{core::Null?} null : let final Never #t29 = (let final Never #t30 = #t28{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t31 = y in #t31.{core::Object::==}(null) ?{core::int?} null : (let final Never #t32 = #t31{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[]=(42, 42); + let final Never #t33 = let final Never #t34 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t33.{core::Object::==}(null) ?{core::Null?} null : let final Never #t35 = (let final Never #t36 = #t33 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t37 = let final Never #t38 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t37.{core::Object::==}(null) ?{core::Null?} null : let final Never #t39 = (let final Never #t40 = #t37 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).bar in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t41 = let final Never #t42 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t41.{core::Object::==}(null) ?{core::int?} null : (let final Never #t43 = #t41 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).baz = 42; + let final Never #t44 = let final Never #t45 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t44.{core::Object::==}(null) ?{core::Null?} null : let final Never #t46 = (let final Never #t47 = #t44 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t48 = let final Never #t49 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t48.{core::Object::==}(null) ?{core::int?} null : (let final Never #t50 = #t48 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[]=(42, 42); invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30: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. diff --git a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect index aa42b16b6ee78..d677ad0390703 100644 --- a/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/never_receiver.dart.weak.transformed.expect @@ -64,29 +64,30 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; static method foo(Never x, 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 final Never? #t1 = y in #t1.{core::Object::==}(null) ?{core::Null?} null : #t1{Never}.foo(); - let final Never? #t2 = y in #t2.{core::Object::==}(null) ?{core::Null?} null : #t2{Never}.bar; - let final Never? #t3 = y in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{Never}.baz = 42; - let final Never? #t4 = y in #t4.{core::Object::==}(null) ?{core::Null?} null : #t4{Never}.call(); - let final Never? #t5 = y in #t5.{core::Object::==}(null) ?{core::Null?} null : #t5{Never}.[](42); - let final Never? #t6 = y in #t6.{core::Object::==}(null) ?{core::int?} null : #t6{Never}.[]=(42, 42); - let final Never #t7 = x in #t7.{core::Object::==}(null) ?{core::Null?} null : #t7.foo(); - let final Never #t8 = x in #t8.{core::Object::==}(null) ?{core::Null?} null : #t8.bar; - let final Never #t9 = x in #t9.{core::Object::==}(null) ?{core::int?} null : #t9.baz = 42; - let final Never #t10 = x in #t10.{core::Object::==}(null) ?{core::Null?} null : #t10.[](42); - let final Never #t11 = x in #t11.{core::Object::==}(null) ?{core::int?} null : #t11.[]=(42, 42); + let final Never #t1 = (let final Never #t2 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t3 = (let final Never #t4 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).bar in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + (let final Never #t5 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).baz = 42; + let final Never #t6 = (let final Never #t7 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t8 = (let final Never #t9 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + (let final Never #t10 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[]=(42, 42); + let final Never #t11 = x = let final Never #t12 = (let final Never #t13 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(1) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t14 = x = let final Never #t15 = (let final Never #t16 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).+(1) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t17 = y in #t17.{core::Object::==}(null) ?{core::Null?} null : let final Never #t18 = (let final Never #t19 = #t17{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t20 = y in #t20.{core::Object::==}(null) ?{core::Null?} null : let final Never #t21 = (let final Never #t22 = #t20{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).bar in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t23 = y in #t23.{core::Object::==}(null) ?{core::int?} null : (let final Never #t24 = #t23{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).baz = 42; + let final Never? #t25 = y in #t25.{core::Object::==}(null) ?{core::Null?} null : let final Never #t26 = (let final Never #t27 = #t25{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t28 = y in #t28.{core::Object::==}(null) ?{core::Null?} null : let final Never #t29 = (let final Never #t30 = #t28{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never? #t31 = y in #t31.{core::Object::==}(null) ?{core::int?} null : (let final Never #t32 = #t31{Never} in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[]=(42, 42); + let final Never #t33 = let final Never #t34 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t33.{core::Object::==}(null) ?{core::Null?} null : let final Never #t35 = (let final Never #t36 = #t33 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).foo() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t37 = let final Never #t38 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t37.{core::Object::==}(null) ?{core::Null?} null : let final Never #t39 = (let final Never #t40 = #t37 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).bar in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t41 = let final Never #t42 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t41.{core::Object::==}(null) ?{core::int?} null : (let final Never #t43 = #t41 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).baz = 42; + let final Never #t44 = let final Never #t45 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t44.{core::Object::==}(null) ?{core::Null?} null : let final Never #t46 = (let final Never #t47 = #t44 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[](42) in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); + let final Never #t48 = let final Never #t49 = x in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t48.{core::Object::==}(null) ?{core::int?} null : (let final Never #t50 = #t48 in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.")).[]=(42, 42); invalid-expression "pkg/front_end/testcases/nnbd/never_receiver.dart:30: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. diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect index 4c9329b1b64de..13041e991faf3 100644 --- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect @@ -55,6 +55,7 @@ library /*isNonNullableByDefault*/; import self as self; import "dart:core" as core; import "dart:async" as asy; +import "dart:_internal" as _in; import "dart:async"; @@ -120,16 +121,19 @@ static method caseReturn1(self::Enum e) → self::Enum { { return e; } + #L3: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); } } static method caseReturn2(self::Enum e) → self::Enum { switch(e) { - #L3: + #L4: case #C3: { return e; } - #L4: + #L5: default: {} } @@ -179,26 +183,29 @@ static method localFunctions() → dynamic { function yieldAsync() → asy::Stream async* {} function caseReturn1(self::Enum e) → self::Enum { switch(e) { - #L5: + #L6: case #C3: { return e; } - #L6: + #L7: case #C6: { return e; } + #L8: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); } } function caseReturn2(self::Enum e) → self::Enum { switch(e) { - #L7: + #L9: case #C3: { return e; } - #L8: + #L10: default: {} } diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect index b3b3e5b10e520..0c25127e45843 100644 --- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect @@ -55,6 +55,7 @@ library /*isNonNullableByDefault*/; import self as self; import "dart:core" as core; import "dart:async" as asy; +import "dart:_internal" as _in; import "dart:async"; @@ -320,16 +321,19 @@ static method caseReturn1(self::Enum e) → self::Enum { { return e; } + #L11: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); } } static method caseReturn2(self::Enum e) → self::Enum { switch(e) { - #L11: + #L12: case #C3: { return e; } - #L12: + #L13: default: {} } @@ -372,7 +376,7 @@ static method localFunctions() → dynamic { dynamic :await_ctx_var; function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try { - #L13: + #L14: {} asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -396,7 +400,7 @@ static method localFunctions() → dynamic { dynamic :await_ctx_var; function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try { - #L14: + #L15: {} asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -420,12 +424,12 @@ static method localFunctions() → dynamic { dynamic :await_ctx_var; function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try { - #L15: + #L16: { :return_value = let final #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null. FutureOr returnAsync3() async {} // error ^" in null; - break #L15; + break #L16; } asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -449,7 +453,7 @@ static method localFunctions() → dynamic { dynamic :await_ctx_var; function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try { - #L16: + #L17: {} asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -473,7 +477,7 @@ static method localFunctions() → dynamic { dynamic :await_ctx_var; function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try { - #L17: + #L18: {} asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -497,10 +501,10 @@ static method localFunctions() → dynamic { dynamic :await_ctx_var; function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try { - #L18: + #L19: { :return_value = null; - break #L18; + break #L19; } asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -524,7 +528,7 @@ static method localFunctions() → dynamic { dynamic :await_ctx_var; function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try { - #L19: + #L20: {} asy::_completeOnAsyncReturn(:async_completer, :return_value); return; @@ -560,7 +564,7 @@ static method localFunctions() → dynamic { function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding try try { - #L20: + #L21: {} return; } @@ -579,26 +583,29 @@ static method localFunctions() → dynamic { } function caseReturn1(self::Enum e) → self::Enum { switch(e) { - #L21: + #L22: case #C3: { return e; } - #L22: + #L23: case #C6: { return e; } + #L24: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); } } function caseReturn2(self::Enum e) → self::Enum { switch(e) { - #L23: + #L25: case #C3: { return e; } - #L24: + #L26: default: {} } diff --git a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.expect b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.expect index 43d8018dda03f..0a559cb61bccc 100644 --- a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.expect @@ -8,6 +8,7 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; class Enum extends core::Object /*isEnum*/ { final field core::int index; @@ -47,17 +48,20 @@ static method method2(self::Enum? e) → core::int { { return 1; } + #L4: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); } } static method method3(self::Enum? e) → core::int { switch(e) { - #L4: + #L5: case #C3: case #C6: { return 0; } - #L5: + #L6: default: { return 1; @@ -66,13 +70,13 @@ static method method3(self::Enum? e) → core::int { } static method method4(self::Enum? e) → core::int { switch(e) { - #L6: + #L7: case #C3: case #C6: { return 0; } - #L7: + #L8: case #C8: default: { diff --git a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.transformed.expect index 43d8018dda03f..0a559cb61bccc 100644 --- a/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/switch_nullable_enum.dart.weak.transformed.expect @@ -8,6 +8,7 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; class Enum extends core::Object /*isEnum*/ { final field core::int index; @@ -47,17 +48,20 @@ static method method2(self::Enum? e) → core::int { { return 1; } + #L4: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); } } static method method3(self::Enum? e) → core::int { switch(e) { - #L4: + #L5: case #C3: case #C6: { return 0; } - #L5: + #L6: default: { return 1; @@ -66,13 +70,13 @@ static method method3(self::Enum? e) → core::int { } static method method4(self::Enum? e) → core::int { switch(e) { - #L6: + #L7: case #C3: case #C6: { return 0; } - #L7: + #L8: case #C8: default: { diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.weak.expect b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.weak.expect index d0e258ce0a6ba..d5183ef1a6d2c 100644 --- a/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.weak.expect @@ -8,6 +8,7 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; abstract class A extends core::Object { synthetic constructor •() → self::A @@ -18,7 +19,7 @@ abstract class A extends core::Object { #L1: case #C1: { - this.{self::A::neverReturn}(); + let final Never #t1 = this.{self::A::neverReturn}() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } #L2: default: @@ -35,7 +36,7 @@ static method foo(core::int x, core::bool b) → dynamic { #L3: case #C1: { - b ?{Never} throw "hest" : throw "fisk"; + let final Never #t2 = b ?{Never} throw "hest" : throw "fisk" in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } #L4: case #C2: diff --git a/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.weak.transformed.expect index d0e258ce0a6ba..d5183ef1a6d2c 100644 --- a/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/switch_redesign_fall_over.dart.weak.transformed.expect @@ -8,6 +8,7 @@ library /*isNonNullableByDefault*/; // import self as self; import "dart:core" as core; +import "dart:_internal" as _in; abstract class A extends core::Object { synthetic constructor •() → self::A @@ -18,7 +19,7 @@ abstract class A extends core::Object { #L1: case #C1: { - this.{self::A::neverReturn}(); + let final Never #t1 = this.{self::A::neverReturn}() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } #L2: default: @@ -35,7 +36,7 @@ static method foo(core::int x, core::bool b) → dynamic { #L3: case #C1: { - b ?{Never} throw "hest" : throw "fisk"; + let final Never #t2 = b ?{Never} throw "hest" : throw "fisk" in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } #L4: case #C2: diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.weak.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.weak.expect index 4db6f6e7b5b59..8762f10f52e7c 100644 --- a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.weak.expect @@ -1,17 +1,18 @@ library /*isNonNullableByDefault*/; import self as self; import "dart:core" as core; +import "dart:_internal" as _in; class A extends core::Object { synthetic constructor •() → self::A : super core::Object::•() ; method foo() → self::A::X - return self::never(); + return let final Never #t1 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); method bar() → self::A::X? return null; method baz() → self::A::Y% - return self::never(); + return let final Never #t2 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } class B = core::List, Y extends core::Object? = core::Object?> extends core::Object { synthetic constructor •() → self::B @@ -35,21 +36,21 @@ static method never() → Never return throw "Never"; static method main() → dynamic { function fun1() → X - return self::never(); + return let final Never #t3 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun2() → Y% - return self::never(); + return let final Never #t4 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun3 = core::List, Y extends core::Object? = core::Object?>() → X - return self::never(); + return let final Never #t5 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun4 = core::List, Y extends core::Object? = core::Object?>() → Y% - return self::never(); + return let final Never #t6 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun5? = core::List?, Y extends core::List? = core::List?>() → X% - return self::never(); + return let final Never #t7 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun6? = core::List?, Y extends core::List? = core::List?>() → Y% - return self::never(); + return let final Never #t8 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun7() → X% - return self::never(); + return let final Never #t9 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun8() → Y% - return self::never(); + return let final Never #t10 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun9() → Z% - return self::never(); + return let final Never #t11 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.weak.transformed.expect index 4db6f6e7b5b59..8762f10f52e7c 100644 --- a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.weak.transformed.expect @@ -1,17 +1,18 @@ library /*isNonNullableByDefault*/; import self as self; import "dart:core" as core; +import "dart:_internal" as _in; class A extends core::Object { synthetic constructor •() → self::A : super core::Object::•() ; method foo() → self::A::X - return self::never(); + return let final Never #t1 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); method bar() → self::A::X? return null; method baz() → self::A::Y% - return self::never(); + return let final Never #t2 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } class B = core::List, Y extends core::Object? = core::Object?> extends core::Object { synthetic constructor •() → self::B @@ -35,21 +36,21 @@ static method never() → Never return throw "Never"; static method main() → dynamic { function fun1() → X - return self::never(); + return let final Never #t3 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun2() → Y% - return self::never(); + return let final Never #t4 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun3 = core::List, Y extends core::Object? = core::Object?>() → X - return self::never(); + return let final Never #t5 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun4 = core::List, Y extends core::Object? = core::Object?>() → Y% - return self::never(); + return let final Never #t6 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun5? = core::List?, Y extends core::List? = core::List?>() → X% - return self::never(); + return let final Never #t7 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun6? = core::List?, Y extends core::List? = core::List?>() → Y% - return self::never(); + return let final Never #t8 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun7() → X% - return self::never(); + return let final Never #t9 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun8() → Y% - return self::never(); + return let final Never #t10 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); function fun9() → Z% - return self::never(); + return let final Never #t11 = self::never() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); } diff --git a/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.expect index 974155d85210f..3c9a505326b22 100644 --- a/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.expect +++ b/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.expect @@ -129,6 +129,7 @@ library /*isNonNullableByDefault*/; // import self as nev; import "dart:core" as core; +import "dart:_internal" as _in; import "never_opt_out.dart" as self; import "org-dartlang-testcase:///never_opt_out.dart"; @@ -140,14 +141,14 @@ class A extends core::Object { : super core::Object::•() ; method neverMethod(Never value) → Never - return value; + return let final Never #t1 = value in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); get neverProperty() → Never return throw "Should not reach here"; set neverProperty(Never value) → void {} method nullMethod(core::Null? value) → core::Null? return value; get nullProperty() → core::Null? - return let final #t1 = invalid-expression "pkg/front_end/testcases/nnbd_mixed/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be returned from a function with return type 'Null'. + return let final #t2 = invalid-expression "pkg/front_end/testcases/nnbd_mixed/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be returned from a function with return type 'Null'. - 'Type' is from 'dart:core'. Null get nullProperty => Null; ^" in core::Null? as{TypeError,ForNonNullableByDefault} core::Null?; diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart new file mode 100644 index 0000000000000..3939918b13f52 --- /dev/null +++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart @@ -0,0 +1,286 @@ +// 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. + +// @dart=2.8 + +import 'unsound_checks_lib.dart'; + +isNullOptOut1(int i) => i == null; + +isNotNullOptOut1(int i) => i != null; + +isNullOptOut2(int i) => null == i; + +isNotNullOptOut2(int i) => null != i; + +ifNullOptOut(int i) => i ?? 42; + +class OptOutClass1 {} + +extension OptOutExtension on OptOutClass1 { + int operator [](int index) => index; + void operator []=(int index, int value) {} +} + +extensionIfNullOptOut1(int i) => OptOutExtension(new OptOutClass1())[i] ??= 42; + +extensionIfNullOptOut1ForEffect(int i) { + OptOutExtension(new OptOutClass1())[i] ??= 42; +} + +extensionIfNullOptOut2(int i) => new OptOutClass1()[i] ??= 42; + +extensionIfNullOptOut2ForEffect(int i) { + new OptOutClass1()[i] ??= 42; +} + +class OptOutClass2 { + int operator [](int index) => index; + void operator []=(int index, int value) {} +} + +ifNullIndexSetOptOut(int i) => new OptOutClass2()[i] ??= 42; + +ifNullIndexSetOptOutForEffect(int i) { + new OptOutClass2()[i] ??= 42; +} + +class OptOutClass3 { + int field; + + OptOutClass3(this.field); +} + +ifNullPropertySetOptOut(int i) => new OptOutClass3(i).field ??= 42; + +ifNullPropertySetOptOutForEffect(int i) { + new OptOutClass3(i).field ??= 42; +} + +ifNullSetOptOut(int i) => i ??= 42; + +ifNullSetOptOutForEffect(int i) { + i ??= 42; +} + +class OptOutSuperClass4 { + int operator [](int index) => index; + void operator []=(int index, int value) {} +} + +class OptOutClass4 extends OptOutSuperClass4 { + method(int i) => super[i] ??= 42; + methodForEffect(int i) { + super[i] ??= 42; + } +} + +ifNullSuperIndexSetOptOut(int i) => new OptOutClass4().method(i); + +ifNullSuperIndexSetOptOutForEffect(int i) { + new OptOutClass4().methodForEffect(i); +} + +class OptOutClass5 { + int field; + + OptOutClass5(this.field); +} + +nullAwareIfNullSetOptOut(int i) { + OptOutClass5 o = new OptOutClass5(i); + return o?.field ??= 42; +} + +nullAwareIfNullSetOptOutForEffect(int i) { + OptOutClass5 o = new OptOutClass5(i); + o?.field ??= 42; +} + +isTestOptOut(int i) => i is int; + +isNotTestOptOut(int i) => i is! int; + +main() { + expect(false, isNullOptIn1(0)); + expect(false, isNullOptOut1(0)); + + expect(true, isNullOptIn1(null)); + expect(true, isNullOptOut1(null)); + + expect(true, isNotNullOptIn1(0)); + expect(true, isNotNullOptOut1(0)); + + expect(false, isNotNullOptIn1(null)); + expect(false, isNotNullOptOut1(null)); + + expect(false, isNullOptIn2(0)); + expect(false, isNullOptOut2(0)); + + expect(true, isNullOptIn2(null)); + expect(true, isNullOptOut2(null)); + + expect(true, isNotNullOptIn2(0)); + expect(true, isNotNullOptOut2(0)); + + expect(false, isNotNullOptIn2(null)); + expect(false, isNotNullOptOut2(null)); + + expect(0, ifNullOptIn(0)); + expect(0, ifNullOptOut(0)); + + expect(42, ifNullOptIn(null)); + expect(42, ifNullOptOut(null)); + + expect(0, extensionIfNullOptIn1(0)); + expect(0, extensionIfNullOptOut1(0)); + + expect(42, extensionIfNullOptIn1(null)); + expect(42, extensionIfNullOptOut1(null)); + + extensionIfNullOptIn1ForEffect(0); + extensionIfNullOptOut1ForEffect(0); + + extensionIfNullOptIn1ForEffect(null); + extensionIfNullOptOut1ForEffect(null); + + expect(0, extensionIfNullOptIn2(0)); + expect(0, extensionIfNullOptOut2(0)); + + expect(42, extensionIfNullOptIn2(null)); + expect(42, extensionIfNullOptOut2(null)); + + extensionIfNullOptIn2ForEffect(0); + extensionIfNullOptOut2ForEffect(0); + + extensionIfNullOptIn2ForEffect(null); + extensionIfNullOptOut2ForEffect(null); + + expect(0, ifNullIndexSetOptIn(0)); + expect(0, ifNullIndexSetOptOut(0)); + + expect(42, ifNullIndexSetOptIn(null)); + expect(42, ifNullIndexSetOptOut(null)); + + ifNullIndexSetOptInForEffect(0); + ifNullIndexSetOptOutForEffect(0); + + ifNullIndexSetOptInForEffect(null); + ifNullIndexSetOptOutForEffect(null); + + expect(0, ifNullPropertySetOptIn(0)); + expect(0, ifNullPropertySetOptOut(0)); + + expect(42, ifNullPropertySetOptIn(null)); + expect(42, ifNullPropertySetOptOut(null)); + + ifNullPropertySetOptInForEffect(0); + ifNullPropertySetOptOutForEffect(0); + + ifNullPropertySetOptInForEffect(null); + ifNullPropertySetOptOutForEffect(null); + + expect(0, ifNullSetOptIn(0)); + expect(0, ifNullSetOptOut(0)); + + expect(42, ifNullSetOptIn(null)); + expect(42, ifNullSetOptOut(null)); + + ifNullSetOptInForEffect(0); + ifNullSetOptOutForEffect(0); + + ifNullSetOptInForEffect(null); + ifNullSetOptOutForEffect(null); + + expect(0, ifNullSuperIndexSetOptIn(0)); + expect(0, ifNullSuperIndexSetOptOut(0)); + + expect(42, ifNullSuperIndexSetOptIn(null)); + expect(42, ifNullSuperIndexSetOptOut(null)); + + ifNullSuperIndexSetOptInForEffect(0); + ifNullSuperIndexSetOptOutForEffect(0); + + ifNullSuperIndexSetOptInForEffect(null); + ifNullSuperIndexSetOptOutForEffect(null); + + expect(0, nullAwareIfNullSetOptIn(0)); + expect(0, nullAwareIfNullSetOptOut(0)); + + expect(42, nullAwareIfNullSetOptIn(null)); + expect(42, nullAwareIfNullSetOptOut(null)); + + nullAwareIfNullSetOptInForEffect(0); + nullAwareIfNullSetOptOutForEffect(0); + + nullAwareIfNullSetOptInForEffect(null); + nullAwareIfNullSetOptOutForEffect(null); + + expect(true, isTestOptIn(0)); + expect(true, isTestOptOut(0)); + + expect(false, isTestOptIn(null)); + expect(false, isTestOptOut(null)); + + expect(false, isNotTestOptIn(0)); + expect(false, isNotTestOptOut(0)); + + expect(true, isNotTestOptIn(null)); + expect(true, isNotTestOptOut(null)); + + expect(true, nullAwareAccess1(0)); + expect(null, nullAwareAccess1(null)); + + promotionToNever(0); + promotionToNever(null); + + unnecessaryNullCheck(() => 0); + unnecessaryNullCheck(() => null); + + expect(0, unnecessaryIfNull(() => 0, () => 42)); + expect(42, unnecessaryIfNull(() => null, () => 42)); + + unnecessaryIfNullAssign([0], () => 42); + unnecessaryIfNullAssign([null], () => 42); + + unnecessaryNullAwareAccess(() => 0); + unnecessaryNullAwareAccess(() => null); + + throws(() => callReturningNever(() => throw 'foo'), (e) => e == 'foo'); + var f = () => null; + throws(() => callReturningNever(f)); + + switchOnEnum(E.e1); + switchOnEnum(E.e2); + throws(() => switchOnEnum(null)); + + switchOnEnumWithBreak(E.e1); + switchOnEnumWithBreak(E.e2); + throws(() => switchOnEnumWithBreak(null)); + + switchOnEnumWithFallThrough1(E.e1); + switchOnEnumWithFallThrough1(E.e2); + throws(() => switchOnEnumWithFallThrough1(null)); + + switchOnEnumWithFallThrough2(E.e1); + switchOnEnumWithFallThrough2(E.e2); + throws(() => switchOnEnumWithFallThrough2(null)); +} + +expect(expected, actual) { + if (expected != actual) throw 'Expected $expected, actual $actual'; +} + +throws(void f(), [bool Function(Object) testException]) { + try { + f(); + } catch (e) { + if (testException != null && !testException(e)) { + throw 'Unexpected exception: $e'; + } + print(e); + return; + } + throw 'Missing exception.'; +} diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline.expect new file mode 100644 index 0000000000000..50ce9f2e5c367 --- /dev/null +++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.textual_outline.expect @@ -0,0 +1,49 @@ +// @dart = 2.8 +import 'unsound_checks_lib.dart'; +isNullOptOut1(int i) => i == null; +isNotNullOptOut1(int i) => i != null; +isNullOptOut2(int i) => null == i; +isNotNullOptOut2(int i) => null != i; +ifNullOptOut(int i) => i ?? 42; +class OptOutClass1 {} +extension OptOutExtension ; +on OptOutClass1 (){} +extensionIfNullOptOut1(int i) => OptOutExtension(new OptOutClass1())[i] ??= 42; +extensionIfNullOptOut1ForEffect(int i) {} +extensionIfNullOptOut2(int i) => new OptOutClass1()[i] ??= 42; +extensionIfNullOptOut2ForEffect(int i) {} +class OptOutClass2 { + int operator [](int index) => index; + void operator []=(int index, int value) {} +} +ifNullIndexSetOptOut(int i) => new OptOutClass2()[i] ??= 42; +ifNullIndexSetOptOutForEffect(int i) {} +class OptOutClass3 { + int field; + OptOutClass3(this.field); +} +ifNullPropertySetOptOut(int i) => new OptOutClass3(i).field ??= 42; +ifNullPropertySetOptOutForEffect(int i) {} +ifNullSetOptOut(int i) => i ??= 42; +ifNullSetOptOutForEffect(int i) {} +class OptOutSuperClass4 { + int operator [](int index) => index; + void operator []=(int index, int value) {} +} +class OptOutClass4 extends OptOutSuperClass4 { + method(int i) => super[i] ??= 42; + methodForEffect(int i) {} +} +ifNullSuperIndexSetOptOut(int i) => new OptOutClass4().method(i); +ifNullSuperIndexSetOptOutForEffect(int i) {} +class OptOutClass5 { + int field; + OptOutClass5(this.field); +} +nullAwareIfNullSetOptOut(int i) {} +nullAwareIfNullSetOptOutForEffect(int i) {} +isTestOptOut(int i) => i is int; +isNotTestOptOut(int i) => i is! int; +main() {} +expect(expected, actual) {} +throws(void f(), [bool Function(Object) testException]) {} diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect new file mode 100644 index 0000000000000..211e16d2b200a --- /dev/null +++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect @@ -0,0 +1,621 @@ +library; +import self as self; +import "dart:core" as core; +import "unsound_checks_lib.dart" as uns; + +import "org-dartlang-testcase:///unsound_checks_lib.dart"; + +class OptOutClass1 extends core::Object { + synthetic constructor •() → self::OptOutClass1* + : super core::Object::•() + ; + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class OptOutClass2 extends core::Object { + synthetic constructor •() → self::OptOutClass2* + : super core::Object::•() + ; + operator [](core::int* index) → core::int* + return index; + operator []=(core::int* index, core::int* value) → void {} + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class OptOutClass3 extends core::Object { + field core::int* field; + constructor •(core::int* field) → self::OptOutClass3* + : self::OptOutClass3::field = field, super core::Object::•() + ; + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class OptOutSuperClass4 extends core::Object { + synthetic constructor •() → self::OptOutSuperClass4* + : super core::Object::•() + ; + operator [](core::int* index) → core::int* + return index; + operator []=(core::int* index, core::int* value) → void {} + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class OptOutClass4 extends self::OptOutSuperClass4 { + synthetic constructor •() → self::OptOutClass4* + : super self::OptOutSuperClass4::•() + ; + method method(core::int* i) → dynamic + return let final core::int* #t1 = i in let final core::int* #t2 = super.{self::OptOutSuperClass4::[]}(#t1) in #t2.{core::num::==}(null) ?{core::int*} let final core::int* #t3 = 42 in let final void #t4 = super.{self::OptOutSuperClass4::[]=}(#t1, #t3) in #t3 : #t2; + method methodForEffect(core::int* i) → dynamic { + let final core::int* #t5 = i in super.{self::OptOutSuperClass4::[]}(#t5).{core::num::==}(null) ?{core::int*} super.{self::OptOutSuperClass4::[]=}(#t5, 42) : null; + } +} +class OptOutClass5 extends core::Object { + field core::int* field; + constructor •(core::int* field) → self::OptOutClass5* + : self::OptOutClass5::field = field, super core::Object::•() + ; + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +extension OptOutExtension on self::OptOutClass1* { + operator [] = self::OptOutExtension|[]; + operator []= = self::OptOutExtension|[]=; +} +static method isNullOptOut1(core::int* i) → dynamic + return i.{core::num::==}(null); +static method isNotNullOptOut1(core::int* i) → dynamic + return !i.{core::num::==}(null); +static method isNullOptOut2(core::int* i) → dynamic + return null.{core::Object::==}(i); +static method isNotNullOptOut2(core::int* i) → dynamic + return !null.{core::Object::==}(i); +static method ifNullOptOut(core::int* i) → dynamic + return let final core::int* #t6 = i in #t6.{core::num::==}(null) ?{core::int*} 42 : #t6; +static method OptOutExtension|[](final self::OptOutClass1* #this, core::int* index) → core::int* + return index; +static method OptOutExtension|[]=(final self::OptOutClass1* #this, core::int* index, core::int* value) → void {} +static method extensionIfNullOptOut1(core::int* i) → dynamic + return let final self::OptOutClass1* #t7 = new self::OptOutClass1::•() in let final core::int* #t8 = i in let final core::int* #t9 = self::OptOutExtension|[](#t7, #t8) in #t9.{core::num::==}(null) ?{core::int*} let final core::int* #t10 = 42 in let final void #t11 = self::OptOutExtension|[]=(#t7, #t8, #t10) in #t10 : #t9; +static method extensionIfNullOptOut1ForEffect(core::int* i) → dynamic { + let final self::OptOutClass1* #t12 = new self::OptOutClass1::•() in let final core::int* #t13 = i in self::OptOutExtension|[](#t12, #t13).{core::num::==}(null) ?{core::int*} self::OptOutExtension|[]=(#t12, #t13, 42) : null; +} +static method extensionIfNullOptOut2(core::int* i) → dynamic + return let final self::OptOutClass1* #t14 = new self::OptOutClass1::•() in let final core::int* #t15 = i in let final core::int* #t16 = self::OptOutExtension|[](#t14, #t15) in #t16.{core::num::==}(null) ?{core::int*} let final core::int* #t17 = 42 in let final void #t18 = self::OptOutExtension|[]=(#t14, #t15, #t17) in #t17 : #t16; +static method extensionIfNullOptOut2ForEffect(core::int* i) → dynamic { + let final self::OptOutClass1* #t19 = new self::OptOutClass1::•() in let final core::int* #t20 = i in self::OptOutExtension|[](#t19, #t20).{core::num::==}(null) ?{core::int*} self::OptOutExtension|[]=(#t19, #t20, 42) : null; +} +static method ifNullIndexSetOptOut(core::int* i) → dynamic + return let final self::OptOutClass2* #t21 = new self::OptOutClass2::•() in let final core::int* #t22 = i in let final core::int* #t23 = #t21.{self::OptOutClass2::[]}(#t22) in #t23.{core::num::==}(null) ?{core::int*} let final core::int* #t24 = 42 in let final void #t25 = #t21.{self::OptOutClass2::[]=}(#t22, #t24) in #t24 : #t23; +static method ifNullIndexSetOptOutForEffect(core::int* i) → dynamic { + let final self::OptOutClass2* #t26 = new self::OptOutClass2::•() in let final core::int* #t27 = i in #t26.{self::OptOutClass2::[]}(#t27).{core::num::==}(null) ?{core::int*} #t26.{self::OptOutClass2::[]=}(#t27, 42) : null; +} +static method ifNullPropertySetOptOut(core::int* i) → dynamic + return let final self::OptOutClass3* #t28 = new self::OptOutClass3::•(i) in let final core::int* #t29 = #t28.{self::OptOutClass3::field} in #t29.{core::num::==}(null) ?{core::int*} #t28.{self::OptOutClass3::field} = 42 : #t29; +static method ifNullPropertySetOptOutForEffect(core::int* i) → dynamic { + let final self::OptOutClass3* #t30 = new self::OptOutClass3::•(i) in #t30.{self::OptOutClass3::field}.{core::num::==}(null) ?{core::int*} #t30.{self::OptOutClass3::field} = 42 : null; +} +static method ifNullSetOptOut(core::int* i) → dynamic + return let final core::int* #t31 = i in #t31.{core::num::==}(null) ?{core::int*} i = 42 : #t31; +static method ifNullSetOptOutForEffect(core::int* i) → dynamic { + i.{core::num::==}(null) ?{core::int*} i = 42 : null; +} +static method ifNullSuperIndexSetOptOut(core::int* i) → dynamic + return new self::OptOutClass4::•().{self::OptOutClass4::method}(i); +static method ifNullSuperIndexSetOptOutForEffect(core::int* i) → dynamic { + new self::OptOutClass4::•().{self::OptOutClass4::methodForEffect}(i); +} +static method nullAwareIfNullSetOptOut(core::int* i) → dynamic { + self::OptOutClass5* o = new self::OptOutClass5::•(i); + return let final self::OptOutClass5* #t32 = o in #t32.{self::OptOutClass5::==}(null) ?{core::int*} null : let final core::int* #t33 = #t32.{self::OptOutClass5::field} in #t33.{core::num::==}(null) ?{core::int*} #t32.{self::OptOutClass5::field} = 42 : #t33; +} +static method nullAwareIfNullSetOptOutForEffect(core::int* i) → dynamic { + self::OptOutClass5* o = new self::OptOutClass5::•(i); + let final self::OptOutClass5* #t34 = o in #t34.{self::OptOutClass5::==}(null) ?{core::int*} null : #t34.{self::OptOutClass5::field}.{core::num::==}(null) ?{core::int*} #t34.{self::OptOutClass5::field} = 42 : null; +} +static method isTestOptOut(core::int* i) → dynamic + return i is core::int*; +static method isNotTestOptOut(core::int* i) → dynamic + return !(i is core::int*); +static method main() → dynamic { + self::expect(false, uns::isNullOptIn1(0)); + self::expect(false, self::isNullOptOut1(0)); + self::expect(true, uns::isNullOptIn1(null)); + self::expect(true, self::isNullOptOut1(null)); + self::expect(true, uns::isNotNullOptIn1(0)); + self::expect(true, self::isNotNullOptOut1(0)); + self::expect(false, uns::isNotNullOptIn1(null)); + self::expect(false, self::isNotNullOptOut1(null)); + self::expect(false, uns::isNullOptIn2(0)); + self::expect(false, self::isNullOptOut2(0)); + self::expect(true, uns::isNullOptIn2(null)); + self::expect(true, self::isNullOptOut2(null)); + self::expect(true, uns::isNotNullOptIn2(0)); + self::expect(true, self::isNotNullOptOut2(0)); + self::expect(false, uns::isNotNullOptIn2(null)); + self::expect(false, self::isNotNullOptOut2(null)); + self::expect(0, uns::ifNullOptIn(0)); + self::expect(0, self::ifNullOptOut(0)); + self::expect(42, uns::ifNullOptIn(null)); + self::expect(42, self::ifNullOptOut(null)); + self::expect(0, uns::extensionIfNullOptIn1(0)); + self::expect(0, self::extensionIfNullOptOut1(0)); + self::expect(42, uns::extensionIfNullOptIn1(null)); + self::expect(42, self::extensionIfNullOptOut1(null)); + uns::extensionIfNullOptIn1ForEffect(0); + self::extensionIfNullOptOut1ForEffect(0); + uns::extensionIfNullOptIn1ForEffect(null); + self::extensionIfNullOptOut1ForEffect(null); + self::expect(0, uns::extensionIfNullOptIn2(0)); + self::expect(0, self::extensionIfNullOptOut2(0)); + self::expect(42, uns::extensionIfNullOptIn2(null)); + self::expect(42, self::extensionIfNullOptOut2(null)); + uns::extensionIfNullOptIn2ForEffect(0); + self::extensionIfNullOptOut2ForEffect(0); + uns::extensionIfNullOptIn2ForEffect(null); + self::extensionIfNullOptOut2ForEffect(null); + self::expect(0, uns::ifNullIndexSetOptIn(0)); + self::expect(0, self::ifNullIndexSetOptOut(0)); + self::expect(42, uns::ifNullIndexSetOptIn(null)); + self::expect(42, self::ifNullIndexSetOptOut(null)); + uns::ifNullIndexSetOptInForEffect(0); + self::ifNullIndexSetOptOutForEffect(0); + uns::ifNullIndexSetOptInForEffect(null); + self::ifNullIndexSetOptOutForEffect(null); + self::expect(0, uns::ifNullPropertySetOptIn(0)); + self::expect(0, self::ifNullPropertySetOptOut(0)); + self::expect(42, uns::ifNullPropertySetOptIn(null)); + self::expect(42, self::ifNullPropertySetOptOut(null)); + uns::ifNullPropertySetOptInForEffect(0); + self::ifNullPropertySetOptOutForEffect(0); + uns::ifNullPropertySetOptInForEffect(null); + self::ifNullPropertySetOptOutForEffect(null); + self::expect(0, uns::ifNullSetOptIn(0)); + self::expect(0, self::ifNullSetOptOut(0)); + self::expect(42, uns::ifNullSetOptIn(null)); + self::expect(42, self::ifNullSetOptOut(null)); + uns::ifNullSetOptInForEffect(0); + self::ifNullSetOptOutForEffect(0); + uns::ifNullSetOptInForEffect(null); + self::ifNullSetOptOutForEffect(null); + self::expect(0, uns::ifNullSuperIndexSetOptIn(0)); + self::expect(0, self::ifNullSuperIndexSetOptOut(0)); + self::expect(42, uns::ifNullSuperIndexSetOptIn(null)); + self::expect(42, self::ifNullSuperIndexSetOptOut(null)); + uns::ifNullSuperIndexSetOptInForEffect(0); + self::ifNullSuperIndexSetOptOutForEffect(0); + uns::ifNullSuperIndexSetOptInForEffect(null); + self::ifNullSuperIndexSetOptOutForEffect(null); + self::expect(0, uns::nullAwareIfNullSetOptIn(0)); + self::expect(0, self::nullAwareIfNullSetOptOut(0)); + self::expect(42, uns::nullAwareIfNullSetOptIn(null)); + self::expect(42, self::nullAwareIfNullSetOptOut(null)); + uns::nullAwareIfNullSetOptInForEffect(0); + self::nullAwareIfNullSetOptOutForEffect(0); + uns::nullAwareIfNullSetOptInForEffect(null); + self::nullAwareIfNullSetOptOutForEffect(null); + self::expect(true, uns::isTestOptIn(0)); + self::expect(true, self::isTestOptOut(0)); + self::expect(false, uns::isTestOptIn(null)); + self::expect(false, self::isTestOptOut(null)); + self::expect(false, uns::isNotTestOptIn(0)); + self::expect(false, self::isNotTestOptOut(0)); + self::expect(true, uns::isNotTestOptIn(null)); + self::expect(true, self::isNotTestOptOut(null)); + self::expect(true, uns::nullAwareAccess1(0)); + self::expect(null, uns::nullAwareAccess1(null)); + uns::promotionToNever(0); + uns::promotionToNever(null); + uns::unnecessaryNullCheck(() → core::int* => 0); + uns::unnecessaryNullCheck(() → core::Null? => null); + self::expect(0, uns::unnecessaryIfNull(() → core::int* => 0, () → core::int* => 42)); + self::expect(42, uns::unnecessaryIfNull(() → core::Null? => null, () → core::int* => 42)); + uns::unnecessaryIfNullAssign([0], () → core::int* => 42); + uns::unnecessaryIfNullAssign([null], () → core::int* => 42); + uns::unnecessaryNullAwareAccess(() → core::int* => 0); + uns::unnecessaryNullAwareAccess(() → core::Null? => null); + self::throws(() → dynamic => uns::callReturningNever(() → => throw "foo"), (core::Object* e) → core::bool* => e.{core::Object::==}("foo")); + () →* core::Null? f = () → core::Null? => null; + self::throws(() → dynamic => uns::callReturningNever(f as{TypeError} () → Never)); + uns::switchOnEnum(#C3); + uns::switchOnEnum(#C6); + self::throws(() → dynamic => uns::switchOnEnum(null)); + uns::switchOnEnumWithBreak(#C3); + uns::switchOnEnumWithBreak(#C6); + self::throws(() → dynamic => uns::switchOnEnumWithBreak(null)); + uns::switchOnEnumWithFallThrough1(#C3); + uns::switchOnEnumWithFallThrough1(#C6); + self::throws(() → dynamic => uns::switchOnEnumWithFallThrough1(null)); + uns::switchOnEnumWithFallThrough2(#C3); + uns::switchOnEnumWithFallThrough2(#C6); + self::throws(() → dynamic => uns::switchOnEnumWithFallThrough2(null)); +} +static method expect(dynamic expected, dynamic actual) → dynamic { + if(!expected.{core::Object::==}(actual)) + throw "Expected ${expected}, actual ${actual}"; +} +static method throws(() →* void f, [(core::Object*) →* core::bool* testException = #C7]) → dynamic { + try { + f.call(); + } + on dynamic catch(final dynamic e) { + if(!testException.{core::Object::==}(null) && !testException.call(e)) { + throw "Unexpected exception: ${e}"; + } + core::print(e); + return; + } + throw "Missing exception."; +} + +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:13:23: Warning: Operand of null-aware operation '??' has type 'int' which excludes null. +// ifNullOptIn(int i) => i ?? 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:22:66: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// extensionIfNullOptIn1(int i) => OptInExtension(new OptInClass1())[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:25:36: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// OptInExtension(new OptInClass1())[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:28:50: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// extensionIfNullOptIn2(int i) => new OptInClass1()[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:31:20: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// new OptInClass1()[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:39:48: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// ifNullIndexSetOptIn(int i) => new OptInClass2()[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:42:20: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// new OptInClass2()[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:51:53: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// ifNullPropertySetOptIn(int i) => new OptInClass3(i).field ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:54:22: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// new OptInClass3(i).field ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:57:26: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// ifNullSetOptIn(int i) => i ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:60:3: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// i ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:69:25: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// method(int i) => super[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:71:10: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// super[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:113:28: Warning: Operand of null-aware operation '?.' has type 'int' which excludes null. +// nullAwareAccess1(int i) => i?.isEven; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:116:3: Warning: Operand of null-aware operation '?.' has type 'int' which excludes null. +// i?.isEven; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:128:11: Warning: Operand of null-aware operation '??' has type 'int' which excludes null. +// return f() ?? +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:134:4: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// x[0] ??= f(); +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:138:4: Warning: Operand of null-aware operation '?.' has type 'int' which excludes null. +// f()?.gcd(0); // Should not throw if `f` returns null +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:195:10: Error: Not enough type information to disambiguate between literal set and literal map. +// Try providing type arguments for the literal explicitly to disambiguate it. +// return {...d}; // Should not throw ReachabilityError. +// ^ +// +import self as uns; +import "dart:core" as core; +import "dart:_internal" as _in; + +class OptInClass1 extends core::Object { + synthetic constructor •() → uns::OptInClass1 + : super core::Object::•() + ; +} +class OptInClass2 extends core::Object { + synthetic constructor •() → uns::OptInClass2 + : super core::Object::•() + ; + operator [](core::int index) → core::int + return index; + operator []=(core::int index, core::int value) → void {} +} +class OptInClass3 extends core::Object { + field core::int field; + constructor •(core::int field) → uns::OptInClass3 + : uns::OptInClass3::field = field, super core::Object::•() + ; +} +class OptInSuperClass4 extends core::Object { + synthetic constructor •() → uns::OptInSuperClass4 + : super core::Object::•() + ; + operator [](core::int index) → core::int + return index; + operator []=(core::int index, core::int value) → void {} +} +class OptInClass4 extends uns::OptInSuperClass4 { + synthetic constructor •() → uns::OptInClass4 + : super uns::OptInSuperClass4::•() + ; + method method(core::int i) → dynamic + return let final core::int #t35 = i in let final core::int #t36 = super.{uns::OptInSuperClass4::[]}(#t35) in #t36.{core::num::==}(null) ?{core::int} let final core::int #t37 = 42 in let final void #t38 = super.{uns::OptInSuperClass4::[]=}(#t35, #t37) in #t37 : #t36; + method methodForEffect(core::int i) → dynamic { + let final core::int #t39 = i in super.{uns::OptInSuperClass4::[]}(#t39).{core::num::==}(null) ?{core::int} super.{uns::OptInSuperClass4::[]=}(#t39, 42) : null; + } +} +class OptInClass5 extends core::Object { + field core::int field; + constructor •(core::int field) → uns::OptInClass5 + : uns::OptInClass5::field = field, super core::Object::•() + ; +} +class OptInClass6a extends core::Object { + final field uns::OptInClass6b cls; + constructor •(uns::OptInClass6b cls) → uns::OptInClass6a + : uns::OptInClass6a::cls = cls, super core::Object::•() + ; +} +class OptInClass6b extends core::Object { + final field core::int field; + constructor •(core::int field) → uns::OptInClass6b + : uns::OptInClass6b::field = field, super core::Object::•() + ; +} +class E extends core::Object /*isEnum*/ { + final field core::int index; + final field core::String _name; + static const field core::List values = #C8; + static const field uns::E e1 = #C3; + static const field uns::E e2 = #C6; + const constructor •(core::int index, core::String _name) → uns::E + : uns::E::index = index, uns::E::_name = _name, super core::Object::•() + ; + method toString() → core::String + return this.{=uns::E::_name}; +} +extension OptInExtension on uns::OptInClass1 { + operator [] = uns::OptInExtension|[]; + operator []= = uns::OptInExtension|[]=; +} +static method isNullOptIn1(core::int i) → dynamic + return i.{core::num::==}(null); +static method isNotNullOptIn1(core::int i) → dynamic + return !i.{core::num::==}(null); +static method isNullOptIn2(core::int i) → dynamic + return null.{core::Object::==}(i); +static method isNotNullOptIn2(core::int i) → dynamic + return !null.{core::Object::==}(i); +static method ifNullOptIn(core::int i) → dynamic + return let final core::int #t40 = i in #t40.{core::num::==}(null) ?{core::int} 42 : #t40; +static method OptInExtension|[](final uns::OptInClass1 #this, core::int index) → core::int + return index; +static method OptInExtension|[]=(final uns::OptInClass1 #this, core::int index, core::int value) → void {} +static method extensionIfNullOptIn1(core::int i) → dynamic + return let final uns::OptInClass1 #t41 = new uns::OptInClass1::•() in let final core::int #t42 = i in let final core::int #t43 = uns::OptInExtension|[](#t41, #t42) in #t43.{core::num::==}(null) ?{core::int} let final core::int #t44 = 42 in let final void #t45 = uns::OptInExtension|[]=(#t41, #t42, #t44) in #t44 : #t43; +static method extensionIfNullOptIn1ForEffect(core::int i) → dynamic { + let final uns::OptInClass1 #t46 = new uns::OptInClass1::•() in let final core::int #t47 = i in uns::OptInExtension|[](#t46, #t47).{core::num::==}(null) ?{core::int} uns::OptInExtension|[]=(#t46, #t47, 42) : null; +} +static method extensionIfNullOptIn2(core::int i) → dynamic + return let final uns::OptInClass1 #t48 = new uns::OptInClass1::•() in let final core::int #t49 = i in let final core::int #t50 = uns::OptInExtension|[](#t48, #t49) in #t50.{core::num::==}(null) ?{core::int} let final core::int #t51 = 42 in let final void #t52 = uns::OptInExtension|[]=(#t48, #t49, #t51) in #t51 : #t50; +static method extensionIfNullOptIn2ForEffect(core::int i) → dynamic { + let final uns::OptInClass1 #t53 = new uns::OptInClass1::•() in let final core::int #t54 = i in uns::OptInExtension|[](#t53, #t54).{core::num::==}(null) ?{core::int} uns::OptInExtension|[]=(#t53, #t54, 42) : null; +} +static method ifNullIndexSetOptIn(core::int i) → dynamic + return let final uns::OptInClass2 #t55 = new uns::OptInClass2::•() in let final core::int #t56 = i in let final core::int #t57 = #t55.{uns::OptInClass2::[]}(#t56) in #t57.{core::num::==}(null) ?{core::int} let final core::int #t58 = 42 in let final void #t59 = #t55.{uns::OptInClass2::[]=}(#t56, #t58) in #t58 : #t57; +static method ifNullIndexSetOptInForEffect(core::int i) → dynamic { + let final uns::OptInClass2 #t60 = new uns::OptInClass2::•() in let final core::int #t61 = i in #t60.{uns::OptInClass2::[]}(#t61).{core::num::==}(null) ?{core::int} #t60.{uns::OptInClass2::[]=}(#t61, 42) : null; +} +static method ifNullPropertySetOptIn(core::int i) → dynamic + return let final uns::OptInClass3 #t62 = new uns::OptInClass3::•(i) in let final core::int #t63 = #t62.{uns::OptInClass3::field} in #t63.{core::num::==}(null) ?{core::int} #t62.{uns::OptInClass3::field} = 42 : #t63; +static method ifNullPropertySetOptInForEffect(core::int i) → dynamic { + let final uns::OptInClass3 #t64 = new uns::OptInClass3::•(i) in #t64.{uns::OptInClass3::field}.{core::num::==}(null) ?{core::int} #t64.{uns::OptInClass3::field} = 42 : null; +} +static method ifNullSetOptIn(core::int i) → dynamic + return let final core::int #t65 = i in #t65.{core::num::==}(null) ?{core::int} i = 42 : #t65; +static method ifNullSetOptInForEffect(core::int i) → dynamic { + i.{core::num::==}(null) ?{core::int} i = 42 : null; +} +static method ifNullSuperIndexSetOptIn(core::int i) → dynamic + return new uns::OptInClass4::•().{uns::OptInClass4::method}(i); +static method ifNullSuperIndexSetOptInForEffect(core::int i) → dynamic { + new uns::OptInClass4::•().{uns::OptInClass4::methodForEffect}(i); +} +static method nullAwareIfNullSetOptIn(core::int i) → dynamic { + uns::OptInClass5? o = new uns::OptInClass5::•(i); + return let final uns::OptInClass5? #t66 = o in #t66.{core::Object::==}(null) ?{core::int?} null : let final core::int #t67 = #t66.{uns::OptInClass5::field} in #t67.{core::num::==}(null) ?{core::int} #t66.{uns::OptInClass5::field} = 42 : #t67; +} +static method nullAwareIfNullSetOptInForEffect(core::int i) → dynamic { + uns::OptInClass5? o = new uns::OptInClass5::•(i); + let final uns::OptInClass5? #t68 = o in #t68.{core::Object::==}(null) ?{core::int?} null : #t68.{uns::OptInClass5::field}.{core::num::==}(null) ?{core::int} #t68.{uns::OptInClass5::field} = 42 : null; +} +static method isTestOptIn(core::int i) → dynamic + return i is{ForNonNullableByDefault} core::int; +static method isNotTestOptIn(core::int i) → dynamic + return !(i is{ForNonNullableByDefault} core::int); +static method nullAwareAccess1(core::int i) → dynamic + return let final core::int #t69 = i in #t69.{core::num::==}(null) ?{core::bool?} null : #t69.{core::int::isEven}; +static method nullAwareAccessForEffect1(core::int i) → dynamic { + let final core::int #t70 = i in #t70.{core::num::==}(null) ?{core::bool?} null : #t70.{core::int::isEven}; +} +static method promotionToNever(core::int i) → dynamic { + if(i is{ForNonNullableByDefault} core::int) + return; +} +static method unnecessaryNullCheck(() → core::int f) → dynamic { + if(!f.call().{core::num::==}(null)) + return; +} +static method unnecessaryIfNull(() → core::int f, () → core::int g) → dynamic { + return let final core::int #t71 = f.call() in #t71.{core::num::==}(null) ?{core::int} g.call() : #t71; +} +static method unnecessaryIfNullAssign(core::List x, () → core::int f) → dynamic { + let final core::List #t72 = x in let final core::int #t73 = 0 in #t72.{core::List::[]}(#t73).{core::num::==}(null) ?{core::int} #t72.{core::List::[]=}(#t73, f.call()) : null; +} +static method unnecessaryNullAwareAccess(() → core::int f) → dynamic { + let final core::int #t74 = f.call() in #t74.{core::num::==}(null) ?{core::int?} null : #t74.{core::int::gcd}(0); +} +static method callReturningNever(() → Never f) → dynamic { + let final Never #t75 = f.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); +} +static method switchOnEnum(uns::E e) → dynamic { + switch(e) { + #L1: + case #C3: + { + return; + } + #L2: + case #C6: + { + return; + } + #L3: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); + } +} +static method switchOnEnumWithBreak(uns::E e) → dynamic { + #L4: + switch(e) { + #L5: + case #C3: + { + break #L4; + } + #L6: + case #C6: + { + break #L4; + } + #L7: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); + } +} +static method switchOnEnumWithFallThrough1(uns::E e) → dynamic { + #L8: + switch(e) { + #L9: + case #C3: + { + break #L8; + } + #L10: + case #C6: + { + break #L8; + } + #L11: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); + } +} +static method switchOnEnumWithFallThrough2(uns::E e) → dynamic { + #L12: + switch(e) { + #L13: + case #C3: + case #C6: + { + break #L12; + } + #L14: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); + } +} +static method handleThrow() → dynamic { + throw ""; +} +static method handleRethrow() → dynamic { + try { + uns::handleThrow(); + } + on core::Object catch(final core::Object _) { + rethrow; + } +} +static method handleInvalid(dynamic d) → dynamic { + return invalid-expression "pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:195:10: Error: Not enough type information to disambiguate between literal set and literal map. +Try providing type arguments for the literal explicitly to disambiguate it. + return {...d}; // Should not throw ReachabilityError. + ^"; +} + +constants { + #C1 = 0 + #C2 = "E.e1" + #C3 = uns::E {index:#C1, _name:#C2} + #C4 = 1 + #C5 = "E.e2" + #C6 = uns::E {index:#C4, _name:#C5} + #C7 = null + #C8 = [#C3, #C6] +} diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect new file mode 100644 index 0000000000000..211e16d2b200a --- /dev/null +++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect @@ -0,0 +1,621 @@ +library; +import self as self; +import "dart:core" as core; +import "unsound_checks_lib.dart" as uns; + +import "org-dartlang-testcase:///unsound_checks_lib.dart"; + +class OptOutClass1 extends core::Object { + synthetic constructor •() → self::OptOutClass1* + : super core::Object::•() + ; + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class OptOutClass2 extends core::Object { + synthetic constructor •() → self::OptOutClass2* + : super core::Object::•() + ; + operator [](core::int* index) → core::int* + return index; + operator []=(core::int* index, core::int* value) → void {} + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class OptOutClass3 extends core::Object { + field core::int* field; + constructor •(core::int* field) → self::OptOutClass3* + : self::OptOutClass3::field = field, super core::Object::•() + ; + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class OptOutSuperClass4 extends core::Object { + synthetic constructor •() → self::OptOutSuperClass4* + : super core::Object::•() + ; + operator [](core::int* index) → core::int* + return index; + operator []=(core::int* index, core::int* value) → void {} + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +class OptOutClass4 extends self::OptOutSuperClass4 { + synthetic constructor •() → self::OptOutClass4* + : super self::OptOutSuperClass4::•() + ; + method method(core::int* i) → dynamic + return let final core::int* #t1 = i in let final core::int* #t2 = super.{self::OptOutSuperClass4::[]}(#t1) in #t2.{core::num::==}(null) ?{core::int*} let final core::int* #t3 = 42 in let final void #t4 = super.{self::OptOutSuperClass4::[]=}(#t1, #t3) in #t3 : #t2; + method methodForEffect(core::int* i) → dynamic { + let final core::int* #t5 = i in super.{self::OptOutSuperClass4::[]}(#t5).{core::num::==}(null) ?{core::int*} super.{self::OptOutSuperClass4::[]=}(#t5, 42) : null; + } +} +class OptOutClass5 extends core::Object { + field core::int* field; + constructor •(core::int* field) → self::OptOutClass5* + : self::OptOutClass5::field = field, super core::Object::•() + ; + abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode + abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf + abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf + abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue + abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse + abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::== + abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode + abstract member-signature method toString() → core::String*; -> core::Object::toString + abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod + abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType +} +extension OptOutExtension on self::OptOutClass1* { + operator [] = self::OptOutExtension|[]; + operator []= = self::OptOutExtension|[]=; +} +static method isNullOptOut1(core::int* i) → dynamic + return i.{core::num::==}(null); +static method isNotNullOptOut1(core::int* i) → dynamic + return !i.{core::num::==}(null); +static method isNullOptOut2(core::int* i) → dynamic + return null.{core::Object::==}(i); +static method isNotNullOptOut2(core::int* i) → dynamic + return !null.{core::Object::==}(i); +static method ifNullOptOut(core::int* i) → dynamic + return let final core::int* #t6 = i in #t6.{core::num::==}(null) ?{core::int*} 42 : #t6; +static method OptOutExtension|[](final self::OptOutClass1* #this, core::int* index) → core::int* + return index; +static method OptOutExtension|[]=(final self::OptOutClass1* #this, core::int* index, core::int* value) → void {} +static method extensionIfNullOptOut1(core::int* i) → dynamic + return let final self::OptOutClass1* #t7 = new self::OptOutClass1::•() in let final core::int* #t8 = i in let final core::int* #t9 = self::OptOutExtension|[](#t7, #t8) in #t9.{core::num::==}(null) ?{core::int*} let final core::int* #t10 = 42 in let final void #t11 = self::OptOutExtension|[]=(#t7, #t8, #t10) in #t10 : #t9; +static method extensionIfNullOptOut1ForEffect(core::int* i) → dynamic { + let final self::OptOutClass1* #t12 = new self::OptOutClass1::•() in let final core::int* #t13 = i in self::OptOutExtension|[](#t12, #t13).{core::num::==}(null) ?{core::int*} self::OptOutExtension|[]=(#t12, #t13, 42) : null; +} +static method extensionIfNullOptOut2(core::int* i) → dynamic + return let final self::OptOutClass1* #t14 = new self::OptOutClass1::•() in let final core::int* #t15 = i in let final core::int* #t16 = self::OptOutExtension|[](#t14, #t15) in #t16.{core::num::==}(null) ?{core::int*} let final core::int* #t17 = 42 in let final void #t18 = self::OptOutExtension|[]=(#t14, #t15, #t17) in #t17 : #t16; +static method extensionIfNullOptOut2ForEffect(core::int* i) → dynamic { + let final self::OptOutClass1* #t19 = new self::OptOutClass1::•() in let final core::int* #t20 = i in self::OptOutExtension|[](#t19, #t20).{core::num::==}(null) ?{core::int*} self::OptOutExtension|[]=(#t19, #t20, 42) : null; +} +static method ifNullIndexSetOptOut(core::int* i) → dynamic + return let final self::OptOutClass2* #t21 = new self::OptOutClass2::•() in let final core::int* #t22 = i in let final core::int* #t23 = #t21.{self::OptOutClass2::[]}(#t22) in #t23.{core::num::==}(null) ?{core::int*} let final core::int* #t24 = 42 in let final void #t25 = #t21.{self::OptOutClass2::[]=}(#t22, #t24) in #t24 : #t23; +static method ifNullIndexSetOptOutForEffect(core::int* i) → dynamic { + let final self::OptOutClass2* #t26 = new self::OptOutClass2::•() in let final core::int* #t27 = i in #t26.{self::OptOutClass2::[]}(#t27).{core::num::==}(null) ?{core::int*} #t26.{self::OptOutClass2::[]=}(#t27, 42) : null; +} +static method ifNullPropertySetOptOut(core::int* i) → dynamic + return let final self::OptOutClass3* #t28 = new self::OptOutClass3::•(i) in let final core::int* #t29 = #t28.{self::OptOutClass3::field} in #t29.{core::num::==}(null) ?{core::int*} #t28.{self::OptOutClass3::field} = 42 : #t29; +static method ifNullPropertySetOptOutForEffect(core::int* i) → dynamic { + let final self::OptOutClass3* #t30 = new self::OptOutClass3::•(i) in #t30.{self::OptOutClass3::field}.{core::num::==}(null) ?{core::int*} #t30.{self::OptOutClass3::field} = 42 : null; +} +static method ifNullSetOptOut(core::int* i) → dynamic + return let final core::int* #t31 = i in #t31.{core::num::==}(null) ?{core::int*} i = 42 : #t31; +static method ifNullSetOptOutForEffect(core::int* i) → dynamic { + i.{core::num::==}(null) ?{core::int*} i = 42 : null; +} +static method ifNullSuperIndexSetOptOut(core::int* i) → dynamic + return new self::OptOutClass4::•().{self::OptOutClass4::method}(i); +static method ifNullSuperIndexSetOptOutForEffect(core::int* i) → dynamic { + new self::OptOutClass4::•().{self::OptOutClass4::methodForEffect}(i); +} +static method nullAwareIfNullSetOptOut(core::int* i) → dynamic { + self::OptOutClass5* o = new self::OptOutClass5::•(i); + return let final self::OptOutClass5* #t32 = o in #t32.{self::OptOutClass5::==}(null) ?{core::int*} null : let final core::int* #t33 = #t32.{self::OptOutClass5::field} in #t33.{core::num::==}(null) ?{core::int*} #t32.{self::OptOutClass5::field} = 42 : #t33; +} +static method nullAwareIfNullSetOptOutForEffect(core::int* i) → dynamic { + self::OptOutClass5* o = new self::OptOutClass5::•(i); + let final self::OptOutClass5* #t34 = o in #t34.{self::OptOutClass5::==}(null) ?{core::int*} null : #t34.{self::OptOutClass5::field}.{core::num::==}(null) ?{core::int*} #t34.{self::OptOutClass5::field} = 42 : null; +} +static method isTestOptOut(core::int* i) → dynamic + return i is core::int*; +static method isNotTestOptOut(core::int* i) → dynamic + return !(i is core::int*); +static method main() → dynamic { + self::expect(false, uns::isNullOptIn1(0)); + self::expect(false, self::isNullOptOut1(0)); + self::expect(true, uns::isNullOptIn1(null)); + self::expect(true, self::isNullOptOut1(null)); + self::expect(true, uns::isNotNullOptIn1(0)); + self::expect(true, self::isNotNullOptOut1(0)); + self::expect(false, uns::isNotNullOptIn1(null)); + self::expect(false, self::isNotNullOptOut1(null)); + self::expect(false, uns::isNullOptIn2(0)); + self::expect(false, self::isNullOptOut2(0)); + self::expect(true, uns::isNullOptIn2(null)); + self::expect(true, self::isNullOptOut2(null)); + self::expect(true, uns::isNotNullOptIn2(0)); + self::expect(true, self::isNotNullOptOut2(0)); + self::expect(false, uns::isNotNullOptIn2(null)); + self::expect(false, self::isNotNullOptOut2(null)); + self::expect(0, uns::ifNullOptIn(0)); + self::expect(0, self::ifNullOptOut(0)); + self::expect(42, uns::ifNullOptIn(null)); + self::expect(42, self::ifNullOptOut(null)); + self::expect(0, uns::extensionIfNullOptIn1(0)); + self::expect(0, self::extensionIfNullOptOut1(0)); + self::expect(42, uns::extensionIfNullOptIn1(null)); + self::expect(42, self::extensionIfNullOptOut1(null)); + uns::extensionIfNullOptIn1ForEffect(0); + self::extensionIfNullOptOut1ForEffect(0); + uns::extensionIfNullOptIn1ForEffect(null); + self::extensionIfNullOptOut1ForEffect(null); + self::expect(0, uns::extensionIfNullOptIn2(0)); + self::expect(0, self::extensionIfNullOptOut2(0)); + self::expect(42, uns::extensionIfNullOptIn2(null)); + self::expect(42, self::extensionIfNullOptOut2(null)); + uns::extensionIfNullOptIn2ForEffect(0); + self::extensionIfNullOptOut2ForEffect(0); + uns::extensionIfNullOptIn2ForEffect(null); + self::extensionIfNullOptOut2ForEffect(null); + self::expect(0, uns::ifNullIndexSetOptIn(0)); + self::expect(0, self::ifNullIndexSetOptOut(0)); + self::expect(42, uns::ifNullIndexSetOptIn(null)); + self::expect(42, self::ifNullIndexSetOptOut(null)); + uns::ifNullIndexSetOptInForEffect(0); + self::ifNullIndexSetOptOutForEffect(0); + uns::ifNullIndexSetOptInForEffect(null); + self::ifNullIndexSetOptOutForEffect(null); + self::expect(0, uns::ifNullPropertySetOptIn(0)); + self::expect(0, self::ifNullPropertySetOptOut(0)); + self::expect(42, uns::ifNullPropertySetOptIn(null)); + self::expect(42, self::ifNullPropertySetOptOut(null)); + uns::ifNullPropertySetOptInForEffect(0); + self::ifNullPropertySetOptOutForEffect(0); + uns::ifNullPropertySetOptInForEffect(null); + self::ifNullPropertySetOptOutForEffect(null); + self::expect(0, uns::ifNullSetOptIn(0)); + self::expect(0, self::ifNullSetOptOut(0)); + self::expect(42, uns::ifNullSetOptIn(null)); + self::expect(42, self::ifNullSetOptOut(null)); + uns::ifNullSetOptInForEffect(0); + self::ifNullSetOptOutForEffect(0); + uns::ifNullSetOptInForEffect(null); + self::ifNullSetOptOutForEffect(null); + self::expect(0, uns::ifNullSuperIndexSetOptIn(0)); + self::expect(0, self::ifNullSuperIndexSetOptOut(0)); + self::expect(42, uns::ifNullSuperIndexSetOptIn(null)); + self::expect(42, self::ifNullSuperIndexSetOptOut(null)); + uns::ifNullSuperIndexSetOptInForEffect(0); + self::ifNullSuperIndexSetOptOutForEffect(0); + uns::ifNullSuperIndexSetOptInForEffect(null); + self::ifNullSuperIndexSetOptOutForEffect(null); + self::expect(0, uns::nullAwareIfNullSetOptIn(0)); + self::expect(0, self::nullAwareIfNullSetOptOut(0)); + self::expect(42, uns::nullAwareIfNullSetOptIn(null)); + self::expect(42, self::nullAwareIfNullSetOptOut(null)); + uns::nullAwareIfNullSetOptInForEffect(0); + self::nullAwareIfNullSetOptOutForEffect(0); + uns::nullAwareIfNullSetOptInForEffect(null); + self::nullAwareIfNullSetOptOutForEffect(null); + self::expect(true, uns::isTestOptIn(0)); + self::expect(true, self::isTestOptOut(0)); + self::expect(false, uns::isTestOptIn(null)); + self::expect(false, self::isTestOptOut(null)); + self::expect(false, uns::isNotTestOptIn(0)); + self::expect(false, self::isNotTestOptOut(0)); + self::expect(true, uns::isNotTestOptIn(null)); + self::expect(true, self::isNotTestOptOut(null)); + self::expect(true, uns::nullAwareAccess1(0)); + self::expect(null, uns::nullAwareAccess1(null)); + uns::promotionToNever(0); + uns::promotionToNever(null); + uns::unnecessaryNullCheck(() → core::int* => 0); + uns::unnecessaryNullCheck(() → core::Null? => null); + self::expect(0, uns::unnecessaryIfNull(() → core::int* => 0, () → core::int* => 42)); + self::expect(42, uns::unnecessaryIfNull(() → core::Null? => null, () → core::int* => 42)); + uns::unnecessaryIfNullAssign([0], () → core::int* => 42); + uns::unnecessaryIfNullAssign([null], () → core::int* => 42); + uns::unnecessaryNullAwareAccess(() → core::int* => 0); + uns::unnecessaryNullAwareAccess(() → core::Null? => null); + self::throws(() → dynamic => uns::callReturningNever(() → => throw "foo"), (core::Object* e) → core::bool* => e.{core::Object::==}("foo")); + () →* core::Null? f = () → core::Null? => null; + self::throws(() → dynamic => uns::callReturningNever(f as{TypeError} () → Never)); + uns::switchOnEnum(#C3); + uns::switchOnEnum(#C6); + self::throws(() → dynamic => uns::switchOnEnum(null)); + uns::switchOnEnumWithBreak(#C3); + uns::switchOnEnumWithBreak(#C6); + self::throws(() → dynamic => uns::switchOnEnumWithBreak(null)); + uns::switchOnEnumWithFallThrough1(#C3); + uns::switchOnEnumWithFallThrough1(#C6); + self::throws(() → dynamic => uns::switchOnEnumWithFallThrough1(null)); + uns::switchOnEnumWithFallThrough2(#C3); + uns::switchOnEnumWithFallThrough2(#C6); + self::throws(() → dynamic => uns::switchOnEnumWithFallThrough2(null)); +} +static method expect(dynamic expected, dynamic actual) → dynamic { + if(!expected.{core::Object::==}(actual)) + throw "Expected ${expected}, actual ${actual}"; +} +static method throws(() →* void f, [(core::Object*) →* core::bool* testException = #C7]) → dynamic { + try { + f.call(); + } + on dynamic catch(final dynamic e) { + if(!testException.{core::Object::==}(null) && !testException.call(e)) { + throw "Unexpected exception: ${e}"; + } + core::print(e); + return; + } + throw "Missing exception."; +} + +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:13:23: Warning: Operand of null-aware operation '??' has type 'int' which excludes null. +// ifNullOptIn(int i) => i ?? 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:22:66: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// extensionIfNullOptIn1(int i) => OptInExtension(new OptInClass1())[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:25:36: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// OptInExtension(new OptInClass1())[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:28:50: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// extensionIfNullOptIn2(int i) => new OptInClass1()[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:31:20: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// new OptInClass1()[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:39:48: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// ifNullIndexSetOptIn(int i) => new OptInClass2()[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:42:20: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// new OptInClass2()[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:51:53: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// ifNullPropertySetOptIn(int i) => new OptInClass3(i).field ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:54:22: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// new OptInClass3(i).field ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:57:26: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// ifNullSetOptIn(int i) => i ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:60:3: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// i ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:69:25: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// method(int i) => super[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:71:10: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// super[i] ??= 42; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:113:28: Warning: Operand of null-aware operation '?.' has type 'int' which excludes null. +// nullAwareAccess1(int i) => i?.isEven; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:116:3: Warning: Operand of null-aware operation '?.' has type 'int' which excludes null. +// i?.isEven; +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:128:11: Warning: Operand of null-aware operation '??' has type 'int' which excludes null. +// return f() ?? +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:134:4: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null. +// x[0] ??= f(); +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:138:4: Warning: Operand of null-aware operation '?.' has type 'int' which excludes null. +// f()?.gcd(0); // Should not throw if `f` returns null +// ^ +// +// pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:195:10: Error: Not enough type information to disambiguate between literal set and literal map. +// Try providing type arguments for the literal explicitly to disambiguate it. +// return {...d}; // Should not throw ReachabilityError. +// ^ +// +import self as uns; +import "dart:core" as core; +import "dart:_internal" as _in; + +class OptInClass1 extends core::Object { + synthetic constructor •() → uns::OptInClass1 + : super core::Object::•() + ; +} +class OptInClass2 extends core::Object { + synthetic constructor •() → uns::OptInClass2 + : super core::Object::•() + ; + operator [](core::int index) → core::int + return index; + operator []=(core::int index, core::int value) → void {} +} +class OptInClass3 extends core::Object { + field core::int field; + constructor •(core::int field) → uns::OptInClass3 + : uns::OptInClass3::field = field, super core::Object::•() + ; +} +class OptInSuperClass4 extends core::Object { + synthetic constructor •() → uns::OptInSuperClass4 + : super core::Object::•() + ; + operator [](core::int index) → core::int + return index; + operator []=(core::int index, core::int value) → void {} +} +class OptInClass4 extends uns::OptInSuperClass4 { + synthetic constructor •() → uns::OptInClass4 + : super uns::OptInSuperClass4::•() + ; + method method(core::int i) → dynamic + return let final core::int #t35 = i in let final core::int #t36 = super.{uns::OptInSuperClass4::[]}(#t35) in #t36.{core::num::==}(null) ?{core::int} let final core::int #t37 = 42 in let final void #t38 = super.{uns::OptInSuperClass4::[]=}(#t35, #t37) in #t37 : #t36; + method methodForEffect(core::int i) → dynamic { + let final core::int #t39 = i in super.{uns::OptInSuperClass4::[]}(#t39).{core::num::==}(null) ?{core::int} super.{uns::OptInSuperClass4::[]=}(#t39, 42) : null; + } +} +class OptInClass5 extends core::Object { + field core::int field; + constructor •(core::int field) → uns::OptInClass5 + : uns::OptInClass5::field = field, super core::Object::•() + ; +} +class OptInClass6a extends core::Object { + final field uns::OptInClass6b cls; + constructor •(uns::OptInClass6b cls) → uns::OptInClass6a + : uns::OptInClass6a::cls = cls, super core::Object::•() + ; +} +class OptInClass6b extends core::Object { + final field core::int field; + constructor •(core::int field) → uns::OptInClass6b + : uns::OptInClass6b::field = field, super core::Object::•() + ; +} +class E extends core::Object /*isEnum*/ { + final field core::int index; + final field core::String _name; + static const field core::List values = #C8; + static const field uns::E e1 = #C3; + static const field uns::E e2 = #C6; + const constructor •(core::int index, core::String _name) → uns::E + : uns::E::index = index, uns::E::_name = _name, super core::Object::•() + ; + method toString() → core::String + return this.{=uns::E::_name}; +} +extension OptInExtension on uns::OptInClass1 { + operator [] = uns::OptInExtension|[]; + operator []= = uns::OptInExtension|[]=; +} +static method isNullOptIn1(core::int i) → dynamic + return i.{core::num::==}(null); +static method isNotNullOptIn1(core::int i) → dynamic + return !i.{core::num::==}(null); +static method isNullOptIn2(core::int i) → dynamic + return null.{core::Object::==}(i); +static method isNotNullOptIn2(core::int i) → dynamic + return !null.{core::Object::==}(i); +static method ifNullOptIn(core::int i) → dynamic + return let final core::int #t40 = i in #t40.{core::num::==}(null) ?{core::int} 42 : #t40; +static method OptInExtension|[](final uns::OptInClass1 #this, core::int index) → core::int + return index; +static method OptInExtension|[]=(final uns::OptInClass1 #this, core::int index, core::int value) → void {} +static method extensionIfNullOptIn1(core::int i) → dynamic + return let final uns::OptInClass1 #t41 = new uns::OptInClass1::•() in let final core::int #t42 = i in let final core::int #t43 = uns::OptInExtension|[](#t41, #t42) in #t43.{core::num::==}(null) ?{core::int} let final core::int #t44 = 42 in let final void #t45 = uns::OptInExtension|[]=(#t41, #t42, #t44) in #t44 : #t43; +static method extensionIfNullOptIn1ForEffect(core::int i) → dynamic { + let final uns::OptInClass1 #t46 = new uns::OptInClass1::•() in let final core::int #t47 = i in uns::OptInExtension|[](#t46, #t47).{core::num::==}(null) ?{core::int} uns::OptInExtension|[]=(#t46, #t47, 42) : null; +} +static method extensionIfNullOptIn2(core::int i) → dynamic + return let final uns::OptInClass1 #t48 = new uns::OptInClass1::•() in let final core::int #t49 = i in let final core::int #t50 = uns::OptInExtension|[](#t48, #t49) in #t50.{core::num::==}(null) ?{core::int} let final core::int #t51 = 42 in let final void #t52 = uns::OptInExtension|[]=(#t48, #t49, #t51) in #t51 : #t50; +static method extensionIfNullOptIn2ForEffect(core::int i) → dynamic { + let final uns::OptInClass1 #t53 = new uns::OptInClass1::•() in let final core::int #t54 = i in uns::OptInExtension|[](#t53, #t54).{core::num::==}(null) ?{core::int} uns::OptInExtension|[]=(#t53, #t54, 42) : null; +} +static method ifNullIndexSetOptIn(core::int i) → dynamic + return let final uns::OptInClass2 #t55 = new uns::OptInClass2::•() in let final core::int #t56 = i in let final core::int #t57 = #t55.{uns::OptInClass2::[]}(#t56) in #t57.{core::num::==}(null) ?{core::int} let final core::int #t58 = 42 in let final void #t59 = #t55.{uns::OptInClass2::[]=}(#t56, #t58) in #t58 : #t57; +static method ifNullIndexSetOptInForEffect(core::int i) → dynamic { + let final uns::OptInClass2 #t60 = new uns::OptInClass2::•() in let final core::int #t61 = i in #t60.{uns::OptInClass2::[]}(#t61).{core::num::==}(null) ?{core::int} #t60.{uns::OptInClass2::[]=}(#t61, 42) : null; +} +static method ifNullPropertySetOptIn(core::int i) → dynamic + return let final uns::OptInClass3 #t62 = new uns::OptInClass3::•(i) in let final core::int #t63 = #t62.{uns::OptInClass3::field} in #t63.{core::num::==}(null) ?{core::int} #t62.{uns::OptInClass3::field} = 42 : #t63; +static method ifNullPropertySetOptInForEffect(core::int i) → dynamic { + let final uns::OptInClass3 #t64 = new uns::OptInClass3::•(i) in #t64.{uns::OptInClass3::field}.{core::num::==}(null) ?{core::int} #t64.{uns::OptInClass3::field} = 42 : null; +} +static method ifNullSetOptIn(core::int i) → dynamic + return let final core::int #t65 = i in #t65.{core::num::==}(null) ?{core::int} i = 42 : #t65; +static method ifNullSetOptInForEffect(core::int i) → dynamic { + i.{core::num::==}(null) ?{core::int} i = 42 : null; +} +static method ifNullSuperIndexSetOptIn(core::int i) → dynamic + return new uns::OptInClass4::•().{uns::OptInClass4::method}(i); +static method ifNullSuperIndexSetOptInForEffect(core::int i) → dynamic { + new uns::OptInClass4::•().{uns::OptInClass4::methodForEffect}(i); +} +static method nullAwareIfNullSetOptIn(core::int i) → dynamic { + uns::OptInClass5? o = new uns::OptInClass5::•(i); + return let final uns::OptInClass5? #t66 = o in #t66.{core::Object::==}(null) ?{core::int?} null : let final core::int #t67 = #t66.{uns::OptInClass5::field} in #t67.{core::num::==}(null) ?{core::int} #t66.{uns::OptInClass5::field} = 42 : #t67; +} +static method nullAwareIfNullSetOptInForEffect(core::int i) → dynamic { + uns::OptInClass5? o = new uns::OptInClass5::•(i); + let final uns::OptInClass5? #t68 = o in #t68.{core::Object::==}(null) ?{core::int?} null : #t68.{uns::OptInClass5::field}.{core::num::==}(null) ?{core::int} #t68.{uns::OptInClass5::field} = 42 : null; +} +static method isTestOptIn(core::int i) → dynamic + return i is{ForNonNullableByDefault} core::int; +static method isNotTestOptIn(core::int i) → dynamic + return !(i is{ForNonNullableByDefault} core::int); +static method nullAwareAccess1(core::int i) → dynamic + return let final core::int #t69 = i in #t69.{core::num::==}(null) ?{core::bool?} null : #t69.{core::int::isEven}; +static method nullAwareAccessForEffect1(core::int i) → dynamic { + let final core::int #t70 = i in #t70.{core::num::==}(null) ?{core::bool?} null : #t70.{core::int::isEven}; +} +static method promotionToNever(core::int i) → dynamic { + if(i is{ForNonNullableByDefault} core::int) + return; +} +static method unnecessaryNullCheck(() → core::int f) → dynamic { + if(!f.call().{core::num::==}(null)) + return; +} +static method unnecessaryIfNull(() → core::int f, () → core::int g) → dynamic { + return let final core::int #t71 = f.call() in #t71.{core::num::==}(null) ?{core::int} g.call() : #t71; +} +static method unnecessaryIfNullAssign(core::List x, () → core::int f) → dynamic { + let final core::List #t72 = x in let final core::int #t73 = 0 in #t72.{core::List::[]}(#t73).{core::num::==}(null) ?{core::int} #t72.{core::List::[]=}(#t73, f.call()) : null; +} +static method unnecessaryNullAwareAccess(() → core::int f) → dynamic { + let final core::int #t74 = f.call() in #t74.{core::num::==}(null) ?{core::int?} null : #t74.{core::int::gcd}(0); +} +static method callReturningNever(() → Never f) → dynamic { + let final Never #t75 = f.call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`."); +} +static method switchOnEnum(uns::E e) → dynamic { + switch(e) { + #L1: + case #C3: + { + return; + } + #L2: + case #C6: + { + return; + } + #L3: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); + } +} +static method switchOnEnumWithBreak(uns::E e) → dynamic { + #L4: + switch(e) { + #L5: + case #C3: + { + break #L4; + } + #L6: + case #C6: + { + break #L4; + } + #L7: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); + } +} +static method switchOnEnumWithFallThrough1(uns::E e) → dynamic { + #L8: + switch(e) { + #L9: + case #C3: + { + break #L8; + } + #L10: + case #C6: + { + break #L8; + } + #L11: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); + } +} +static method switchOnEnumWithFallThrough2(uns::E e) → dynamic { + #L12: + switch(e) { + #L13: + case #C3: + case #C6: + { + break #L12; + } + #L14: + default: + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable enum type."); + } +} +static method handleThrow() → dynamic { + throw ""; +} +static method handleRethrow() → dynamic { + try { + uns::handleThrow(); + } + on core::Object catch(final core::Object _) { + rethrow; + } +} +static method handleInvalid(dynamic d) → dynamic { + return invalid-expression "pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart:195:10: Error: Not enough type information to disambiguate between literal set and literal map. +Try providing type arguments for the literal explicitly to disambiguate it. + return {...d}; // Should not throw ReachabilityError. + ^"; +} + +constants { + #C1 = 0 + #C2 = "E.e1" + #C3 = uns::E {index:#C1, _name:#C2} + #C4 = 1 + #C5 = "E.e2" + #C6 = uns::E {index:#C4, _name:#C5} + #C7 = null + #C8 = [#C3, #C6] +} diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart b/pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart new file mode 100644 index 0000000000000..6dd9b4708d69a --- /dev/null +++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks_lib.dart @@ -0,0 +1,196 @@ +// 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. + +isNullOptIn1(int i) => i == null; + +isNotNullOptIn1(int i) => i != null; + +isNullOptIn2(int i) => null == i; + +isNotNullOptIn2(int i) => null != i; + +ifNullOptIn(int i) => i ?? 42; + +class OptInClass1 {} + +extension OptInExtension on OptInClass1 { + int operator [](int index) => index; + void operator []=(int index, int value) {} +} + +extensionIfNullOptIn1(int i) => OptInExtension(new OptInClass1())[i] ??= 42; + +extensionIfNullOptIn1ForEffect(int i) { + OptInExtension(new OptInClass1())[i] ??= 42; +} + +extensionIfNullOptIn2(int i) => new OptInClass1()[i] ??= 42; + +extensionIfNullOptIn2ForEffect(int i) { + new OptInClass1()[i] ??= 42; +} + +class OptInClass2 { + int operator [](int index) => index; + void operator []=(int index, int value) {} +} + +ifNullIndexSetOptIn(int i) => new OptInClass2()[i] ??= 42; + +ifNullIndexSetOptInForEffect(int i) { + new OptInClass2()[i] ??= 42; +} + +class OptInClass3 { + int field; + + OptInClass3(this.field); +} + +ifNullPropertySetOptIn(int i) => new OptInClass3(i).field ??= 42; + +ifNullPropertySetOptInForEffect(int i) { + new OptInClass3(i).field ??= 42; +} + +ifNullSetOptIn(int i) => i ??= 42; + +ifNullSetOptInForEffect(int i) { + i ??= 42; +} + +class OptInSuperClass4 { + int operator [](int index) => index; + void operator []=(int index, int value) {} +} + +class OptInClass4 extends OptInSuperClass4 { + method(int i) => super[i] ??= 42; + methodForEffect(int i) { + super[i] ??= 42; + } +} + +ifNullSuperIndexSetOptIn(int i) => new OptInClass4().method(i); + +ifNullSuperIndexSetOptInForEffect(int i) { + new OptInClass4().methodForEffect(i); +} + +class OptInClass5 { + int field; + + OptInClass5(this.field); +} + +nullAwareIfNullSetOptIn(int i) { + OptInClass5? o = new OptInClass5(i); + return o?.field ??= 42; +} + +nullAwareIfNullSetOptInForEffect(int i) { + OptInClass5? o = new OptInClass5(i); + o?.field ??= 42; +} + +isTestOptIn(int i) => i is int; + +isNotTestOptIn(int i) => i is! int; + +class OptInClass6a { + final OptInClass6b cls; + + OptInClass6a(this.cls); +} + +class OptInClass6b { + final int field; + + OptInClass6b(this.field); +} + +nullAwareAccess1(int i) => i?.isEven; + +nullAwareAccessForEffect1(int i) { + i?.isEven; +} + +promotionToNever(int i) { + if (i is int) return; // Should not throw if `i` is null +} + +unnecessaryNullCheck(int f()) { + if (f() != null) return; // Should not throw if `f` returns null +} + +unnecessaryIfNull(int f(), int g()) { + return f() ?? + g(); // Should not throw if `f` returns null (rather than calling `g`) +} + +unnecessaryIfNullAssign(List x, int f()) { + // Should not throw if `x[0]` returns null (rather than calling `f`) + x[0] ??= f(); +} + +unnecessaryNullAwareAccess(int f()) { + f()?.gcd(0); // Should not throw if `f` returns null +} + +callReturningNever(Never f()) { + f(); // Should throw if `f` completes normally +} + +enum E { e1, e2 } + +switchOnEnum(E e) { + switch (e) { + case E.e1: + return; + case E.e2: + return; + } // Should throw if the implicit `default` branch is taken +} + +switchOnEnumWithBreak(E e) { + switch (e) { + case E.e1: + break; + case E.e2: + break; + } // Should throw if the implicit `default` branch is taken +} + +switchOnEnumWithFallThrough1(E e) { + switch (e) { + case E.e1: + break; + case E.e2: + } // Should throw if the implicit `default` branch is taken +} + +switchOnEnumWithFallThrough2(E e) { + switch (e) { + case E.e1: + case E.e2: + } // Should throw if the implicit `default` branch is taken +} + +handleThrow() { + throw ''; // Should not throw ReachabilityError. +} + +handleRethrow() { + try { + handleThrow(); + } catch (_) { + rethrow; // Should not throw ReachabilityError. + } +} + +handleInvalid(dynamic d) { + // This is deliberately creating a compile-time error to verify that we + // don't create ReachabilityError for invalid expressions. + return {...d}; // Should not throw ReachabilityError. +} diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status index bc6e72f18f217..545d83ed58909 100644 --- a/pkg/front_end/testcases/textual_outline.status +++ b/pkg/front_end/testcases/textual_outline.status @@ -197,6 +197,7 @@ nnbd_mixed/no_null_shorting_extension: FormatterCrash nnbd_mixed/null_safety_invalid_language_version: FormatterCrash nnbd_mixed/nullable_extension_on_opt_out: FormatterCrash nnbd_mixed/opt_out: FormatterCrash +nnbd_mixed/unsound_checks: FormatterCrash nonfunction_type_aliases/issue41501: FormatterCrash rasta/bad_redirection: FormatterCrash rasta/issue_000032: FormatterCrash diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart index fd864cf0f96aa..ca2413106ecfc 100644 --- a/pkg/front_end/tool/_fasta/command_line.dart +++ b/pkg/front_end/tool/_fasta/command_line.dart @@ -197,6 +197,7 @@ const Map optionSpecification = Flags.target: const StringValue(), Flags.verbose: const BoolValue(false), Flags.verify: const BoolValue(false), + Flags.warnOnReachabilityCheck: const BoolValue(false), Flags.linkDependencies: const UriListValue(), Flags.noDeps: const BoolValue(false), "-D": const DefineValue(), @@ -298,6 +299,8 @@ ProcessedOptions analyzeCommandLine(String programName, ? NnbdMode.Agnostic : (nnbdStrongMode ? NnbdMode.Strong : NnbdMode.Weak); + final bool warnOnReachabilityCheck = options[Flags.warnOnReachabilityCheck]; + final List linkDependencies = options[Flags.linkDependencies] ?? []; if (nnbdStrongMode && nnbdWeakMode) { @@ -348,7 +351,8 @@ ProcessedOptions analyzeCommandLine(String programName, ..environmentDefines = noDefines ? null : parsedArguments.defines ..nnbdMode = nnbdMode ..additionalDills = linkDependencies - ..emitDeps = !noDeps; + ..emitDeps = !noDeps + ..warnOnReachabilityCheck = warnOnReachabilityCheck; if (programName == "compile_platform") { if (arguments.length != 5) { diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart index 832f96636a34a..d67ff485fcfb2 100644 --- a/pkg/kernel/lib/core_types.dart +++ b/pkg/kernel/lib/core_types.dart @@ -31,6 +31,7 @@ class CoreTypes { ], 'dart:_internal': [ 'LateInitializationErrorImpl', + 'ReachabilityError', 'Symbol', ], 'dart:async': [ @@ -97,6 +98,7 @@ class CoreTypes { Procedure _awaitHelperProcedure; Procedure _boolFromEnvironment; Constructor _lateInitializationErrorConstructor; + Constructor _reachabilityErrorConstructor; /// The `dart:mirrors` library, or `null` if the component does not use it. Library _mirrorsLibrary; @@ -1235,6 +1237,11 @@ class CoreTypes { index.getMember('dart:_internal', 'LateInitializationErrorImpl', ''); } + Constructor get reachabilityErrorConstructor { + return _reachabilityErrorConstructor ??= + index.getMember('dart:_internal', 'ReachabilityError', ''); + } + InterfaceType bottomInterfaceType(Class klass, Nullability nullability) { InterfaceType result = _bottomInterfaceTypes[klass]; if (result == null) { diff --git a/sdk/lib/internal/errors.dart b/sdk/lib/internal/errors.dart index 9010622b8f387..93c01f12d6f57 100644 --- a/sdk/lib/internal/errors.dart +++ b/sdk/lib/internal/errors.dart @@ -17,3 +17,16 @@ class LateInitializationErrorImpl extends Error : "LateInitializationError"; } } + +class ReachabilityError extends Error { + final String? _message; + + ReachabilityError([this._message]); + + String toString() { + var message = _message; + return (message != null) + ? "ReachabilityError: $message" + : "ReachabilityError"; + } +} From def50905c2f5f3eb40b916facb0e2c6c34ab604b Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Fri, 25 Sep 2020 08:35:03 +0000 Subject: [PATCH 2/4] Make flow analysis handling of is/==/??=/?. consistent with mixed mode semantics Bug: https://github.com/dart-lang/language/issues/1143 Change-Id: Id177f8b19c15ef246f21ddd840410cddfee2e5cc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/163600 Commit-Queue: Johnni Winther Reviewed-by: Konstantin Shcheglov --- .../lib/src/flow_analysis/flow_analysis.dart | 42 +++--- .../flow_analysis/flow_analysis_test.dart | 92 +++++++------ .../reachability/data/equality_operator.dart | 10 +- .../reachability/data/if_null.dart | 125 ++++++++++++------ .../reachability/data/null_aware_access.dart | 40 +++--- .../flow_analysis/type_promotion/data/if.dart | 14 +- .../fix/remove_if_null_operator_test.dart | 11 +- .../dead_null_aware_expression_test.dart | 18 +-- ...ally_non_nullable_local_variable_test.dart | 8 -- pkg/expect/lib/expect.dart | 6 + .../test/spell_checking_list_common.txt | 2 + runtime/vm/compiler/recognized_methods_list.h | 2 +- .../boolean_conversion_weak_test.dart | 2 +- .../never/never_null_assignability_lib1.dart | 11 +- 14 files changed, 219 insertions(+), 164 deletions(-) diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart index 2db5055ccb4cf..1663cd4862191 100644 --- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart +++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart @@ -1587,9 +1587,17 @@ class FlowModel { } Type factoredType = typeOperations.factor(previousType, type); - Type typeIfFailed = typeOperations.isSameType(factoredType, previousType) - ? null - : factoredType; + Type typeIfFailed; + if (typeOperations.isNever(factoredType)) { + // Promoting to `Never` would mark the code as unreachable. But it might + // be reachable due to mixed mode unsoundness. So don't promote. + typeIfFailed = null; + } else if (typeOperations.isSameType(factoredType, previousType)) { + // No change to the type, so don't promote. + typeIfFailed = null; + } else { + typeIfFailed = factoredType; + } FlowModel modelIfFailed = _finishTypeTest(typeOperations, variable, info, type, typeIfFailed); @@ -2590,8 +2598,11 @@ class _FlowAnalysisImpl && rhsInfo is _VariableReadInfo) { assert( @@ -2607,7 +2618,7 @@ class _FlowAnalysisImpl(promoted)); - return _current.reachable; + return true; } @override @@ -2812,7 +2819,7 @@ class _FlowAnalysisImpl shortingModel = _current; - if (typeOperations.classifyType(targetType) == - TypeClassification.nonNullable) { - shortingModel = shortingModel.setReachable(false); - shortingIsReachable = false; - } - _stack.add(new _SimpleContext(shortingModel)); + _stack.add(new _SimpleContext(_current)); if (target != null) { ExpressionInfo targetInfo = _getExpressionInfo(target); if (targetInfo is _VariableReadInfo) { @@ -2907,7 +2907,7 @@ class _FlowAnalysisImpl(T x) { } void nonNullableTypeVar(T x) { - if (x == null) /*unreachable*/ { - /*stmt: unreachable*/ 1; + if (x == null) { + // Reachable since the value of x might come from legacy code + 1; } else { 2; } diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/if_null.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/if_null.dart index 0cc336e3b2186..fa2053df93d23 100644 --- a/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/if_null.dart +++ b/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/if_null.dart @@ -11,20 +11,19 @@ void variable_if_null_assign_reachable(int? i) { } void variable_if_null_unreachable(int i) { - i ?? /*unreachable*/ 0; + // Reachable since the value of i might come from legacy code + i ?? 0; } void variable_if_null_assign_unreachable(int i) { - // Note: CFE reports that the update to `i` is unreachable; analyzer does not. - // This is ok; what matters is that the RHS is unreachable. - /*cfe.update: unreachable*/ i ??= /*unreachable*/ 0; + // Reachable since the value of i might come from legacy code + i ??= 0; } void variable_if_null_assign_unreachable_due_to_promotion(int? i) { if (i == null) return; - // Note: CFE reports that the update to `i` is unreachable; analyzer does not. - // This is ok; what matters is that the RHS is unreachable. - /*cfe.update: unreachable*/ i ??= /*unreachable*/ 0; + // Reachable since the value of i might come from legacy code + i ??= 0; } /*member: topLevelNullable:doesNotComplete*/ @@ -44,14 +43,15 @@ void top_level_if_null_assign_reachable() { } void top_level_if_null_unreachable() { - topLevelNonNullGet ?? /*unreachable*/ 0; + // Reachable since the value returned by topLevelNonNullGet might come from + // legacy code + topLevelNonNullGet ?? 0; } void top_level_if_null_assign_unreachable() { - // Note: CFE reports that the update to `topLevelNonNullGet` is unreachable; - // analyzer does not. This is ok; what matters is that the RHS is - // unreachable. - topLevelNonNullGet /*cfe.update: unreachable*/ ??= /*unreachable*/ 0; + // Reachable since the value returned by topLevelNonNullGet might come from + // legacy code + topLevelNonNullGet ??= 0; } class HasProperty { @@ -69,11 +69,13 @@ void property_if_null_assign_reachable(HasProperty x) { } void property_if_null_unreachable(HasProperty x) { - x.prop ?? /*unreachable*/ 0; + // Reachable since the value returned by prop might come from legacy code + x.prop ?? 0; } void property_if_null_assign_unreachable(HasProperty x) { - x.prop ??= /*unreachable*/ 0; + // Reachable since the value returned by prop might come from legacy code + x.prop ??= 0; } void null_aware_property_if_null_reachable(HasProperty? x) { @@ -85,12 +87,14 @@ void null_aware_property_if_null_assign_reachable(HasProperty? x) { } void null_aware_property_if_null_not_shortened(HasProperty? x) { - // If `??` participated in null-shortening, `0` would be unreachable. + // Reachable since the value returned by prop might come from legacy code. + // Also since `??` doesn't participate in null shortening. x?.prop ?? 0; } void null_aware_property_if_null_assign_unreachable(HasProperty? x) { - x?.prop ??= /*unreachable*/ 0; + // Reachable since the value returned by prop might come from legacy code. + x?.prop ??= 0; } class SuperIntQuestionProperty extends HasProperty { @@ -105,11 +109,13 @@ class SuperIntQuestionProperty extends HasProperty { class SuperIntProperty extends HasProperty { void if_null_unreachable() { - super.prop ?? /*unreachable*/ 0; + // Reachable since the value returned by prop might come from legacy code. + super.prop ?? 0; } void if_null_assign_unreachable() { - super.prop ??= /*unreachable*/ 0; + // Reachable since the value returned by prop might come from legacy code. + super.prop ??= 0; } } @@ -130,11 +136,15 @@ void extended_property_if_null_assign_reachable(HasProperty x) { } void extended_property_if_null_unreachable(HasProperty x) { - x.extendedProp ?? /*unreachable*/ 0; + // Reachable since the value returned by extendedProp might come from legacy + // code. + x.extendedProp ?? 0; } void extended_property_if_null_assign_unreachable(HasProperty x) { - x.extendedProp ??= /*unreachable*/ 0; + // Reachable since the value returned by extendedProp might come from legacy + // code. + x.extendedProp ??= 0; } void null_aware_extended_property_if_null_reachable(HasProperty? x) { @@ -147,13 +157,16 @@ void null_aware_extended_property_if_null_assign_reachable( } void null_aware_extended_property_if_null_not_shortened(HasProperty? x) { - // If `??` participated in null-shortening, `0` would be unreachable. + // Reachable since the value returned by extendedProp might come from legacy + // code, and because `??` doesn't participate in null shortening. x?.extendedProp ?? 0; } void null_aware_extended_property_if_null_assign_unreachable( HasProperty? x) { - x?.extendedProp ??= /*unreachable*/ 0; + // Reachable since the value returned by extendedProp might come from legacy + // code. + x?.extendedProp ??= 0; } void explicit_extended_property_if_null_reachable(HasProperty x) { @@ -165,11 +178,15 @@ void explicit_extended_property_if_null_assign_reachable(HasProperty x) { } void explicit_extended_property_if_null_unreachable(HasProperty x) { - ExtensionProperty(x).extendedProp ?? /*unreachable*/ 0; + // Reachable since the value returned by extendedProp might come from legacy + // code. + ExtensionProperty(x).extendedProp ?? 0; } void explicit_extended_property_if_null_assign_unreachable(HasProperty x) { - ExtensionProperty(x).extendedProp ??= /*unreachable*/ 0; + // Reachable since the value returned by extendedProp might come from legacy + // code. + ExtensionProperty(x).extendedProp ??= 0; } void null_aware_explicit_extended_property_if_null_reachable( @@ -184,13 +201,16 @@ void null_aware_explicit_extended_property_if_null_assign_reachable( void null_aware_explicit_extended_property_if_null_not_shortened( HasProperty? x) { - // If `??` participated in null-shortening, `0` would be unreachable. + // Reachable since the value returned by extendedProp might come from legacy + // code, and because `??` doesn't participate in null shortening. ExtensionProperty(x)?.extendedProp ?? 0; } void null_aware_explicit_extended_property_if_null_assign_unreachable( HasProperty? x) { - ExtensionProperty(x)?.extendedProp ??= /*unreachable*/ 0; + // Reachable since the value returned by extendedProp might come from legacy + // code. + ExtensionProperty(x)?.extendedProp ??= 0; } class Indexable { @@ -204,7 +224,9 @@ void index_if_null_reachable(Indexable x) { } void index_if_null_unreachable(Indexable x) { - x[0] ?? /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + x[0] ?? 0; } void index_if_null_assign_reachable(Indexable x) { @@ -212,7 +234,9 @@ void index_if_null_assign_reachable(Indexable x) { } void index_if_null_assign_unreachable(Indexable x) { - x[0] ??= /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + x[0] ??= 0; } void null_aware_index_if_null_reachable(Indexable? x) { @@ -220,7 +244,8 @@ void null_aware_index_if_null_reachable(Indexable? x) { } void null_aware_index_if_null_unreachable(Indexable? x) { - // If `??` participated in null-shortening, `0` would be unreachable. + // Reachable since the value returned by operator[] might come from legacy + // code, and because `??` doesn't participate in null shortening. x?[0] ?? 0; } @@ -229,7 +254,9 @@ void null_aware_index_if_null_assign_reachable(Indexable? x) { } void null_aware_index_if_null_assign_unreachable(Indexable? x) { - x?[0] ??= /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + x?[0] ??= 0; } class SuperIntQuestionIndex extends Indexable { @@ -244,11 +271,15 @@ class SuperIntQuestionIndex extends Indexable { class SuperIntIndex extends Indexable { void if_null_unreachable() { - super[0] ?? /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + super[0] ?? 0; } void if_null_assign_unreachable() { - super[0] ??= /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + super[0] ??= 0; } } @@ -269,11 +300,15 @@ void extended_index_if_null_assign_reachable(HasProperty x) { } void extended_index_if_null_unreachable(HasProperty x) { - x[0] ?? /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + x[0] ?? 0; } void extended_index_if_null_assign_unreachable(HasProperty x) { - x[0] ??= /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + x[0] ??= 0; } void null_aware_extended_index_if_null_reachable(HasProperty? x) { @@ -285,12 +320,15 @@ void null_aware_extended_index_if_null_assign_reachable(HasProperty? x) { } void null_aware_extended_index_if_null_not_shortened(HasProperty? x) { - // If `??` participated in null-shortening, `0` would be unreachable. + // Reachable since the value returned by operator[] might come from legacy + // code, and because `??` doesn't participate in null shortening. x?[0] ?? 0; } void null_aware_extended_index_if_null_assign_unreachable(HasProperty? x) { - x?[0] ??= /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + x?[0] ??= 0; } void explicit_extended_index_if_null_reachable(HasProperty x) { @@ -302,11 +340,15 @@ void explicit_extended_index_if_null_assign_reachable(HasProperty x) { } void explicit_extended_index_if_null_unreachable(HasProperty x) { - ExtensionIndex(x)[0] ?? /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + ExtensionIndex(x)[0] ?? 0; } void explicit_extended_index_if_null_assign_unreachable(HasProperty x) { - ExtensionIndex(x)[0] ??= /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + ExtensionIndex(x)[0] ??= 0; } void null_aware_explicit_extended_index_if_null_reachable( @@ -321,11 +363,14 @@ void null_aware_explicit_extended_index_if_null_assign_reachable( void null_aware_explicit_extended_index_if_null_not_shortened( HasProperty? x) { - // If `??` participated in null-shortening, `0` would be unreachable. + // Reachable since the value returned by operator[] might come from legacy + // code, and because `??` doesn't participate in null shortening. ExtensionIndex(x)?[0] ?? 0; } void null_aware_explicit_extended_index_if_null_assign_unreachable( HasProperty? x) { - ExtensionIndex(x)?[0] ??= /*unreachable*/ 0; + // Reachable since the value returned by operator[] might come from legacy + // code. + ExtensionIndex(x)?[0] ??= 0; } diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/null_aware_access.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/null_aware_access.dart index a204bf8601a69..43c8e2e1ee2ce 100644 --- a/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/null_aware_access.dart +++ b/pkg/_fe_analyzer_shared/test/flow_analysis/reachability/data/null_aware_access.dart @@ -7,10 +7,10 @@ void index_reachable(List? f()) { 0; } -/*member: index_unreachable:doesNotComplete*/ void index_unreachable(List f()) { + // Reachable since the value returned by f() might come from legacy code f()?[throw '']; - /*stmt: unreachable*/ 0; + 0; } void cascaded_index_reachable(List? f()) { @@ -18,10 +18,10 @@ void cascaded_index_reachable(List? f()) { 0; } -/*member: cascaded_index_unreachable:doesNotComplete*/ void cascaded_index_unreachable(List f()) { + // Reachable since the value returned by f() might come from legacy code f()?..[throw '']; - /*stmt: unreachable*/ 0; + 0; } void method_invocation_reachable(int? f()) { @@ -29,10 +29,10 @@ void method_invocation_reachable(int? f()) { 0; } -/*member: method_invocation_unreachable:doesNotComplete*/ void method_invocation_unreachable(int f()) { + // Reachable since the value returned by f() might come from legacy code f()?.remainder(throw ''); - /*stmt: unreachable*/ 0; + 0; } void cascaded_method_invocation_reachable(int? f()) { @@ -40,10 +40,10 @@ void cascaded_method_invocation_reachable(int? f()) { 0; } -/*member: cascaded_method_invocation_unreachable:doesNotComplete*/ void cascaded_method_invocation_unreachable(int f()) { + // Reachable since the value returned by f() might come from legacy code f()?..remainder(throw ''); - /*stmt: unreachable*/ 0; + 0; } void property_get_reachable(int? f()) { @@ -51,10 +51,10 @@ void property_get_reachable(int? f()) { 0; } -/*member: property_get_unreachable:doesNotComplete*/ void property_get_unreachable(int f()) { + // Reachable since the value returned by f() might come from legacy code f()?.hashCode.remainder(throw ''); - /*stmt: unreachable*/ 0; + 0; } void cascaded_property_get_reachable(int? f()) { @@ -62,10 +62,10 @@ void cascaded_property_get_reachable(int? f()) { 0; } -/*member: cascaded_property_get_unreachable:doesNotComplete*/ void cascaded_property_get_unreachable(int f()) { + // Reachable since the value returned by f() might come from legacy code f()?..hashCode.remainder(throw ''); - /*stmt: unreachable*/ 0; + 0; } void property_get_invocation_reachable(List? f()) { @@ -76,13 +76,13 @@ void property_get_invocation_reachable(List? f()) { 0; } -/*member: property_get_invocation_unreachable:doesNotComplete*/ void property_get_invocation_unreachable(List f()) { + // Reachable since the value returned by f() might come from legacy code // We need a special test case for this because it parses like a method // invocation but the analyzer rewrites it as a property access followed by a // function expression invocation. f()?.first(throw ''); - /*stmt: unreachable*/ 0; + 0; } void cascaded_property_get_invocation_reachable( @@ -94,14 +94,14 @@ void cascaded_property_get_invocation_reachable( 0; } -/*member: cascaded_property_get_invocation_unreachable:doesNotComplete*/ void cascaded_property_get_invocation_unreachable( List f()) { + // Reachable since the value returned by f() might come from legacy code // We need a special test case for this because it parses like a method // invocation but the analyzer rewrites it as a property access followed by a // function expression invocation. f()?..first(throw ''); - /*stmt: unreachable*/ 0; + 0; } class C { @@ -113,10 +113,10 @@ void property_set_reachable(C? f()) { 0; } -/*member: property_set_unreachable:doesNotComplete*/ void property_set_unreachable(C f()) { + // Reachable since the value returned by f() might come from legacy code f()?.field = throw ''; - /*stmt: unreachable*/ 0; + 0; } void cascaded_property_set_reachable(C? f()) { @@ -124,8 +124,8 @@ void cascaded_property_set_reachable(C? f()) { 0; } -/*member: cascaded_property_set_unreachable:doesNotComplete*/ void cascaded_property_set_unreachable(C f()) { + // Reachable since the value returned by f() might come from legacy code f()?..field = throw ''; - /*stmt: unreachable*/ 0; + 0; } diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart index de0fa50c92f55..1a8f3e9878d1e 100644 --- a/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart +++ b/pkg/_fe_analyzer_shared/test/flow_analysis/type_promotion/data/if.dart @@ -87,7 +87,12 @@ isType_factor_declaredType(int? v) { if (v is int?) { v; } else { - /*Never*/ v; + // Type promotion never promotes a variable to type `Never`, since that + // could lead to code being deemed unreachable when in fact it is reachable + // due to mixed mode unsoundness. (In this particular case mixed mode + // unsoundness couldn't cause this "else" block to be reached, but flow + // analysis isn't smart enough to know that.) + v; } v; } @@ -96,7 +101,12 @@ isType_factor_supertype(int? v) { if (v is num?) { v; } else { - /*Never*/ v; + // Type promotion never promotes a variable to type `Never`, since that + // could lead to code being deemed unreachable when in fact it is reachable + // due to mixed mode unsoundness. (In this particular case mixed mode + // unsoundness couldn't cause this "else" block to be reached, but flow + // analysis isn't smart enough to know that.) + v; } v; } diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart index 28948d044398b..32b927a641fd3 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/remove_if_null_operator_test.dart @@ -5,7 +5,6 @@ import 'package:analysis_server/src/services/correction/fix.dart'; import 'package:analysis_server/src/services/linter/lint_names.dart'; import 'package:analyzer/src/dart/analysis/experiments.dart'; -import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -32,10 +31,7 @@ int f(int a, int b) => a ?? b; '''); await assertHasFix(''' int f(int a, int b) => a; -''', errorFilter: (e) { - // See https://github.com/dart-lang/sdk/issues/43263. - return e.errorCode != HintCode.DEAD_CODE; - }); +'''); } Future test_nestedChild() async { @@ -44,10 +40,7 @@ int f(int a, int b) => a ?? b * 2 + 1; '''); await assertHasFix(''' int f(int a, int b) => a; -''', errorFilter: (e) { - // See https://github.com/dart-lang/sdk/issues/43263. - return e.errorCode != HintCode.DEAD_CODE; - }); +'''); } } diff --git a/pkg/analyzer/test/src/diagnostics/dead_null_aware_expression_test.dart b/pkg/analyzer/test/src/diagnostics/dead_null_aware_expression_test.dart index e60e478610054..c1e4746fe2a40 100644 --- a/pkg/analyzer/test/src/diagnostics/dead_null_aware_expression_test.dart +++ b/pkg/analyzer/test/src/diagnostics/dead_null_aware_expression_test.dart @@ -22,16 +22,13 @@ class DeadNullAwareExpressionTest extends PubPackageResolutionTest var x = 0; '''); - await assertErrorsInCode(''' + await assertNoErrorsInCode(''' import 'a.dart'; f() { x ??= 0; } -''', [ - // See https://github.com/dart-lang/sdk/issues/43263. - error(HintCode.DEAD_CODE, 32, 2), - ]); +'''); } test_assignCompound_map() async { @@ -54,8 +51,6 @@ f(int x) { } ''', [ error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 19, 1), - // See https://github.com/dart-lang/sdk/issues/43263. - error(HintCode.DEAD_CODE, 19, 2), ]); } @@ -73,16 +68,13 @@ f(int? x) { var x = 0; '''); - await assertErrorsInCode(''' + await assertNoErrorsInCode(''' import 'a.dart'; f() { x ?? 0; } -''', [ - // See https://github.com/dart-lang/sdk/issues/43263. - error(HintCode.DEAD_CODE, 31, 2), - ]); +'''); } test_binary_nonNullable() async { @@ -92,8 +84,6 @@ f(int x) { } ''', [ error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 18, 1), - // See https://github.com/dart-lang/sdk/issues/43263. - error(HintCode.DEAD_CODE, 18, 2), ]); } diff --git a/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart index df5882be22f49..16a01ee4b9f79 100644 --- a/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart +++ b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart @@ -84,8 +84,6 @@ void f() { } ''', [ _notAssignedError(22, 1), - // See https://github.com/dart-lang/sdk/issues/43263. - error(HintCode.DEAD_CODE, 28, 2), error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 28, 1), ]); } @@ -98,8 +96,6 @@ void f() { } ''', [ _notAssignedError(22, 1), - // See https://github.com/dart-lang/sdk/issues/43263. - error(HintCode.DEAD_CODE, 28, 2), error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 28, 1), _notAssignedError(28, 1), ]); @@ -124,8 +120,6 @@ void f() { } ''', [ error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 33, 1), - // See https://github.com/dart-lang/sdk/issues/43263. - error(HintCode.DEAD_CODE, 33, 7), ]); } @@ -138,8 +132,6 @@ void f(int a) { } ''', [ error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 32, 7), - // See https://github.com/dart-lang/sdk/issues/43263. - error(HintCode.DEAD_CODE, 32, 13), _notAssignedError(43, 1), ]); } diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart index fcf64daa07e60..6e6b8e67d66bd 100644 --- a/pkg/expect/lib/expect.dart +++ b/pkg/expect/lib/expect.dart @@ -612,6 +612,12 @@ class Expect { Expect.throws(f, (error) => error is NoSuchMethodError, reason); } + static void throwsReachabilityError(void f(), + [String reason = "ReachabilityError"]) { + Expect.throws( + f, (error) => error.toString().startsWith('ReachabilityError'), reason); + } + /// Checks that [f] throws an appropriate error on a null argument. /// /// In strong mode, this is expected to be a [TypeError] when casting the diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt index 77a6578a62454..1521039b3d2fd 100644 --- a/pkg/front_end/test/spell_checking_list_common.txt +++ b/pkg/front_end/test/spell_checking_list_common.txt @@ -2285,6 +2285,7 @@ promote promoted promoter promotes +promoting promotion promotions propagate @@ -3160,6 +3161,7 @@ unsigned unsized unskip unsorted +unsoundness unspecified unsplit unstable diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h index 523d82fa1e3c0..bd837eba8a219 100644 --- a/runtime/vm/compiler/recognized_methods_list.h +++ b/runtime/vm/compiler/recognized_methods_list.h @@ -81,7 +81,7 @@ namespace dart { V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x143ed675) \ V(::, copyRangeFromUint8ListToOneByteString, \ CopyRangeFromUint8ListToOneByteString, 0x89d6a60a) \ - V(_StringBase, _interpolate, StringBaseInterpolate, 0xbf682f1c) \ + V(_StringBase, _interpolate, StringBaseInterpolate, 0xd5a58efc) \ V(_IntegerImplementation, toDouble, IntegerToDouble, 0x5f8db5f5) \ V(_Double, _add, DoubleAdd, 0x4326962a) \ V(_Double, _sub, DoubleSub, 0x81077f31) \ diff --git a/tests/language/nnbd/boolean_conversion/boolean_conversion_weak_test.dart b/tests/language/nnbd/boolean_conversion/boolean_conversion_weak_test.dart index c8b0167029f88..e72869141d28e 100644 --- a/tests/language/nnbd/boolean_conversion/boolean_conversion_weak_test.dart +++ b/tests/language/nnbd/boolean_conversion/boolean_conversion_weak_test.dart @@ -13,7 +13,7 @@ import 'package:expect/expect.dart'; import 'boolean_conversion_lib1.dart'; void main() { - check(neverAsBoolean, null, Expect.throwsAssertionError); + check(neverAsBoolean, null, Expect.throwsReachabilityError); check(booleanAsBoolean, null, Expect.throwsAssertionError); check(booleanAsBoolean, true, expectOk); diff --git a/tests/language/nnbd/never/never_null_assignability_lib1.dart b/tests/language/nnbd/never/never_null_assignability_lib1.dart index b006476bb4edd..ff19ad55cce16 100644 --- a/tests/language/nnbd/never/never_null_assignability_lib1.dart +++ b/tests/language/nnbd/never/never_null_assignability_lib1.dart @@ -25,9 +25,9 @@ void takesNull(Null n) { } void takesNever(Never n) { - // In weak mode, we may get null. Throw AssertionError so that this - // can be distinguished from a dynamic call failure. - if (n != null) throw AssertionError("Not null"); + // In weak mode, we may get null. However, we can't observe it (because + // evaluating an expression of type `Never` causes an exception to be + // thrown). So do nothing. } void applyTakesNull(void Function(Null) fn, dynamic arg) { @@ -36,8 +36,9 @@ void applyTakesNull(void Function(Null) fn, dynamic arg) { } void applyTakesNever(void Function(Never) fn, dynamic arg) { - // Make the cast explicit for clarity. - fn(arg as Never); + // We can't make the cast explicit, because `arg as Never` has static type + // `Never`, which would cause an exception to be thrown. + fn(arg); } void applyTakesNullDynamically(void Function(Null) fn, dynamic arg) { From 316128d6cd76a0748b2f37093a4f5a97f9e73222 Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Fri, 25 Sep 2020 09:21:44 +0000 Subject: [PATCH 3/4] [kernel] Remove unused dart:async import Since Dart 2.1, Future and Stream have been exported from dart:core Change-Id: Ib452692ea2ce02bcc84fa50ffb054410114de56f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164100 Auto-Submit: Mike Fairhurst Commit-Queue: Aske Simon Christensen Reviewed-by: Aske Simon Christensen --- pkg/kernel/lib/kernel.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/kernel/lib/kernel.dart b/pkg/kernel/lib/kernel.dart index d93c68834a33a..8504ef3eb4a31 100644 --- a/pkg/kernel/lib/kernel.dart +++ b/pkg/kernel/lib/kernel.dart @@ -16,7 +16,6 @@ library kernel; import 'ast.dart'; import 'binary/ast_to_binary.dart'; import 'binary/ast_from_binary.dart'; -import 'dart:async'; import 'dart:io'; import 'text/ast_to_text.dart'; From 02923c6f83a03ca729e5418e7c0e3369912ed5cd Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 25 Sep 2020 10:37:00 +0000 Subject: [PATCH 4/4] Make `Future.wait` not return a `const []` when given no futures. Fixes #43445. Bug: https://github.com/dart-lang/sdk/issues/43445 Change-Id: I70f722f6bee1d4cfe4d53a5f37bc29f0751edd78 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164162 Reviewed-by: Nate Bosch Commit-Queue: Lasse R.H. Nielsen --- runtime/vm/compiler/recognized_methods_list.h | 2 +- sdk/lib/async/future.dart | 2 +- tests/lib/async/future_test.dart | 11 +++++++++++ tests/lib_2/async/future_test.dart | 11 +++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h index bd837eba8a219..7044628843577 100644 --- a/runtime/vm/compiler/recognized_methods_list.h +++ b/runtime/vm/compiler/recognized_methods_list.h @@ -192,7 +192,7 @@ namespace dart { V(::, reachabilityFence, ReachabilityFence, 0xad39d0a6) \ V(_Utf8Decoder, _scan, Utf8DecoderScan, 0x78f44c3c) \ V(_Future, timeout, FutureTimeout, 0x010f8ad4) \ - V(Future, wait, FutureWait, 0x486414a9) \ + V(Future, wait, FutureWait, 0x9a812df7) \ // List of intrinsics: // (class-name, function-name, intrinsification method, fingerprint). diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart index bb6ed77720081..0e1d703d3a7ce 100644 --- a/sdk/lib/async/future.dart +++ b/sdk/lib/async/future.dart @@ -433,7 +433,7 @@ abstract class Future { remaining++; } if (remaining == 0) { - return new Future>.value(const []); + return _future.._completeWithValue([]); } values = new List.filled(remaining, null); } catch (e, st) { diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart index b084c860164bd..f2d971039c49e 100644 --- a/tests/lib/async/future_test.dart +++ b/tests/lib/async/future_test.dart @@ -143,6 +143,17 @@ void testCompleteManySuccessHandlers() { Expect.equals(3, after2); asyncEnd(); }); + + // Regression test for fix to issue: + // https://github.com/dart-lang/sdk/issues/43445 + asyncStart(); + Future.wait(>[]).then((list) { + Expect.equals(0, list.length); + Expect.type>(list); + Expect.notType>(list); + Expect.notType>(list); + asyncEnd(); + }); } // Tests for [catchError] diff --git a/tests/lib_2/async/future_test.dart b/tests/lib_2/async/future_test.dart index 3a4f09d7da66f..6c227cf22d31f 100644 --- a/tests/lib_2/async/future_test.dart +++ b/tests/lib_2/async/future_test.dart @@ -140,6 +140,17 @@ void testCompleteManySuccessHandlers() { Expect.equals(3, after2); asyncEnd(); }); + + // Regression test for fix to issue: + // https://github.com/dart-lang/sdk/issues/43445 + asyncStart(); + Future.wait(>[]).then((list) { + Expect.equals(0, list.length); + Expect.type>(list); + Expect.notType>(list); + Expect.notType>(list); + asyncEnd(); + }); } // Tests for [catchError]