From 9e89e9145b9d82fdde6ed85993226626926dca7e Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Fri, 5 Sep 2025 00:05:41 -0700 Subject: [PATCH] [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 Reviewed-by: Johnni Winther --- .../lib/src/base/incremental_compiler.dart | 31 ++++++++++++++++--- .../test/scopes/data/constructor.dart | 9 ++---- pkg/front_end/test/scopes/data/mixins.dart | 14 ++------- pkg/kernel/lib/dart_scope_calculator.dart | 15 +++++++-- .../test/dart_scope_calculator_test.dart | 9 ++++++ 5 files changed, 53 insertions(+), 25 deletions(-) diff --git a/pkg/front_end/lib/src/base/incremental_compiler.dart b/pkg/front_end/lib/src/base/incremental_compiler.dart index adeaaf42433..f08fd03c04f 100644 --- a/pkg/front_end/lib/src/base/incremental_compiler.dart +++ b/pkg/front_end/lib/src/base/incremental_compiler.dart @@ -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 substitutionMap = {}; + Map 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, + ); } } } diff --git a/pkg/front_end/test/scopes/data/constructor.dart b/pkg/front_end/test/scopes/data/constructor.dart index 888838477c4..bed1b984d6e 100644 --- a/pkg/front_end/test/scopes/data/constructor.dart +++ b/pkg/front_end/test/scopes/data/constructor.dart @@ -101,9 +101,7 @@ class Foo2 { class=Foo2, member=foo, static, - typeParameters=[ - Foo2.E, - Foo2.foo.E], + typeParameters=[Foo2.foo.E], variables=[a] */ x; @@ -131,7 +129,6 @@ class Foo2 { class=Foo2, member=bar, static, - typeParameters=[Foo2.E], variables=[a] */ x; @@ -143,9 +140,7 @@ class Foo2 { class=Foo2, member=baz, static, - typeParameters=[ - Foo2.E, - Foo2.baz.E], + typeParameters=[Foo2.baz.E], variables=[a] */ x; diff --git a/pkg/front_end/test/scopes/data/mixins.dart b/pkg/front_end/test/scopes/data/mixins.dart index b3987e3e8f0..5426efe54b7 100644 --- a/pkg/front_end/test/scopes/data/mixins.dart +++ b/pkg/front_end/test/scopes/data/mixins.dart @@ -94,8 +94,7 @@ mixin GenericMixin { static var field = /* class=GenericMixin, - member=field, - typeParameters=[GenericMixin.T] + member=field */ x; @@ -103,8 +102,7 @@ mixin GenericMixin { /* class=GenericMixin, member=empty, - static, - typeParameters=[GenericMixin.T] + static */ x; } @@ -114,7 +112,6 @@ mixin GenericMixin { class=GenericMixin, member=oneParameter, static, - typeParameters=[GenericMixin.T], variables=[a] */ x; @@ -125,7 +122,6 @@ mixin GenericMixin { class=GenericMixin, member=twoParameters, static, - typeParameters=[GenericMixin.T], variables=[ a, b] @@ -138,7 +134,6 @@ mixin GenericMixin { class=GenericMixin, member=optionalParameter, static, - typeParameters=[GenericMixin.T], variables=[ a, b] @@ -151,7 +146,6 @@ mixin GenericMixin { class=GenericMixin, member=namedParameter, static, - typeParameters=[GenericMixin.T], variables=[ a, b] @@ -164,9 +158,7 @@ mixin GenericMixin { class=GenericMixin, member=oneTypeParameter, static, - typeParameters=[ - GenericMixin.T, - GenericMixin.oneTypeParameter.T] + typeParameters=[GenericMixin.oneTypeParameter.T] */ x; } diff --git a/pkg/kernel/lib/dart_scope_calculator.dart b/pkg/kernel/lib/dart_scope_calculator.dart index 8084844c3f1..253eaac6457 100644 --- a/pkg/kernel/lib/dart_scope_calculator.dart +++ b/pkg/kernel/lib/dart_scope_calculator.dart @@ -111,10 +111,19 @@ class DartScopeBuilder2 extends VisitorDefault 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 typeParameters = []; - for (List typeParameterScope in typeParameterScopes) { + for (int i = fromIndex; i < typeParameterScopes.length; i++) { + List typeParameterScope = typeParameterScopes[i]; typeParameters.addAll(typeParameterScope); } DartScope2 findScope = new DartScope2(node, _library, _currentCls, diff --git a/pkg/kernel/test/dart_scope_calculator_test.dart b/pkg/kernel/test/dart_scope_calculator_test.dart index fb5a011e703..a0f7f4b5f67 100644 --- a/pkg/kernel/test/dart_scope_calculator_test.dart +++ b/pkg/kernel/test/dart_scope_calculator_test.dart @@ -350,6 +350,15 @@ class ScopeTestingBinaryPrinter extends BinaryPrinter { List 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?;