Skip to content

Commit f65f719

Browse files
pqCommit Queue
authored and
Commit Queue
committed
[element model] fix unsafe ConstructorMember cast
See: b/374689139. https://dart-review.googlesource.com/c/sdk/+/390941 is blocking an SDK roll. Root cause: ``` Action threw an exception: type 'ConstructorMember' is not a subtype of type 'ConstructorFragment' in type cast #0 InterfaceTypeImpl.constructors2.<anonymous closure> (package:analyzer/src/dart/element/type.dart:569) #1 MappedListIterable.elementAt (dart:_internal/iterable.dart:435) #2 ListIterator.moveNext (dart:_internal/iterable.dart:364) #3 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:189) #4 new _GrowableList.of (dart:core-patch/growable_array.dart:150) #5 new List.of (dart:core-patch/array_patch.dart:39) #6 ListIterable.toList (dart:_internal/iterable.dart:224) #7 InterfaceTypeImpl.constructors2 (package:analyzer/src/dart/element/type.dart:570) #8 _Visitor._hasConstConstructorInvocation (package:linter/src/rules/prefer_const_constructors_in_immutables.dart:110) #9 _Visitor.visitConstructorDeclaration (package:linter/src/rules/prefer_const_constructors_in_immutables.dart:58) ``` To verify the fix locally: ``` solo_test_X() async { await assertNoErrorsInCode(r''' class A<T> {} '''); var A = findElement.class_('A').instantiate( typeArguments: [intType], nullabilitySuffix: NullabilitySuffix.none, ); A.constructors2; } ``` Bug: b/374689139 Change-Id: I70034d938d840dc0c3939db27e7116164e4617e9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391483 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Phil Quitslund <[email protected]>
1 parent 98ddead commit f65f719

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

pkg/analyzer/lib/src/dart/element/type.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,13 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
554554

555555
@override
556556
List<ConstructorElement2> get constructors2 => constructors
557-
.map((fragment) => (fragment as ConstructorFragment).element)
557+
.map((fragment) => switch (fragment) {
558+
ConstructorFragment(:var element) => element,
559+
ConstructorMember() => fragment,
560+
_ => throw StateError(
561+
'unexpected fragment type: ${fragment.runtimeType}',
562+
)
563+
})
558564
.toList();
559565

560566
@override

pkg/linter/test/rules/prefer_const_constructors_in_immutables_test.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,21 @@ macro class M {
405405
]);
406406
}
407407

408+
test_parameterizedType() async {
409+
// Verify we aren't doing an unsafe cast to a `ConstructorFragment` in type.dart.
410+
// b/374689139
411+
await assertNoDiagnostics(r'''
412+
import 'package:meta/meta.dart';
413+
414+
class A<T> {}
415+
416+
@immutable
417+
class C<U> extends A<U> {
418+
C();
419+
}
420+
''');
421+
}
422+
408423
test_returnOfInvalidType() async {
409424
await assertDiagnostics(r'''
410425
import 'package:meta/meta.dart';

0 commit comments

Comments
 (0)