Version 2.13.0-191.0.dev
Merge commit '76e41bc4c5d0edba398956c1438770128735e9c6' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index 7aebe35..6e79f8f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -702,6 +702,27 @@
return issues;
}
+/// Finds raw non-simple types in bounds of type variables in [typeBuilder].
+///
+/// Returns flattened list of triplets. The first element of the triplet is the
+/// [TypeDeclarationBuilder] for the type variable from [variables] that has raw
+/// generic types with inbound references in its bound. The second element of
+/// the triplet is the error message. The third element is the context.
+List<Object> getInboundReferenceIssuesInType(TypeBuilder typeBuilder) {
+ List<FunctionTypeBuilder> genericFunctionTypeBuilders =
+ <FunctionTypeBuilder>[];
+ findUnaliasedGenericFunctionTypes(typeBuilder,
+ result: genericFunctionTypeBuilders);
+ List<Object> issues = <Object>[];
+ for (FunctionTypeBuilder genericFunctionTypeBuilder
+ in genericFunctionTypeBuilders) {
+ List<TypeVariableBuilder> typeVariables =
+ genericFunctionTypeBuilder.typeVariables;
+ issues.addAll(getInboundReferenceIssues(typeVariables));
+ }
+ return issues;
+}
+
/// Finds raw type paths starting from those in [start] and ending with [end].
///
/// Returns list of found paths. Each path is represented as a list of
@@ -964,8 +985,38 @@
}
}
+/// Finds generic function type sub-terms in [type].
+void findUnaliasedGenericFunctionTypes(TypeBuilder type,
+ {List<FunctionTypeBuilder> result}) {
+ assert(result != null);
+ if (type is FunctionTypeBuilder) {
+ if (type.typeVariables != null && type.typeVariables.length > 0) {
+ result.add(type);
+
+ for (TypeVariableBuilder typeVariable in type.typeVariables) {
+ findUnaliasedGenericFunctionTypes(typeVariable.bound, result: result);
+ findUnaliasedGenericFunctionTypes(typeVariable.defaultType,
+ result: result);
+ }
+ }
+ findUnaliasedGenericFunctionTypes(type.returnType, result: result);
+ if (type.formals != null) {
+ for (FormalParameterBuilder formal in type.formals) {
+ findUnaliasedGenericFunctionTypes(formal.type, result: result);
+ }
+ }
+ } else if (type is NamedTypeBuilder) {
+ if (type.arguments != null) {
+ for (TypeBuilder argument in type.arguments) {
+ findUnaliasedGenericFunctionTypes(argument, result: result);
+ }
+ }
+ }
+}
+
+/// Finds generic function type sub-terms in [type] including the aliased ones.
void findGenericFunctionTypes(TypeBuilder type, {List<TypeBuilder> result}) {
- result ??= <TypeBuilder>[];
+ assert(result != null);
if (type is FunctionTypeBuilder) {
if (type.typeVariables != null && type.typeVariables.length > 0) {
result.add(type);
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index eb7744b..097bde3 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -96,6 +96,7 @@
calculateBounds,
computeTypeVariableBuilderVariance,
findGenericFunctionTypes,
+ getInboundReferenceIssuesInType,
getNonSimplicityIssuesForDeclaration,
getNonSimplicityIssuesForTypeVariables,
pendingVariance;
@@ -3105,6 +3106,7 @@
inErrorRecovery: issues.isNotEmpty);
declaration.constructors.forEach((String name, Builder member) {
+ List<FormalParameterBuilder> formals;
if (member is ProcedureBuilder) {
assert(member.isFactory,
"Unexpected constructor member (${member.runtimeType}).");
@@ -3112,9 +3114,18 @@
// Type variables are inherited from the class so if the class
// has issues, so does the factory constructors.
inErrorRecovery: issues.isNotEmpty);
+ formals = member.formals;
} else {
assert(member is ConstructorBuilder,
"Unexpected constructor member (${member.runtimeType}).");
+ formals = (member as ConstructorBuilder).formals;
+ }
+ if (formals != null && formals.isNotEmpty) {
+ for (FormalParameterBuilder formal in formals) {
+ List<Object> issues =
+ getInboundReferenceIssuesInType(formal.type);
+ reportIssues(issues);
+ }
}
});
}
@@ -3122,23 +3133,46 @@
if (member is ProcedureBuilder) {
List<Object> issues =
getNonSimplicityIssuesForTypeVariables(member.typeVariables);
+ if (member.formals != null && member.formals.isNotEmpty) {
+ for (FormalParameterBuilder formal in member.formals) {
+ issues.addAll(getInboundReferenceIssuesInType(formal.type));
+ }
+ }
+ if (member.returnType != null) {
+ issues.addAll(getInboundReferenceIssuesInType(member.returnType));
+ }
reportIssues(issues);
count += computeDefaultTypesForVariables(member.typeVariables,
inErrorRecovery: issues.isNotEmpty);
} else {
assert(member is FieldBuilder,
"Unexpected class member $member (${member.runtimeType}).");
+ TypeBuilder fieldType = (member as FieldBuilder).type;
+ if (fieldType != null) {
+ List<Object> issues = getInboundReferenceIssuesInType(fieldType);
+ reportIssues(issues);
+ }
}
});
} else if (declaration is TypeAliasBuilder) {
List<Object> issues = getNonSimplicityIssuesForDeclaration(declaration,
performErrorRecovery: true);
+ issues.addAll(getInboundReferenceIssuesInType(declaration.type));
reportIssues(issues);
count += computeDefaultTypesForVariables(declaration.typeVariables,
inErrorRecovery: issues.isNotEmpty);
} else if (declaration is FunctionBuilder) {
List<Object> issues =
getNonSimplicityIssuesForTypeVariables(declaration.typeVariables);
+ if (declaration.formals != null && declaration.formals.isNotEmpty) {
+ for (FormalParameterBuilder formal in declaration.formals) {
+ issues.addAll(getInboundReferenceIssuesInType(formal.type));
+ }
+ }
+ if (declaration.returnType != null) {
+ issues
+ .addAll(getInboundReferenceIssuesInType(declaration.returnType));
+ }
reportIssues(issues);
count += computeDefaultTypesForVariables(declaration.typeVariables,
inErrorRecovery: issues.isNotEmpty);
@@ -3155,6 +3189,14 @@
if (member is ProcedureBuilder) {
List<Object> issues =
getNonSimplicityIssuesForTypeVariables(member.typeVariables);
+ if (member.formals != null && member.formals.isNotEmpty) {
+ for (FormalParameterBuilder formal in member.formals) {
+ issues.addAll(getInboundReferenceIssuesInType(formal.type));
+ }
+ }
+ if (member.returnType != null) {
+ issues.addAll(getInboundReferenceIssuesInType(member.returnType));
+ }
reportIssues(issues);
count += computeDefaultTypesForVariables(member.typeVariables,
inErrorRecovery: issues.isNotEmpty);
@@ -3163,16 +3205,34 @@
"Unexpected extension member $member (${member.runtimeType}).");
}
});
+ } else if (declaration is FieldBuilder) {
+ if (declaration.type != null) {
+ List<Object> issues =
+ getInboundReferenceIssuesInType(declaration.type);
+ reportIssues(issues);
+ }
} else {
assert(
- declaration is FieldBuilder ||
- declaration is PrefixBuilder ||
+ declaration is PrefixBuilder ||
declaration is DynamicTypeDeclarationBuilder ||
declaration is NeverTypeDeclarationBuilder,
"Unexpected top level member $declaration "
"(${declaration.runtimeType}).");
}
}
+ for (Builder declaration in libraryDeclaration.setters.values) {
+ assert(
+ declaration is ProcedureBuilder,
+ "Expected setter to be a ProcedureBuilder, "
+ "but got '${declaration.runtimeType}'");
+ if (declaration is ProcedureBuilder &&
+ declaration.formals != null &&
+ declaration.formals.isNotEmpty) {
+ for (FormalParameterBuilder formal in declaration.formals) {
+ reportIssues(getInboundReferenceIssuesInType(formal.type));
+ }
+ }
+ }
return count;
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 1d8e254..3057286 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -246,7 +246,8 @@
library.checkBoundsInTypeParameters(
typeEnvironment, typedef.typeParameters, fileUri);
library.checkBoundsInType(
- typedef.type, typeEnvironment, fileUri, type?.charOffset ?? charOffset);
+ typedef.type, typeEnvironment, fileUri, type?.charOffset ?? charOffset,
+ allowSuperBounded: false);
}
@override
diff --git a/pkg/front_end/testcases/general/issue42435.dart b/pkg/front_end/testcases/general/issue42435.dart
new file mode 100644
index 0000000..f49f068
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2021, 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.
+
+class A<X extends A<X>> {}
+
+typedef F = Function<Y extends A>();
+
+class B {
+ B(Function<Z extends A>() a);
+ factory B.foo(Function<Z extends A>() a) => new B(a);
+ foo2(Function<Z extends A>() a) {}
+ Function<Z extends A>() foo3() => throw 42;
+ Function<Z extends A>() get foo4 => throw 42;
+ void set foo5(Function<Z extends A>() a) {}
+ Function<Z extends A>() foo6 = (() => throw 42)();
+}
+
+bar2(Function<Z extends A>() a) {}
+Function<Z extends A>() bar3() => throw 42;
+Function<Z extends A>() get bar4 => throw 42;
+void set bar5(Function<Z extends A>() a) {}
+Function<Z extends A>() bar6 = (() => throw 42)();
+
+extension E on int {
+ baz2(Function<Z extends A>() a) {}
+ Function<Z extends A>() baz3() => throw 42;
+ Function<Z extends A>() get baz4 => throw 42;
+ void set baz5(Function<Z extends A>() a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue42435.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue42435.dart.textual_outline.expect
new file mode 100644
index 0000000..2e81748
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.textual_outline.expect
@@ -0,0 +1,28 @@
+class A<X extends A<X>> {}
+
+typedef F = Function<Y extends A>();
+
+class B {
+ B(Function<Z extends A>() a);
+ factory B.foo(Function<Z extends A>() a) => new B(a);
+ foo2(Function<Z extends A>() a) {}
+ Function<Z extends A>() foo3() => throw 42;
+ Function<Z extends A>() get foo4 => throw 42;
+ void set foo5(Function<Z extends A>() a) {}
+ Function<Z extends A>() foo6 = (() => throw 42)();
+}
+
+bar2(Function<Z extends A>() a) {}
+Function<Z extends A>() bar3() => throw 42;
+Function<Z extends A>() get bar4 => throw 42;
+void set bar5(Function<Z extends A>() a) {}
+Function<Z extends A>() bar6 = (() => throw 42)();
+
+extension E on int {
+ baz2(Function<Z extends A>() a) {}
+ Function<Z extends A>() baz3() => throw 42;
+ Function<Z extends A>() get baz4 => throw 42;
+ void set baz5(Function<Z extends A>() a) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue42435.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue42435.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..c61aa8e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.textual_outline_modelled.expect
@@ -0,0 +1,27 @@
+Function<Z extends A>() bar3() => throw 42;
+Function<Z extends A>() bar6 = (() => throw 42)();
+Function<Z extends A>() get bar4 => throw 42;
+bar2(Function<Z extends A>() a) {}
+
+class A<X extends A<X>> {}
+
+class B {
+ B(Function<Z extends A>() a);
+ Function<Z extends A>() foo3() => throw 42;
+ Function<Z extends A>() foo6 = (() => throw 42)();
+ Function<Z extends A>() get foo4 => throw 42;
+ factory B.foo(Function<Z extends A>() a) => new B(a);
+ foo2(Function<Z extends A>() a) {}
+ void set foo5(Function<Z extends A>() a) {}
+}
+
+extension E on int {
+ Function<Z extends A>() baz3() => throw 42;
+ Function<Z extends A>() get baz4 => throw 42;
+ baz2(Function<Z extends A>() a) {}
+ void set baz5(Function<Z extends A>() a) {}
+}
+
+main() {}
+typedef F = Function<Y extends A>();
+void set bar5(Function<Z extends A>() a) {}
diff --git a/pkg/front_end/testcases/general/issue42435.dart.weak.expect b/pkg/front_end/testcases/general/issue42435.dart.weak.expect
new file mode 100644
index 0000000..4c809d0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.weak.expect
@@ -0,0 +1,190 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435.dart:7:22: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef F = Function<Y extends A>();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:10:14: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// B(Function<Z extends A>() a);
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:11:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// factory B.foo(Function<Z extends A>() a) => new B(a);
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:12:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// foo2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:13:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() foo3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:14:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get foo4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:16:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() foo6 = (() => throw 42)();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:15:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set foo5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:19:15: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// bar2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:20:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:21:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get bar4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:23:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar6 = (() => throw 42)();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:26:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// baz2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:27:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() baz3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:28:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get baz4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:29:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set baz5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:22:24: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set bar5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+typedef F = <Y extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic foo6 = let final Never #t1 = (() → Never => throw 42).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ constructor •(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+ : super core::Object::•()
+ ;
+ static factory foo(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+ return new self::B::•(a);
+ method foo2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+ method foo3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+ get foo4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+ set foo5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+}
+extension E on core::int {
+ method baz2 = self::E|baz2;
+ tearoff baz2 = self::E|get#baz2;
+ method baz3 = self::E|baz3;
+ tearoff baz3 = self::E|get#baz3;
+ get baz4 = self::E|get#baz4;
+ set baz5 = self::E|set#baz5;
+}
+static field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic bar6 = let final Never #t2 = (() → Never => throw 42).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+static method bar2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+static method bar3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+static get bar4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+static set bar5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+static method E|baz2(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+static method E|get#baz2(lowered final core::int #this) → (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic) → dynamic
+ return (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic => self::E|baz2(#this, a);
+static method E|baz3(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+static method E|get#baz3(lowered final core::int #this) → () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic => self::E|baz3(#this);
+static method E|get#baz4(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+static method E|set#baz5(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue42435.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue42435.dart.weak.outline.expect
new file mode 100644
index 0000000..90c287f
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.weak.outline.expect
@@ -0,0 +1,194 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435.dart:7:22: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef F = Function<Y extends A>();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:10:14: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// B(Function<Z extends A>() a);
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:11:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// factory B.foo(Function<Z extends A>() a) => new B(a);
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:12:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// foo2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:13:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() foo3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:14:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get foo4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:16:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() foo6 = (() => throw 42)();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:15:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set foo5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:19:15: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// bar2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:20:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:21:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get bar4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:23:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar6 = (() => throw 42)();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:26:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// baz2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:27:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() baz3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:28:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get baz4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:29:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set baz5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:22:24: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set bar5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F = <Y extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+}
+class B extends core::Object {
+ field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic foo6;
+ constructor •(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+ ;
+ static factory foo(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+ ;
+ method foo2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic
+ ;
+ method foo3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ ;
+ get foo4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ ;
+ set foo5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void
+ ;
+}
+extension E on core::int {
+ method baz2 = self::E|baz2;
+ tearoff baz2 = self::E|get#baz2;
+ method baz3 = self::E|baz3;
+ tearoff baz3 = self::E|get#baz3;
+ get baz4 = self::E|get#baz4;
+ set baz5 = self::E|set#baz5;
+}
+static field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic bar6;
+static method bar2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic
+ ;
+static method bar3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ ;
+static get bar4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ ;
+static set bar5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void
+ ;
+static method E|baz2(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic
+ ;
+static method E|get#baz2(lowered final core::int #this) → (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic) → dynamic
+ return (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic => self::E|baz2(#this, a);
+static method E|baz3(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ ;
+static method E|get#baz3(lowered final core::int #this) → () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic => self::E|baz3(#this);
+static method E|get#baz4(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ ;
+static method E|set#baz5(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/issue42435.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue42435.dart.weak.transformed.expect
new file mode 100644
index 0000000..4c809d0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435.dart.weak.transformed.expect
@@ -0,0 +1,190 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435.dart:7:22: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef F = Function<Y extends A>();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:10:14: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// B(Function<Z extends A>() a);
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:11:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// factory B.foo(Function<Z extends A>() a) => new B(a);
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:12:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// foo2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:13:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() foo3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:14:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get foo4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:16:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() foo6 = (() => throw 42)();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:15:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set foo5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:19:15: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// bar2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:20:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:21:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get bar4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:23:10: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() bar6 = (() => throw 42)();
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:26:17: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// baz2(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:27:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() baz3() => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:28:12: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// Function<Z extends A>() get baz4 => throw 42;
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:29:26: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set baz5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+// pkg/front_end/testcases/general/issue42435.dart:22:24: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// void set bar5(Function<Z extends A>() a) {}
+// ^
+// pkg/front_end/testcases/general/issue42435.dart:5:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+typedef F = <Y extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic foo6 = let final Never #t1 = (() → Never => throw 42).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ constructor •(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+ : super core::Object::•()
+ ;
+ static factory foo(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → self::B
+ return new self::B::•(a);
+ method foo2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+ method foo3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+ get foo4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+ set foo5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+}
+extension E on core::int {
+ method baz2 = self::E|baz2;
+ tearoff baz2 = self::E|get#baz2;
+ method baz3 = self::E|baz3;
+ tearoff baz3 = self::E|get#baz3;
+ get baz4 = self::E|get#baz4;
+ set baz5 = self::E|set#baz5;
+}
+static field <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic bar6 = let final Never #t2 = (() → Never => throw 42).call() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+static method bar2(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+static method bar3() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+static get bar4() → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+static set bar5(<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+static method E|baz2(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic {}
+static method E|get#baz2(lowered final core::int #this) → (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic) → dynamic
+ return (<Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → dynamic => self::E|baz2(#this, a);
+static method E|baz3(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+static method E|get#baz3(lowered final core::int #this) → () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return () → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic => self::E|baz3(#this);
+static method E|get#baz4(lowered final core::int #this) → <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic
+ return throw 42;
+static method E|set#baz5(lowered final core::int #this, <Z extends self::A<self::A<dynamic>> = dynamic>() → dynamic a) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart b/pkg/front_end/testcases/general/issue42435_2.dart
new file mode 100644
index 0000000..cc13212
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart
@@ -0,0 +1,5 @@
+class A<X extends A<X>> {}
+
+typedef AAlias = Function<X extends A>();
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline.expect
new file mode 100644
index 0000000..3230d3d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+class A<X extends A<X>> {}
+
+typedef AAlias = Function<X extends A>();
+main() {}
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ce0d405
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+class A<X extends A<X>> {}
+
+main() {}
+typedef AAlias = Function<X extends A>();
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.weak.expect b/pkg/front_end/testcases/general/issue42435_2.dart.weak.expect
new file mode 100644
index 0000000..aa9fc93
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.weak.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435_2.dart:3:27: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef AAlias = Function<X extends A>();
+// ^
+// pkg/front_end/testcases/general/issue42435_2.dart:1:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias = <X extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue42435_2.dart.weak.outline.expect
new file mode 100644
index 0000000..b808ee98
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.weak.outline.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435_2.dart:3:27: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef AAlias = Function<X extends A>();
+// ^
+// pkg/front_end/testcases/general/issue42435_2.dart:1:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias = <X extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/issue42435_2.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue42435_2.dart.weak.transformed.expect
new file mode 100644
index 0000000..aa9fc93
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue42435_2.dart.weak.transformed.expect
@@ -0,0 +1,22 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue42435_2.dart:3:27: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'A' here.
+// typedef AAlias = Function<X extends A>();
+// ^
+// pkg/front_end/testcases/general/issue42435_2.dart:1:9: Context: Bound of this variable references variable 'X' from the same declaration.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias = <X extends self::A<self::A<dynamic>> = dynamic>() → dynamic;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart
new file mode 100644
index 0000000..1a3a438
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2021, 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.
+
+class A<X extends A<X>> {}
+
+typedef AAlias<X> = A;
+
+void main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect
new file mode 100644
index 0000000..e43a323
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect
new file mode 100644
index 0000000..e43a323
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline.expect
new file mode 100644
index 0000000..35e4a77
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+class A<X extends A<X>> {}
+typedef AAlias<X> = A;
+void main() {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect
new file mode 100644
index 0000000..e43a323
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect
new file mode 100644
index 0000000..19040d1
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+}
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect
new file mode 100644
index 0000000..e43a323
--- /dev/null
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:7:21: Error: Inferred type argument 'A<dynamic>' doesn't conform to the bound 'A<X>' of the type variable 'X' on 'A'.
+// - 'A' is from 'pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+// typedef AAlias<X> = A;
+// ^
+// pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends A<X>> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef AAlias<unrelated X extends core::Object? = dynamic> = self::A<self::A<dynamic>>;
+class A<X extends self::A<self::A::X> = self::A<dynamic>> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 4486b80..90a00d2 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -135,6 +135,7 @@
nonfunction_type_aliases/issue42446: FormatterCrash
nonfunction_type_aliases/issue45051: FormatterCrash
nonfunction_type_aliases/issue45464: FormatterCrash
+nonfunction_type_aliases/issue45491: FormatterCrash
nonfunction_type_aliases/issue45519: FormatterCrash
nonfunction_type_aliases/issue45519_2: FormatterCrash
nonfunction_type_aliases/nullable_supertypes: FormatterCrash
diff --git a/runtime/vm/compiler/backend/evaluator.cc b/runtime/vm/compiler/backend/evaluator.cc
index 11b007a..fd8c0e8 100644
--- a/runtime/vm/compiler/backend/evaluator.cc
+++ b/runtime/vm/compiler/backend/evaluator.cc
@@ -71,9 +71,8 @@
int64_t Evaluator::TruncateTo(int64_t v, Representation r) {
switch (r) {
case kTagged: {
- // Smi occupies word minus kSmiTagShift bits.
const intptr_t kTruncateBits =
- (kBitsPerInt64 - kBitsPerWord) + kSmiTagShift;
+ kBitsPerInt64 - (compiler::target::kSmiBits + 1 /*sign bit*/);
return Utils::ShiftLeftWithTruncation(v, kTruncateBits) >> kTruncateBits;
}
case kUnboxedInt32:
diff --git a/tests/language/vm/regress_45525_test.dart b/tests/language/vm/regress_45525_test.dart
new file mode 100644
index 0000000..2becc03
--- /dev/null
+++ b/tests/language/vm/regress_45525_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+dynamic a() {
+ return 23;
+}
+
+dynamic b() {
+ return 26;
+}
+
+@pragma("vm:never-inline")
+dynamic foo() {
+ // BinarySmiOp(<<) marked truncating
+ return (a() << b()) & 0xFFFFFFF;
+}
+
+main() {
+ for (var i = 0; i < 20; i++) {
+ Expect.equals(201326592, foo());
+ }
+}
diff --git a/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart b/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart
new file mode 100644
index 0000000..cfde735
--- /dev/null
+++ b/tests/language/why_not_promoted/argument_type_not_assignable_nullability_error_test.dart
@@ -0,0 +1,593 @@
+// Copyright (c) 2021, 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.
+
+// This test contains a test case for each condition that can lead to the front
+// end's `ArgumentTypeNotAssignableNullability` error, for which we wish to
+// report "why not promoted" context information.
+
+class C1 {
+ int? bad;
+ // ^
+ // [context 1] 'bad' refers to a property so it couldn't be promoted.
+ f(int i) {}
+}
+
+required_unnamed(C1 c) {
+ if (c.bad == null) return;
+ c.f(c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 1] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C2 {
+ int? bad;
+ // ^
+ // [context 2] 'bad' refers to a property so it couldn't be promoted.
+ f([int i = 0]) {}
+}
+
+optional_unnamed(C2 c) {
+ if (c.bad == null) return;
+ c.f(c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 2] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C3 {
+ int? bad;
+ // ^
+ // [context 3] 'bad' refers to a property so it couldn't be promoted.
+ f({required int i}) {}
+}
+
+required_named(C3 c) {
+ if (c.bad == null) return;
+ c.f(i: c.bad);
+ // ^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 3] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C4 {
+ int? bad;
+ // ^
+ // [context 4] 'bad' refers to a property so it couldn't be promoted.
+ f({int i = 0}) {}
+}
+
+optional_named(C4 c) {
+ if (c.bad == null) return;
+ c.f(i: c.bad);
+ // ^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 4] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C5 {
+ List<int>? bad;
+ // ^
+ // [context 5] 'bad' refers to a property so it couldn't be promoted.
+ f<T>(List<T> x) {}
+}
+
+type_inferred(C5 c) {
+ if (c.bad == null) return;
+ c.f(c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 5] The argument type 'List<int>?' can't be assigned to the parameter type 'List<int>' because 'List<int>?' is nullable and 'List<int>' isn't.
+}
+
+class C6 {
+ int? bad;
+ // ^
+ // [context 6] 'bad' refers to a property so it couldn't be promoted.
+ C6(int i);
+}
+
+C6? constructor_with_implicit_new(C6 c) {
+ if (c.bad == null) return null;
+ return C6(c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 6] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C7 {
+ int? bad;
+ // ^
+ // [context 7] 'bad' refers to a property so it couldn't be promoted.
+ C7(int i);
+}
+
+C7? constructor_with_explicit_new(C7 c) {
+ if (c.bad == null) return null;
+ return new C7(c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 7] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C8 {
+ int? bad;
+ // ^
+ // [context 8] 'bad' refers to a property so it couldn't be promoted.
+}
+
+userDefinableBinaryOpRhs(C8 c) {
+ if (c.bad == null) return;
+ 1 + c.bad;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 8] A value of type 'int?' can't be assigned to a variable of type 'num' because 'int?' is nullable and 'num' isn't.
+}
+
+class C9 {
+ int? bad;
+ f(int i) {}
+}
+
+questionQuestionRhs(C9 c, int? i) {
+ // Note: "why not supported" functionality is currently not supported for the
+ // RHS of `??` because it requires more clever reasoning than we currently do:
+ // we would have to understand that the reason `i ?? c.bad` has a type of
+ // `int?` rather than `int` is because `c.bad` was not promoted. We currently
+ // only support detecting non-promotion when the expression that had the wrong
+ // type *is* the expression that wasn't promoted.
+ if (c.bad == null) return;
+ c.f(i ?? c.bad);
+ // ^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe] The argument type 'int?' can't be assigned to the parameter type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C10 {
+ D10? bad;
+ f(bool b) {}
+}
+
+class D10 {
+ bool operator ==(covariant D10 other) => true;
+}
+
+equalRhs(C10 c, D10 d) {
+ if (c.bad == null) return;
+ // Note: we don't report an error here because `==` always accepts `null`.
+ c.f(d == c.bad);
+ c.f(d != c.bad);
+}
+
+class C11 {
+ bool? bad;
+ // ^
+ // [context 9] 'bad' refers to a property so it couldn't be promoted.
+ // [context 10] 'bad' refers to a property so it couldn't be promoted.
+ f(bool b) {}
+}
+
+andOperand(C11 c, bool b) {
+ if (c.bad == null) return;
+ c.f(c.bad && b);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 9] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+ c.f(b && c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 10] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C12 {
+ bool? bad;
+ // ^
+ // [context 11] 'bad' refers to a property so it couldn't be promoted.
+ // [context 12] 'bad' refers to a property so it couldn't be promoted.
+ f(bool b) {}
+}
+
+orOperand(C12 c, bool b) {
+ if (c.bad == null) return;
+ c.f(c.bad || b);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 11] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+ c.f(b || c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 12] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C13 {
+ bool? bad;
+ // ^
+ // [context 13] 'bad' refers to a property so it couldn't be promoted.
+}
+
+assertStatementCondition(C13 c) {
+ if (c.bad == null) return;
+ assert(c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 13] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C14 {
+ bool? bad;
+ // ^
+ // [context 14] 'bad' refers to a property so it couldn't be promoted.
+ C14.assertInitializerCondition(C14 c)
+ : bad = c.bad!,
+ assert(c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 14] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C15 {
+ bool? bad;
+ // ^
+ // [context 15] 'bad' refers to a property so it couldn't be promoted.
+ f(bool b) {}
+}
+
+notOperand(C15 c) {
+ if (c.bad == null) return;
+ c.f(!c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 15] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C16 {
+ bool? bad;
+ // ^
+ // [context 16] 'bad' refers to a property so it couldn't be promoted.
+ // [context 17] 'bad' refers to a property so it couldn't be promoted.
+ // [context 18] 'bad' refers to a property so it couldn't be promoted.
+ // [context 19] 'bad' refers to a property so it couldn't be promoted.
+}
+
+forLoopCondition(C16 c) {
+ if (c.bad == null) return;
+ for (; c.bad;) {}
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 16] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+ [for (; c.bad;) null];
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 17] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+ ({for (; c.bad;) null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 18] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+ ({for (; c.bad;) null: null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 19] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C17 {
+ bool? bad;
+ // ^
+ // [context 20] 'bad' refers to a property so it couldn't be promoted.
+ f(int i) {}
+}
+
+conditionalExpressionCondition(C17 c) {
+ if (c.bad == null) return;
+ c.f(c.bad ? 1 : 2);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 20] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C18 {
+ bool? bad;
+ // ^
+ // [context 21] 'bad' refers to a property so it couldn't be promoted.
+}
+
+doLoopCondition(C18 c) {
+ if (c.bad == null) return;
+ do {} while (c.bad);
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 21] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C19 {
+ bool? bad;
+ // ^
+ // [context 22] 'bad' refers to a property so it couldn't be promoted.
+ // [context 23] 'bad' refers to a property so it couldn't be promoted.
+ // [context 24] 'bad' refers to a property so it couldn't be promoted.
+ // [context 25] 'bad' refers to a property so it couldn't be promoted.
+}
+
+ifCondition(C19 c) {
+ if (c.bad == null) return;
+ if (c.bad) {}
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 22] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+ [if (c.bad) null];
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 23] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+ ({if (c.bad) null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 24] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+ ({if (c.bad) null: null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 25] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C20 {
+ bool? bad;
+ // ^
+ // [context 26] 'bad' refers to a property so it couldn't be promoted.
+}
+
+whileCondition(C20 c) {
+ if (c.bad == null) return;
+ while (c.bad) {}
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 26] A value of type 'bool?' can't be assigned to a variable of type 'bool' because 'bool?' is nullable and 'bool' isn't.
+}
+
+class C21 {
+ int? bad;
+ // ^
+ // [context 27] 'bad' refers to a property so it couldn't be promoted.
+}
+
+assignmentRhs(C21 c, int i) {
+ if (c.bad == null) return;
+ i = c.bad;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 27] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C22 {
+ int? bad;
+ // ^
+ // [context 28] 'bad' refers to a property so it couldn't be promoted.
+}
+
+variableInitializer(C22 c) {
+ if (c.bad == null) return;
+ int i = c.bad;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 28] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C23 {
+ int? bad;
+ // ^
+ // [context 29] 'bad' refers to a property so it couldn't be promoted.
+ final int x;
+ final int y;
+ C23.constructorInitializer(C23 c)
+ : x = c.bad!,
+ y = c.bad;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_NOT_ASSIGNABLE
+ // ^
+ // [cfe 29] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C24 {
+ int? bad;
+ // ^
+ // [context 30] 'bad' refers to a property so it couldn't be promoted.
+ // [context 31] 'bad' refers to a property so it couldn't be promoted.
+ // [context 32] 'bad' refers to a property so it couldn't be promoted.
+ // [context 33] 'bad' refers to a property so it couldn't be promoted.
+}
+
+forVariableInitializer(C24 c) {
+ if (c.bad == null) return;
+ for (int i = c.bad; false;) {}
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 30] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+ [for (int i = c.bad; false;) null];
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 31] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+ ({for (int i = c.bad; false;) null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 32] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+ ({for (int i = c.bad; false;) null: null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 33] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C25 {
+ int? bad;
+ // ^
+ // [context 34] 'bad' refers to a property so it couldn't be promoted.
+ // [context 35] 'bad' refers to a property so it couldn't be promoted.
+ // [context 36] 'bad' refers to a property so it couldn't be promoted.
+ // [context 37] 'bad' refers to a property so it couldn't be promoted.
+}
+
+forAssignmentInitializer(C25 c, int i) {
+ if (c.bad == null) return;
+ for (i = c.bad; false;) {}
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 34] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+ [for (i = c.bad; false;) null];
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 35] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+ ({for (i = c.bad; false;) null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 36] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+ ({for (i = c.bad; false;) null: null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
+ // ^
+ // [cfe 37] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C26 {
+ int? bad;
+ // ^
+ // [context 38] 'bad' refers to a property so it couldn't be promoted.
+}
+
+compoundAssignmentRhs(C26 c) {
+ num n = 0;
+ if (c.bad == null) return;
+ n += c.bad;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 38] A value of type 'int?' can't be assigned to a variable of type 'num' because 'int?' is nullable and 'num' isn't.
+}
+
+class C27 {
+ int? bad;
+ // ^
+ // [context 39] 'bad' refers to a property so it couldn't be promoted.
+}
+
+indexGet(C27 c, List<int> values) {
+ if (c.bad == null) return;
+ values[c.bad];
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 39] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C28 {
+ int? bad;
+ // ^
+ // [context 40] 'bad' refers to a property so it couldn't be promoted.
+}
+
+indexSet(C28 c, List<int> values) {
+ if (c.bad == null) return;
+ values[c.bad] = 0;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe 40] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C29 {
+ int? bad;
+}
+
+indexSetCompound(C29 c, List<int> values) {
+ // TODO(paulberry): get this to work with the CFE
+ if (c.bad == null) return;
+ values[c.bad] += 1;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C30 {
+ int? bad;
+}
+
+indexSetIfNull(C30 c, List<int?> values) {
+ // TODO(paulberry): get this to work with the CFE
+ if (c.bad == null) return;
+ values[c.bad] ??= 1;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C31 {
+ int? bad;
+}
+
+indexSetPreIncDec(C31 c, List<int> values) {
+ // TODO(paulberry): get this to work with the CFE
+ if (c.bad == null) return;
+ ++values[c.bad];
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+ --values[c.bad];
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
+
+class C32 {
+ int? bad;
+}
+
+indexSetPostIncDec(C32 c, List<int> values) {
+ // TODO(paulberry): get this to work with the CFE
+ if (c.bad == null) return;
+ values[c.bad]++;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+ values[c.bad]--;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ // ^
+ // [cfe] A value of type 'int?' can't be assigned to a variable of type 'int' because 'int?' is nullable and 'int' isn't.
+}
diff --git a/tests/language/why_not_promoted/assignment_error_test.dart b/tests/language/why_not_promoted/assignment_error_test.dart
new file mode 100644
index 0000000..6f363d8
--- /dev/null
+++ b/tests/language/why_not_promoted/assignment_error_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, 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.
+
+abstract class C {
+ C? operator +(int i);
+ int get cProperty => 0;
+}
+
+direct_assignment(int? i, int? j) {
+ if (i == null) return;
+ i = j;
+//^
+// [context 1] Variable 'i' could be null due to an intervening write.
+ i.isEven;
+//^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ //^
+ // [cfe 1] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+compound_assignment(C? c, int i) {
+ if (c == null) return;
+ c += i;
+//^
+// [context 2] Variable 'c' could be null due to an intervening write.
+ c.cProperty;
+//^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ //^
+ // [cfe 2] Property 'cProperty' cannot be accessed on 'C?' because it is potentially null.
+}
+
+via_postfix_op(C? c) {
+ if (c == null) return;
+ c++;
+//^
+// [context 3] Variable 'c' could be null due to an intervening write.
+ c.cProperty;
+//^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ //^
+ // [cfe 3] Property 'cProperty' cannot be accessed on 'C?' because it is potentially null.
+}
+
+via_prefix_op(C? c) {
+ if (c == null) return;
+ ++c;
+ //^
+ // [context 4] Variable 'c' could be null due to an intervening write.
+ c.cProperty;
+//^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ //^
+ // [cfe 4] Property 'cProperty' cannot be accessed on 'C?' because it is potentially null.
+}
+
+via_for_each_statement(int? i, List<int?> list) {
+ if (i == null) return;
+ for (i in list) {
+ // ^
+ // [context 5] Variable 'i' could be null due to an intervening write.
+ i.isEven;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ //^
+ // [cfe 5] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+}
+
+via_for_each_list_element(int? i, List<int?> list) {
+ if (i == null) return;
+ [for (i in list) i.isEven];
+ // ^
+ // [context 6] Variable 'i' could be null due to an intervening write.
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 6] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+via_for_each_set_element(int? i, List<int?> list) {
+ if (i == null) return;
+ ({for (i in list) i.isEven});
+ // ^
+ // [context 7] Variable 'i' could be null due to an intervening write.
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 7] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+via_for_each_map_key(int? i, List<int?> list) {
+ if (i == null) return;
+ ({for (i in list) i.isEven: null});
+ // ^
+ // [context 8] Variable 'i' could be null due to an intervening write.
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 8] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+via_for_each_map_value(int? i, List<int?> list) {
+ if (i == null) return;
+ ({for (i in list) null: i.isEven});
+ // ^
+ // [context 9] Variable 'i' could be null due to an intervening write.
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 9] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/extension_property_error_test.dart b/tests/language/why_not_promoted/extension_property_error_test.dart
new file mode 100644
index 0000000..db7d3ee
--- /dev/null
+++ b/tests/language/why_not_promoted/extension_property_error_test.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2021, 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.
+
+class C {
+ get_property_via_explicit_this() {
+ if (this.i == null) return;
+ this.i.isEven;
+// ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 1] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ get_property_via_explicit_this_parenthesized() {
+ if ((this).i == null) return;
+ (this).i.isEven;
+// ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 2] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ get_property_by_implicit_this() {
+ if (i == null) return;
+ i.isEven;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 3] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+}
+
+extension E on C {
+ int? get i => null;
+ // ^
+ // [context 1] 'i' refers to a property so it couldn't be promoted.
+ // [context 2] 'i' refers to a property so it couldn't be promoted.
+ // [context 3] 'i' refers to a property so it couldn't be promoted.
+ // [context 4] 'i' refers to a property so it couldn't be promoted.
+ // [context 5] 'i' refers to a property so it couldn't be promoted.
+ int? get j => null;
+}
+
+class D extends C {
+ get_property_by_implicit_super() {
+ if (i == null) return;
+ i.isEven;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 4] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+}
+
+get_property_via_prefixed_identifier(C c) {
+ if (c.i == null) return;
+ c.i.isEven;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 5] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_property_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+ // Note: no context on this error because the property the user is attempting
+ // to promote is on c1, but the property the user is accessing is on c2.
+ if (c1.i == null) return;
+ c2.i.isEven;
+//^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_property_via_prefixed_identifier_mismatched_property(C c) {
+ // Note: no context on this error because the property the user is attempting
+ // to promote is C.i, but the property the user is accessing is C.j.
+ if (c.i == null) return;
+ c.j.isEven;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/field_error_test.dart b/tests/language/why_not_promoted/field_error_test.dart
new file mode 100644
index 0000000..b32683d
--- /dev/null
+++ b/tests/language/why_not_promoted/field_error_test.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2021, 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.
+
+class C {
+ int? i;
+ // ^
+ // [context 1] 'i' refers to a property so it couldn't be promoted.
+ // [context 2] 'i' refers to a property so it couldn't be promoted.
+ // [context 3] 'i' refers to a property so it couldn't be promoted.
+ // [context 4] 'i' refers to a property so it couldn't be promoted.
+ // [context 5] 'i' refers to a property so it couldn't be promoted.
+ // [context 6] 'i' refers to a property so it couldn't be promoted.
+ int? j;
+
+ get_field_via_explicit_this() {
+ if (this.i == null) return;
+ this.i.isEven;
+// ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 1] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ get_field_via_explicit_this_parenthesized() {
+ if ((this).i == null) return;
+ (this).i.isEven;
+// ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 2] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ get_field_by_implicit_this() {
+ if (i == null) return;
+ i.isEven;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 3] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+}
+
+class D extends C {
+ get_field_via_explicit_super() {
+ if (super.i == null) return;
+ super.i.isEven;
+// ^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 4] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ get_field_by_implicit_super() {
+ if (i == null) return;
+ i.isEven;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 5] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+}
+
+get_field_via_prefixed_identifier(C c) {
+ if (c.i == null) return;
+ c.i.isEven;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 6] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_field_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+ // Note: no context on this error because the property the user is attempting
+ // to promote is on c1, but the property the user is accessing is on c2.
+ if (c1.i == null) return;
+ c2.i.isEven;
+//^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_field_via_prefixed_identifier_mismatched_property(C c) {
+ // Note: no context on this error because the property the user is attempting
+ // to promote is C.i, but the property the user is accessing is C.j.
+ if (c.i == null) return;
+ c.j.isEven;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart b/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart
new file mode 100644
index 0000000..225e86b
--- /dev/null
+++ b/tests/language/why_not_promoted/for_in_loop_type_not_iterable_nullability_error_test.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2021, 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.
+
+// This test contains a test case for each condition that can lead to the front
+// end's `ForInLoopTypeNotIterableNullability` or
+// `ForInLoopTypeNotIterablePartNullability` errors, for which we wish to report
+// "why not promoted" context information.
+
+class C1 {
+ List<int>? bad;
+ // ^
+ // [context 1] 'bad' refers to a property so it couldn't be promoted.
+ // [context 2] 'bad' refers to a property so it couldn't be promoted.
+ // [context 3] 'bad' refers to a property so it couldn't be promoted.
+ // [context 4] 'bad' refers to a property so it couldn't be promoted.
+ // [context 5] 'bad' refers to a property so it couldn't be promoted.
+ // [context 6] 'bad' refers to a property so it couldn't be promoted.
+ // [context 7] 'bad' refers to a property so it couldn't be promoted.
+ // [context 8] 'bad' refers to a property so it couldn't be promoted.
+}
+
+forStatement(C1 c) {
+ if (c.bad == null) return;
+ for (var x in c.bad) {}
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 1] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInList(C1 c) {
+ if (c.bad == null) return;
+ [for (var x in c.bad) null];
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 2] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInSet(C1 c) {
+ if (c.bad == null) return;
+ <dynamic>{for (var x in c.bad) null};
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 3] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInMap(C1 c) {
+ if (c.bad == null) return;
+ <dynamic, dynamic>{for (var x in c.bad) null: null};
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 4] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInAmbiguousSet_resolvableDuringParsing(C1 c) {
+ if (c.bad == null) return;
+ ({for (var x in c.bad) null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 5] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInAmbiguousMap_resolvableDuringParsing(C1 c) {
+ if (c.bad == null) return;
+ ({for (var x in c.bad) null: null});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 6] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInAmbiguousSet_notResolvableDuringParsing(C1 c, List list) {
+ if (c.bad == null) return;
+ ({for (var x in c.bad) ...list});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 7] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
+
+forElementInAmbiguousMap_notResolvableDuringParsing(C1 c, Map map) {
+ if (c.bad == null) return;
+ ({for (var x in c.bad) ...map});
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 8] The type 'List<int>?' used in the 'for' loop must implement 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
diff --git a/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart b/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart
new file mode 100644
index 0000000..78da0e8
--- /dev/null
+++ b/tests/language/why_not_promoted/invalid_assignment_error_nullability_error_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, 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.
+
+// This test contains a test case for each condition that can lead to the front
+// end's `InvalidAssignmentErrorNullability` or
+// `InvalidAssignmentErrorPartNullability` errors, for which we wish to report
+// "why not promoted" context information.
+
+class C1 {
+ List<int>? bad;
+ // ^
+ // [context 1] 'bad' refers to a property so it couldn't be promoted.
+}
+
+test(C1 c) sync* {
+ if (c.bad == null) return;
+ yield* c.bad;
+ // ^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // [analyzer] COMPILE_TIME_ERROR.YIELD_OF_INVALID_TYPE
+ // ^
+ // [cfe 1] A value of type 'List<int>?' can't be assigned to a variable of type 'Iterable<dynamic>' because 'List<int>?' is nullable and 'Iterable<dynamic>' isn't.
+}
diff --git a/tests/language/why_not_promoted/nullable_expression_call_error_test.dart b/tests/language/why_not_promoted/nullable_expression_call_error_test.dart
new file mode 100644
index 0000000..45c461f
--- /dev/null
+++ b/tests/language/why_not_promoted/nullable_expression_call_error_test.dart
@@ -0,0 +1,147 @@
+// Copyright (c) 2021, 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.
+
+// This test contains a test case for each condition that can lead to the front
+// end's `NullableExpressionCallError`, for which we wish to report "why not
+// promoted" context information.
+
+class C1 {
+ C2? bad;
+ // ^
+ // [context 1] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C2 {
+ void call() {}
+}
+
+instance_method_invocation(C1 c) {
+ if (c.bad == null) return;
+ c.bad();
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 1] Can't use an expression of type 'C2?' as a function because it's potentially null.
+}
+
+class C3 {
+ C4? ok;
+ C5? bad;
+ // ^
+ // [context 2] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C4 {}
+
+class C5 {}
+
+extension on C4? {
+ void call() {}
+}
+
+extension on C5 {
+ void call() {}
+}
+
+extension_invocation_method(C3 c) {
+ if (c.ok == null) return;
+ c.ok();
+ if (c.bad == null) return;
+ c.bad();
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 2] Can't use an expression of type 'C5?' as a function because it's potentially null.
+}
+
+class C6 {
+ C7? bad;
+ // ^
+ // [context 3] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C7 {
+ void Function() get call => () {};
+}
+
+instance_getter_invocation(C6 c) {
+ if (c.bad == null) return;
+ c.bad();
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 3] Can't use an expression of type 'C7?' as a function because it's potentially null.
+}
+
+class C8 {
+ C9? ok;
+ C10? bad;
+ // ^
+ // [context 4] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C9 {}
+
+class C10 {}
+
+extension on C9? {
+ void Function() get call => () {};
+}
+
+extension on C10 {
+ void Function() get call => () {};
+}
+
+extension_invocation_getter(C8 c) {
+ if (c.ok == null) return;
+ // Note: the analyzer produces an extraneous error on the line below due to
+ // https://github.com/dart-lang/sdk/issues/45551
+ c.ok();
+//^^^^
+// [analyzer] COMPILE_TIME_ERROR.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+ if (c.bad == null) return;
+ c.bad();
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 4] Can't use an expression of type 'C10?' as a function because it's potentially null.
+}
+
+class C11 {
+ void Function()? bad;
+ // ^
+ // [context 5] 'bad' refers to a property so it couldn't be promoted.
+}
+
+function_invocation(C11 c) {
+ if (c.bad == null) return;
+ c.bad();
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 5] Can't use an expression of type 'void Function()?' as a function because it's potentially null.
+}
+
+class C12 {
+ C13? bad;
+ // ^
+ // [context 6] 'bad' refers to a property so it couldn't be promoted.
+}
+
+class C13 {
+ void Function() foo;
+ C13(this.foo);
+}
+
+instance_field_invocation(C12 c) {
+ if (c.bad == null) return;
+ // Note: the CFE error message is misleading here. See
+ // https://github.com/dart-lang/sdk/issues/45552
+ c.bad.foo();
+//^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 6] Can't use an expression of type 'C13?' as a function because it's potentially null.
+}
diff --git a/tests/language/why_not_promoted/nullable_method_call_error_test.dart b/tests/language/why_not_promoted/nullable_method_call_error_test.dart
new file mode 100644
index 0000000..986436b
--- /dev/null
+++ b/tests/language/why_not_promoted/nullable_method_call_error_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2021, 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.
+
+// This test contains a test case for each condition that can lead to the front
+// end's `NullableMethodCallError`, for which we wish to report "why not
+// promoted" context information.
+
+class C {
+ int? i;
+ // ^
+ // [context 3] 'i' refers to a property so it couldn't be promoted.
+ // [context 4] 'i' refers to a property so it couldn't be promoted.
+ // [context 5] 'i' refers to a property so it couldn't be promoted.
+ // [context 6] 'i' refers to a property so it couldn't be promoted.
+ void Function()? f;
+ // ^
+ // [context 7] 'f' refers to a property so it couldn't be promoted.
+}
+
+extension on int {
+ get propertyOnNonNullInt => null;
+ void methodOnNonNullInt() {}
+}
+
+extension on int? {
+ get propertyOnNullableInt => null;
+ void methodOnNullableInt() {}
+}
+
+property_get_of_variable(int? i, int? j) {
+ if (i == null) return;
+ i = j;
+//^
+// [context 1] Variable 'i' could be null due to an intervening write.
+ i.isEven;
+//^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 1] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+extension_property_get_of_variable(int? i, int? j) {
+ if (i == null) return;
+ i = j;
+//^
+// [context 2] Variable 'i' could be null due to an intervening write.
+ i.propertyOnNullableInt;
+ i.propertyOnNonNullInt;
+//^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 2] Property 'propertyOnNonNullInt' cannot be accessed on 'int?' because it is potentially null.
+}
+
+property_get_of_expression(C c) {
+ if (c.i == null) return;
+ c.i.isEven;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 3] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+extension_property_get_of_expression(C c) {
+ if (c.i == null) return;
+ c.i.propertyOnNullableInt;
+ c.i.propertyOnNonNullInt;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 4] Property 'propertyOnNonNullInt' cannot be accessed on 'int?' because it is potentially null.
+}
+
+method_invocation(C c) {
+ if (c.i == null) return;
+ c.i.abs();
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 5] Method 'abs' cannot be called on 'int?' because it is potentially null.
+}
+
+extension_method_invocation(C c) {
+ if (c.i == null) return;
+ c.i.methodOnNullableInt();
+ c.i.methodOnNonNullInt();
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 6] Method 'methodOnNonNullInt' cannot be called on 'int?' because it is potentially null.
+}
+
+call_invocation(C c) {
+ if (c.f == null) return;
+ c.f.call();
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 7] Method 'call' cannot be called on 'void Function()?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/nullable_spread_error_test.dart b/tests/language/why_not_promoted/nullable_spread_error_test.dart
new file mode 100644
index 0000000..3d9e669
--- /dev/null
+++ b/tests/language/why_not_promoted/nullable_spread_error_test.dart
@@ -0,0 +1,199 @@
+// Copyright (c) 2021, 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.
+
+// This test contains a test case for each condition that can lead to the front
+// end's `NullableSpreadError` error, for which we wish to report "why not
+// promoted" context information.
+
+class C {
+ List<int>? listQuestion;
+ // ^
+ // [context 1] 'listQuestion' refers to a property so it couldn't be promoted.
+ // [context 5] 'listQuestion' refers to a property so it couldn't be promoted.
+ // [context 11] 'listQuestion' refers to a property so it couldn't be promoted.
+ Object? objectQuestion;
+ // ^
+ // [context 4] 'objectQuestion' refers to a property so it couldn't be promoted.
+ // [context 8] 'objectQuestion' refers to a property so it couldn't be promoted.
+ // [context 9] 'objectQuestion' refers to a property so it couldn't be promoted.
+ // [context 10] 'objectQuestion' refers to a property so it couldn't be promoted.
+ // [context 14] 'objectQuestion' refers to a property so it couldn't be promoted.
+ // [context 15] 'objectQuestion' refers to a property so it couldn't be promoted.
+ Set<int>? setQuestion;
+ // ^
+ // [context 2] 'setQuestion' refers to a property so it couldn't be promoted.
+ // [context 6] 'setQuestion' refers to a property so it couldn't be promoted.
+ // [context 12] 'setQuestion' refers to a property so it couldn't be promoted.
+ // [context 16] 'setQuestion' refers to a property so it couldn't be promoted.
+ Map<int, int>? mapQuestion;
+ // ^
+ // [context 3] 'mapQuestion' refers to a property so it couldn't be promoted.
+ // [context 7] 'mapQuestion' refers to a property so it couldn't be promoted.
+ // [context 13] 'mapQuestion' refers to a property so it couldn't be promoted.
+}
+
+list_from_list_question(C c) {
+ if (c.listQuestion == null) return;
+ return [...c.listQuestion];
+ // ^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 1] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+list_from_set_question(C c) {
+ if (c.setQuestion == null) return;
+ return [...c.setQuestion];
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 2] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+list_from_map_question(C c) {
+ if (c.mapQuestion == null) return;
+ return [...c.mapQuestion];
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.NOT_ITERABLE_SPREAD
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 3] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+ // [cfe] Unexpected type 'Map<int, int>?' of a spread. Expected 'dynamic' or an Iterable.
+}
+
+list_from_object_question(C c) {
+ if (c.objectQuestion is! List<int>) return;
+ return [...c.objectQuestion];
+ // ^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.NOT_ITERABLE_SPREAD
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 4] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+ // [cfe] Unexpected type 'Object?' of a spread. Expected 'dynamic' or an Iterable.
+}
+
+set_from_list_question(C c) {
+ if (c.listQuestion == null) return;
+ return {...c.listQuestion};
+ // ^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 5] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+set_from_set_question(C c) {
+ if (c.setQuestion == null) return;
+ return {...c.setQuestion};
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 6] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+set_from_map_question(C c) {
+ if (c.mapQuestion == null) return;
+ return {...c.mapQuestion};
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 7] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+set_from_object_question_type_disambiguate_by_entry(C c) {
+ if (c.objectQuestion is! Set<int>) return;
+ return {null, ...c.objectQuestion};
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
+ // ^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 8] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+ // [cfe] Unexpected type 'Object?' of a spread. Expected 'dynamic' or an Iterable.
+}
+
+set_from_object_question_type_disambiguate_by_previous_spread(C c) {
+ if (c.objectQuestion is! Set<int>) return;
+ return {...<int>{}, ...c.objectQuestion};
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
+ // ^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 9] Unexpected type 'Object?' of a map spread entry. Expected 'dynamic' or a Map.
+}
+
+set_from_object_question_type_disambiguate_by_literal_args(C c) {
+ if (c.objectQuestion is! Set<int>) return;
+ return <int>{...c.objectQuestion};
+ // ^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.NOT_ITERABLE_SPREAD
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 10] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+ // [cfe] Unexpected type 'Object?' of a spread. Expected 'dynamic' or an Iterable.
+}
+
+map_from_list_question(C c) {
+ if (c.listQuestion == null) return;
+ return {...c.listQuestion};
+ // ^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 11] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+map_from_set_question(C c) {
+ if (c.setQuestion == null) return;
+ return {...c.setQuestion};
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 12] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+map_from_map_question(C c) {
+ if (c.mapQuestion == null) return;
+ return {...c.mapQuestion};
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 13] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+}
+
+map_from_object_question_type_disambiguate_by_key_value_pair(C c) {
+ if (c.objectQuestion is! Map<int, int>) return;
+ return {null: null, ...c.objectQuestion};
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
+ // ^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 14] Unexpected type 'Object?' of a map spread entry. Expected 'dynamic' or a Map.
+}
+
+map_from_object_question_type_disambiguate_by_previous_spread(C c) {
+ if (c.objectQuestion is! Map<int, int>) return;
+ return {...<int, int>{}, ...c.objectQuestion};
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_SET_OR_MAP_LITERAL_EITHER
+ // ^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 15] Unexpected type 'Object?' of a map spread entry. Expected 'dynamic' or a Map.
+}
+
+map_from_set_question_type_disambiguate_by_literal_args(C c) {
+ // Note: analyzer shows "why not promoted" information here, but CFE doesn't.
+ // That's probably ok, since there are two problems here (set/map mismatch and
+ // null safety); it's a matter of interpretation whether to prioritize one or
+ // the other.
+ if (c.setQuestion == null) return;
+ return <int, int>{...c.setQuestion};
+ // ^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.NOT_MAP_SPREAD
+ // [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+ // ^
+ // [cfe 16] An expression whose value can be 'null' must be null-checked before it can be dereferenced.
+ // [cfe] Unexpected type 'Set<int>?' of a map spread entry. Expected 'dynamic' or a Map.
+}
diff --git a/tests/language/why_not_promoted/property_error_test.dart b/tests/language/why_not_promoted/property_error_test.dart
new file mode 100644
index 0000000..87452be
--- /dev/null
+++ b/tests/language/why_not_promoted/property_error_test.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2021, 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.
+
+class C {
+ int? get i => null;
+ // ^
+ // [context 1] 'i' refers to a property so it couldn't be promoted.
+ // [context 2] 'i' refers to a property so it couldn't be promoted.
+ // [context 3] 'i' refers to a property so it couldn't be promoted.
+ // [context 4] 'i' refers to a property so it couldn't be promoted.
+ // [context 5] 'i' refers to a property so it couldn't be promoted.
+ // [context 6] 'i' refers to a property so it couldn't be promoted.
+ int? get j => null;
+
+ get_property_via_explicit_this() {
+ if (this.i == null) return;
+ this.i.isEven;
+// ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 1] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ get_property_via_explicit_this_parenthesized() {
+ if ((this).i == null) return;
+ (this).i.isEven;
+// ^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 2] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ get_property_by_implicit_this() {
+ if (i == null) return;
+ i.isEven;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 3] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+}
+
+class D extends C {
+ get_property_via_explicit_super() {
+ if (super.i == null) return;
+ super.i.isEven;
+// ^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 4] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ get_property_by_implicit_super() {
+ if (i == null) return;
+ i.isEven;
+// ^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 5] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+}
+
+get_property_via_prefixed_identifier(C c) {
+ if (c.i == null) return;
+ c.i.isEven;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe 6] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_property_via_prefixed_identifier_mismatched_target(C c1, C c2) {
+ // Note: no context on this error because the property the user is attempting
+ // to promote is on c1, but the property the user is accessing is on c2.
+ if (c1.i == null) return;
+ c2.i.isEven;
+//^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
+
+get_property_via_prefixed_identifier_mismatched_property(C c) {
+ // Note: no context on this error because the property the user is attempting
+ // to promote is C.i, but the property the user is accessing is C.j.
+ if (c.i == null) return;
+ c.j.isEven;
+//^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+}
diff --git a/tests/language/why_not_promoted/this_error_test.dart b/tests/language/why_not_promoted/this_error_test.dart
new file mode 100644
index 0000000..b9a770b
--- /dev/null
+++ b/tests/language/why_not_promoted/this_error_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2021, 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.
+
+// This test validates integration of "why not promoted" when the user tries to
+// promote `this`.
+
+// TODO(paulberry): once we support adding "why not promoted" information to
+// errors that aren't related to null safety, test references to `this` in
+// classes and mixins.
+
+extension on int? {
+ extension_explicit_this() {
+ // TODO(paulberry): get this to work with the CFE.
+ if (this == null) return;
+ this.isEven;
+// ^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// ^
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+
+ extension_implicit_this() {
+ // TODO(paulberry): get this to work with the CFE.
+ if (this == null) return;
+ isEven;
+// ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.UNCHECKED_USE_OF_NULLABLE_VALUE
+// [cfe] Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
+ }
+}
diff --git a/tests/language_2/vm/regress_45525_test.dart b/tests/language_2/vm/regress_45525_test.dart
new file mode 100644
index 0000000..2becc03
--- /dev/null
+++ b/tests/language_2/vm/regress_45525_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2021, 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+dynamic a() {
+ return 23;
+}
+
+dynamic b() {
+ return 26;
+}
+
+@pragma("vm:never-inline")
+dynamic foo() {
+ // BinarySmiOp(<<) marked truncating
+ return (a() << b()) & 0xFFFFFFF;
+}
+
+main() {
+ for (var i = 0; i < 20; i++) {
+ Expect.equals(201326592, foo());
+ }
+}
diff --git a/tools/VERSION b/tools/VERSION
index 7d7fd15..59b36cd 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 13
PATCH 0
-PRERELEASE 190
+PRERELEASE 191
PRERELEASE_PATCH 0
\ No newline at end of file