[CFE] Fix crash in expression evaluation related to type parameters

Change-Id: I9e86877a75c937fbb313ad1e492e15ced4a1be9d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448400
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Jens Johansen
2025-09-05 00:05:41 -07:00
committed by Commit Queue
parent a757154d93
commit 9e89e9145b
5 changed files with 53 additions and 25 deletions
@@ -56,11 +56,13 @@ import 'package:kernel/kernel.dart'
VariableSet,
VisitorDefault,
VisitorVoidMixin,
Member;
Member,
TypeParameterType;
import 'package:kernel/kernel.dart' as kernel show Combinator;
import 'package:kernel/reference_from_index.dart';
import 'package:kernel/target/changed_structure_notifier.dart'
show ChangedStructureNotifier;
import 'package:kernel/type_algebra.dart' show Substitution;
import 'package:package_config/package_config.dart' show Package, PackageConfig;
import '../api_prototype/experimental_flags.dart';
@@ -1863,6 +1865,25 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
cls,
offset,
);
Map<TypeParameter, TypeParameterType> substitutionMap = {};
Map<String, TypeParameter> typeDefinitionNamesMap = {};
for (TypeParameter typeDefinition in typeDefinitions) {
if (typeDefinition.name != null) {
typeDefinitionNamesMap[typeDefinition.name!] = typeDefinition;
}
}
for (TypeParameter typeParameter in foundScope.typeParameters) {
TypeParameter? match = typeDefinitionNamesMap[typeParameter.name];
if (match != null) {
substitutionMap[typeParameter] = new TypeParameterType(
match,
match.computeNullabilityFromBound(),
);
}
}
Substitution substitution = Substitution.fromMap(substitutionMap);
final bool alwaysInlineConstants = lastGoodKernelTarget
.backendTarget
.constantsBackend
@@ -1886,7 +1907,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
extraKnownVariables.add(
new VariableDeclarationImpl(
def.key,
type: def.value.type,
type: substitution.substituteType(def.value.type),
isConst: true,
hasDeclaredInitializer: true,
initializer: def.value.initializer,
@@ -1905,7 +1926,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
extraKnownVariables.add(
new VariableDeclarationImpl(
def.key,
type: def.value.type,
type: substitution.substituteType(def.value.type),
isConst: false,
)..fileOffset = def.value.fileOffset,
);
@@ -1914,7 +1935,9 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
_ExtensionTypeFinder.isOrContainsExtensionType(
def.value.type,
)) {
usedDefinitions[def.key] = def.value.type;
usedDefinitions[def.key] = substitution.substituteType(
def.value.type,
);
}
}
}
@@ -101,9 +101,7 @@ class Foo2<E extends num> {
class=Foo2,
member=foo,
static,
typeParameters=[
Foo2.E,
Foo2.foo.E],
typeParameters=[Foo2.foo.E],
variables=[a]
*/
x;
@@ -131,7 +129,6 @@ class Foo2<E extends num> {
class=Foo2,
member=bar,
static,
typeParameters=[Foo2.E],
variables=[a]
*/
x;
@@ -143,9 +140,7 @@ class Foo2<E extends num> {
class=Foo2,
member=baz,
static,
typeParameters=[
Foo2.E,
Foo2.baz.E],
typeParameters=[Foo2.baz.E],
variables=[a]
*/
x;
+3 -11
View File
@@ -94,8 +94,7 @@ mixin GenericMixin<T> {
static var field = /*
class=GenericMixin,
member=field,
typeParameters=[GenericMixin.T]
member=field
*/
x;
@@ -103,8 +102,7 @@ mixin GenericMixin<T> {
/*
class=GenericMixin,
member=empty,
static,
typeParameters=[GenericMixin.T]
static
*/
x;
}
@@ -114,7 +112,6 @@ mixin GenericMixin<T> {
class=GenericMixin,
member=oneParameter,
static,
typeParameters=[GenericMixin.T],
variables=[a]
*/
x;
@@ -125,7 +122,6 @@ mixin GenericMixin<T> {
class=GenericMixin,
member=twoParameters,
static,
typeParameters=[GenericMixin.T],
variables=[
a,
b]
@@ -138,7 +134,6 @@ mixin GenericMixin<T> {
class=GenericMixin,
member=optionalParameter,
static,
typeParameters=[GenericMixin.T],
variables=[
a,
b]
@@ -151,7 +146,6 @@ mixin GenericMixin<T> {
class=GenericMixin,
member=namedParameter,
static,
typeParameters=[GenericMixin.T],
variables=[
a,
b]
@@ -164,9 +158,7 @@ mixin GenericMixin<T> {
class=GenericMixin,
member=oneTypeParameter,
static,
typeParameters=[
GenericMixin.T,
GenericMixin.oneTypeParameter.T]
typeParameters=[GenericMixin.oneTypeParameter.T]
*/
x;
}
+12 -3
View File
@@ -111,10 +111,19 @@ class DartScopeBuilder2 extends VisitorDefault<void> with VisitorVoidMixin {
}
}
}
// TODO(jensj): If the current member is static and we're in a class we have
// to skip the typeParameters from the class.
int fromIndex = 0;
if (_currentCls != null &&
_currentMember != null &&
!_currentMember!.isInstanceMember &&
_currentMember is! Constructor) {
// We're inside a class, but currently in a static member (that is not a
// constructor). The first list in [typeParameterScopes] are the class
// ones, so we'll skip those here.
fromIndex = 1;
}
List<TypeParameter> typeParameters = [];
for (List<TypeParameter> typeParameterScope in typeParameterScopes) {
for (int i = fromIndex; i < typeParameterScopes.length; i++) {
List<TypeParameter> typeParameterScope = typeParameterScopes[i];
typeParameters.addAll(typeParameterScope);
}
DartScope2 findScope = new DartScope2(node, _library, _currentCls,
@@ -350,6 +350,15 @@ class ScopeTestingBinaryPrinter extends BinaryPrinter {
List<Object> expectedTypeParameters =
getTypeParameterIndexerForTesting().index.keys.toList();
if (currentMember != null &&
!currentMember!.isInstanceMember &&
currentMember is! Constructor &&
currentClass != null &&
currentClass!.typeParameters.isNotEmpty) {
expectedTypeParameters = (expectedTypeParameters.toSet()
..removeAll(currentClass!.typeParameters))
.toList();
}
VariableIndexer2? varIndexer =
getVariableIndexerForTesting() as VariableIndexer2?;