Skip to content

Commit 408e486

Browse files
chloestefantsovaCommit Queue
authored andcommitted
[cfe] Account for extension type self-dependency via raw types
Closes #54241 Change-Id: I7afcaab225f93763f0dd2852bb51227c05abe4bb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/340403 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent d0aa049 commit 408e486

10 files changed

+236
-2
lines changed

pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'package:front_end/src/fasta/builder/record_type_builder.dart';
6-
import 'package:front_end/src/fasta/kernel/body_builder_context.dart';
75
import 'package:kernel/ast.dart';
86
import 'package:kernel/class_hierarchy.dart';
97
import 'package:kernel/core_types.dart';
@@ -20,10 +18,16 @@ import '../builder/library_builder.dart';
2018
import '../builder/member_builder.dart';
2119
import '../builder/metadata_builder.dart';
2220
import '../builder/name_iterator.dart';
21+
import '../builder/record_type_builder.dart';
2322
import '../builder/type_builder.dart';
23+
import '../dill/dill_class_builder.dart';
24+
import '../dill/dill_extension_type_declaration_builder.dart';
25+
import '../dill/dill_type_alias_builder.dart';
26+
import '../kernel/body_builder_context.dart';
2427
import '../kernel/hierarchy/hierarchy_builder.dart';
2528
import '../kernel/kernel_helper.dart';
2629
import '../kernel/type_algorithms.dart';
30+
import '../kernel/type_builder_computer.dart';
2731
import '../messages.dart';
2832
import '../problems.dart';
2933
import '../scope.dart';
@@ -373,6 +377,65 @@ class SourceExtensionTypeDeclarationBuilder
373377
return true;
374378
}
375379
}
380+
} else if (declaration != null && declaration.typeVariablesCount > 0) {
381+
List<TypeVariableBuilderBase>? typeParameters;
382+
List<TypeParameter>? typeParametersFromKernel;
383+
bool isFromKernel = false;
384+
switch (declaration) {
385+
case ClassBuilder():
386+
typeParameters = declaration.typeVariables;
387+
if (declaration is DillClassBuilder) {
388+
isFromKernel = true;
389+
typeParametersFromKernel = declaration.cls.typeParameters;
390+
}
391+
case TypeAliasBuilder():
392+
typeParameters = declaration.typeVariables;
393+
if (declaration is DillTypeAliasBuilder) {
394+
isFromKernel = true;
395+
typeParametersFromKernel = declaration.typedef.typeParameters;
396+
}
397+
case ExtensionTypeDeclarationBuilder():
398+
typeParameters = declaration.typeParameters;
399+
if (declaration is DillExtensionTypeDeclarationBuilder) {
400+
isFromKernel = true;
401+
typeParametersFromKernel =
402+
declaration.extensionTypeDeclaration.typeParameters;
403+
}
404+
case BuiltinTypeDeclarationBuilder():
405+
case InvalidTypeDeclarationBuilder():
406+
case OmittedTypeDeclarationBuilder():
407+
case ExtensionBuilder():
408+
case TypeVariableBuilderBase():
409+
}
410+
if (typeParameters != null) {
411+
TypeBuilderComputer? typeBuilderComputer;
412+
for (int i = 0; i < typeParameters.length; i++) {
413+
TypeVariableBuilderBase typeParameter = typeParameters[i];
414+
if (!isFromKernel) {
415+
if (_checkRepresentationDependency(
416+
typeParameter.defaultType!,
417+
rootExtensionTypeDeclaration,
418+
seenExtensionTypeDeclarations.toSet(),
419+
usedTypeAliasBuilders.toSet())) {
420+
return true;
421+
}
422+
} else if (typeParametersFromKernel != null) {
423+
assert(
424+
typeParameters.length == typeParametersFromKernel.length);
425+
typeBuilderComputer ??=
426+
new TypeBuilderComputer(libraryBuilder.loader);
427+
if (_checkRepresentationDependency(
428+
typeParametersFromKernel[i]
429+
.defaultType
430+
.accept(typeBuilderComputer),
431+
rootExtensionTypeDeclaration,
432+
seenExtensionTypeDeclarations.toSet(),
433+
usedTypeAliasBuilders.toSet())) {
434+
return true;
435+
}
436+
}
437+
}
438+
}
376439
}
377440
case FunctionTypeBuilder(
378441
:List<StructuralVariableBuilder>? typeVariables,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
class A<X extends E> {}
6+
extension type E(Function<Y extends A>() it) {}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type.
6+
// extension type E(Function<Y extends A>() it) {}
7+
// ^
8+
//
9+
import self as self;
10+
import "dart:core" as core;
11+
12+
class A<X extends self::E /* = invalid-type */> extends core::Object {
13+
synthetic constructor •() → self::A<self::A::X%>
14+
: super core::Object::•()
15+
;
16+
}
17+
extension type E(invalid-type it) {
18+
abstract extension-type-member representation-field get it() → <Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic;
19+
constructor • = self::E|constructor#;
20+
constructor tearoff • = self::E|constructor#_#new#tearOff;
21+
}
22+
static extension-type-member method E|constructor#(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */ {
23+
lowered final self::E /* = invalid-type */ #this = it;
24+
return #this;
25+
}
26+
static extension-type-member method E|constructor#_#new#tearOff(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */
27+
return self::E|constructor#(it);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type.
6+
// extension type E(Function<Y extends A>() it) {}
7+
// ^
8+
//
9+
import self as self;
10+
import "dart:core" as core;
11+
12+
class A<X extends self::E /* = invalid-type */> extends core::Object {
13+
synthetic constructor •() → self::A<self::A::X%>
14+
: super core::Object::•()
15+
;
16+
}
17+
extension type E(invalid-type it) {
18+
abstract extension-type-member representation-field get it() → <Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic;
19+
constructor • = self::E|constructor#;
20+
constructor tearoff • = self::E|constructor#_#new#tearOff;
21+
}
22+
static extension-type-member method E|constructor#(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */ {
23+
lowered final self::E /* = invalid-type */ #this = it;
24+
return #this;
25+
}
26+
static extension-type-member method E|constructor#_#new#tearOff(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */
27+
return self::E|constructor#(it);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class A<X extends E> {}
2+
3+
extension type E(Function<Y extends A>() it) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class A<X extends E> {}
2+
3+
extension type E(Function<Y extends A>() it) {}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type.
6+
// extension type E(Function<Y extends A>() it) {}
7+
// ^
8+
//
9+
import self as self;
10+
import "dart:core" as core;
11+
12+
class A<X extends self::E /* = invalid-type */> extends core::Object {
13+
synthetic constructor •() → self::A<self::A::X%>
14+
: super core::Object::•()
15+
;
16+
}
17+
extension type E(invalid-type it) {
18+
abstract extension-type-member representation-field get it() → <Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic;
19+
constructor • = self::E|constructor#;
20+
constructor tearoff • = self::E|constructor#_#new#tearOff;
21+
}
22+
static extension-type-member method E|constructor#(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */ {
23+
lowered final self::E /* = invalid-type */ #this = it;
24+
return #this;
25+
}
26+
static extension-type-member method E|constructor#_#new#tearOff(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */
27+
return self::E|constructor#(it);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type.
6+
// extension type E(Function<Y extends A>() it) {}
7+
// ^
8+
//
9+
import self as self;
10+
import "dart:core" as core;
11+
12+
class A<X extends self::E /* = invalid-type */> extends core::Object {
13+
synthetic constructor •() → self::A<self::A::X%>
14+
: super core::Object::•()
15+
;
16+
}
17+
extension type E(invalid-type it) {
18+
abstract extension-type-member representation-field get it() → <Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic;
19+
constructor • = self::E|constructor#;
20+
constructor tearoff • = self::E|constructor#_#new#tearOff;
21+
}
22+
static extension-type-member method E|constructor#(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */ {
23+
lowered final self::E /* = invalid-type */ #this = it;
24+
return #this;
25+
}
26+
static extension-type-member method E|constructor#_#new#tearOff(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */
27+
return self::E|constructor#(it);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type.
6+
// extension type E(Function<Y extends A>() it) {}
7+
// ^
8+
//
9+
import self as self;
10+
import "dart:core" as core;
11+
12+
class A<X extends self::E /* = invalid-type */> extends core::Object {
13+
synthetic constructor •() → self::A<self::A::X%>
14+
;
15+
}
16+
extension type E(invalid-type it) {
17+
abstract extension-type-member representation-field get it() → <Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic;
18+
constructor • = self::E|constructor#;
19+
constructor tearoff • = self::E|constructor#_#new#tearOff;
20+
}
21+
static extension-type-member method E|constructor#(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */
22+
;
23+
static extension-type-member method E|constructor#_#new#tearOff(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */
24+
return self::E|constructor#(it);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/extension_types/issue54241.dart:6:18: Error: An extension type can't depend on itself through its representation type.
6+
// extension type E(Function<Y extends A>() it) {}
7+
// ^
8+
//
9+
import self as self;
10+
import "dart:core" as core;
11+
12+
class A<X extends self::E /* = invalid-type */> extends core::Object {
13+
synthetic constructor •() → self::A<self::A::X%>
14+
: super core::Object::•()
15+
;
16+
}
17+
extension type E(invalid-type it) {
18+
abstract extension-type-member representation-field get it() → <Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic;
19+
constructor • = self::E|constructor#;
20+
constructor tearoff • = self::E|constructor#_#new#tearOff;
21+
}
22+
static extension-type-member method E|constructor#(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */ {
23+
lowered final self::E /* = invalid-type */ #this = it;
24+
return #this;
25+
}
26+
static extension-type-member method E|constructor#_#new#tearOff(<Y extends self::A<self::E /* = invalid-type */> = dynamic>() → dynamic it) → self::E /* = invalid-type */
27+
return self::E|constructor#(it);

0 commit comments

Comments
 (0)