Skip to content

Commit bf31d0e

Browse files
kallentuCommit Queue
authored and
Commit Queue
committed
[cfe] Class type parameters wildcards are non-binding.
Wildcard type parameters are not added to the scope of the class. They do not collide with other wildcards or other wildcard type parameters. Bug: #55655 Change-Id: I473a5023c570623fe2a11df5c07d491082bab642 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371943 Commit-Queue: Kallen Tu <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]>
1 parent 818f977 commit bf31d0e

11 files changed

+279
-4
lines changed

pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@ class NominalVariableBuilder extends TypeVariableBuilderBase {
188188

189189
final TypeParameter actualParameter;
190190

191+
final bool isWildcard;
192+
191193
@override
192194
NominalVariableBuilder? actualOrigin;
193195

@@ -196,7 +198,8 @@ class NominalVariableBuilder extends TypeVariableBuilderBase {
196198
{TypeBuilder? bound,
197199
required TypeVariableKind kind,
198200
Variance? variableVariance,
199-
List<MetadataBuilder>? metadata})
201+
List<MetadataBuilder>? metadata,
202+
this.isWildcard = false})
200203
: actualParameter =
201204
new TypeParameter(name == noNameSentinel ? null : name, null)
202205
..fileOffset = charOffset
@@ -220,7 +223,7 @@ class NominalVariableBuilder extends TypeVariableBuilderBase {
220223
///
221224
/// class A<X extends A<X>> {}
222225
NominalVariableBuilder.fromKernel(TypeParameter parameter,
223-
{required Loader? loader})
226+
{required Loader? loader, this.isWildcard = false})
224227
: actualParameter = parameter,
225228
// TODO(johnniwinther): Do we need to support synthesized type
226229
// parameters from kernel?

pkg/front_end/lib/src/fasta/scope.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ class Scope extends MutableScope {
461461
Scope newScope = new Scope.nested(this, "type variables",
462462
isModifiable: false, kind: ScopeKind.typeParameters);
463463
for (NominalVariableBuilder t in typeVariables) {
464+
if (t.isWildcard) continue;
464465
(newScope._local ??= {})[t.name] = t;
465466
}
466467
return newScope;

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,7 +2583,10 @@ class SourceCompilationUnitImpl implements SourceCompilationUnit {
25832583
{required TypeVariableKind kind}) {
25842584
NominalVariableBuilder builder = new NominalVariableBuilder(
25852585
name, _sourceLibraryBuilder, charOffset, fileUri,
2586-
bound: bound, metadata: metadata, kind: kind);
2586+
bound: bound,
2587+
metadata: metadata,
2588+
kind: kind,
2589+
isWildcard: libraryFeatures.wildcardVariables.isEnabled && name == '_');
25872590

25882591
unboundNominalVariables.add(builder);
25892592
return builder;
@@ -2611,6 +2614,7 @@ class SourceCompilationUnitImpl implements SourceCompilationUnit {
26112614
<String, NominalVariableBuilder>{};
26122615
for (NominalVariableBuilder tv in typeVariables) {
26132616
NominalVariableBuilder? existing = typeVariablesByName[tv.name];
2617+
if (tv.isWildcard) continue;
26142618
if (existing != null) {
26152619
if (existing.kind == TypeVariableKind.extensionSynthesized) {
26162620
// The type parameter from the extension is shadowed by the type
@@ -2673,7 +2677,9 @@ class SourceCompilationUnitImpl implements SourceCompilationUnit {
26732677
?.clone(newTypes, _sourceLibraryBuilder, declaration),
26742678
kind: kind,
26752679
variableVariance:
2676-
variable.parameter.isLegacyCovariant ? null : variable.variance);
2680+
variable.parameter.isLegacyCovariant ? null : variable.variance,
2681+
isWildcard: libraryFeatures.wildcardVariables.isEnabled &&
2682+
variable.isWildcard);
26772683
copy.add(newVariable);
26782684
unboundNominalVariables.add(newVariable);
26792685
}
@@ -6219,6 +6225,7 @@ class TypeParameterScopeBuilder {
62196225
if (typeVariables != null) {
62206226
map = <String, NominalVariableBuilder>{};
62216227
for (NominalVariableBuilder builder in typeVariables) {
6228+
if (builder.isWildcard) continue;
62226229
map[builder.name] = builder;
62236230
}
62246231
}

pkg/front_end/testcases/strong.status

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ value_class/copy_with_call_sites: RuntimeError # Expected
310310
value_class/simple: RuntimeError # Expected
311311
value_class/value_extends_non_value: RuntimeError # Expected
312312
value_class/value_implements_non_value: RuntimeError # Expected
313+
wildcard_variables/class_type_parameters: semiFuzzFailureOnForceRebuildBodies # Expected
313314
wildcard_variables/local_var_no_shadowing: semiFuzzFailureOnForceRebuildBodies # Expected
314315
wildcard_variables/top_level_function_no_shadow: semiFuzzFailureOnForceRebuildBodies # Expected
315316

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2024, 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+
typedef _ = BB;
6+
7+
class AA {}
8+
9+
class BB extends AA {}
10+
11+
class A<T, U extends AA> {}
12+
13+
class B<_, _ extends AA> extends A<_, _> {
14+
int foo<_ extends _>([int _ = 2]) => 1;
15+
}
16+
17+
class C<T, _ extends _> extends A<T, _> {
18+
static const int _ = 1;
19+
}
20+
21+
class D<_, _> {}
22+
23+
class DoesNotUseTypeVariable<_> {
24+
Type returnsBB() {
25+
return _;
26+
}
27+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
typedef _ = self::BB;
6+
class AA extends core::Object {
7+
synthetic constructor •() → self::AA
8+
: super core::Object::•()
9+
;
10+
}
11+
class BB extends self::AA {
12+
synthetic constructor •() → self::BB
13+
: super self::AA::•()
14+
;
15+
}
16+
class A<T extends core::Object? = dynamic, U extends self::AA> extends core::Object {
17+
synthetic constructor •() → self::A<self::A::T%, self::A::U>
18+
: super core::Object::•()
19+
;
20+
}
21+
class B<_ extends core::Object? = dynamic, _ extends self::AA> extends self::A<self::BB, self::BB> {
22+
synthetic constructor •() → self::B<self::B::_%, self::B::_>
23+
: super self::A::•()
24+
;
25+
method foo<_ extends self::BB>([wildcard core::int _ = #C1]) → core::int
26+
return 1;
27+
}
28+
class C<T extends core::Object? = dynamic, _ extends self::BB> extends self::A<self::C::T%, self::BB> {
29+
static const field core::int _ = #C2;
30+
synthetic constructor •() → self::C<self::C::T%, self::C::_>
31+
: super self::A::•()
32+
;
33+
}
34+
class D<_ extends core::Object? = dynamic, _ extends core::Object? = dynamic> extends core::Object {
35+
synthetic constructor •() → self::D<self::D::_%, self::D::_%>
36+
: super core::Object::•()
37+
;
38+
}
39+
class DoesNotUseTypeVariable<_ extends core::Object? = dynamic> extends core::Object {
40+
synthetic constructor •() → self::DoesNotUseTypeVariable<self::DoesNotUseTypeVariable::_%>
41+
: super core::Object::•()
42+
;
43+
method returnsBB() → core::Type {
44+
return #C3;
45+
}
46+
}
47+
48+
constants {
49+
#C1 = 2
50+
#C2 = 1
51+
#C3 = TypeLiteralConstant(self::BB)
52+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
typedef _ = self::BB;
6+
class AA extends core::Object {
7+
synthetic constructor •() → self::AA
8+
: super core::Object::•()
9+
;
10+
}
11+
class BB extends self::AA {
12+
synthetic constructor •() → self::BB
13+
: super self::AA::•()
14+
;
15+
}
16+
class A<T extends core::Object? = dynamic, U extends self::AA> extends core::Object {
17+
synthetic constructor •() → self::A<self::A::T%, self::A::U>
18+
: super core::Object::•()
19+
;
20+
}
21+
class B<_ extends core::Object? = dynamic, _ extends self::AA> extends self::A<self::BB, self::BB> {
22+
synthetic constructor •() → self::B<self::B::_%, self::B::_>
23+
: super self::A::•()
24+
;
25+
method foo<_ extends self::BB>([wildcard core::int _ = #C1]) → core::int
26+
return 1;
27+
}
28+
class C<T extends core::Object? = dynamic, _ extends self::BB> extends self::A<self::C::T%, self::BB> {
29+
static const field core::int _ = #C2;
30+
synthetic constructor •() → self::C<self::C::T%, self::C::_>
31+
: super self::A::•()
32+
;
33+
}
34+
class D<_ extends core::Object? = dynamic, _ extends core::Object? = dynamic> extends core::Object {
35+
synthetic constructor •() → self::D<self::D::_%, self::D::_%>
36+
: super core::Object::•()
37+
;
38+
}
39+
class DoesNotUseTypeVariable<_ extends core::Object? = dynamic> extends core::Object {
40+
synthetic constructor •() → self::DoesNotUseTypeVariable<self::DoesNotUseTypeVariable::_%>
41+
: super core::Object::•()
42+
;
43+
method returnsBB() → core::Type {
44+
return #C3;
45+
}
46+
}
47+
48+
constants {
49+
#C1 = 2
50+
#C2 = 1
51+
#C3 = TypeLiteralConstant(self::BB)
52+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
typedef _ = self::BB;
6+
class AA extends core::Object {
7+
synthetic constructor •() → self::AA
8+
;
9+
}
10+
class BB extends self::AA {
11+
synthetic constructor •() → self::BB
12+
;
13+
}
14+
class A<T extends core::Object? = dynamic, U extends self::AA> extends core::Object {
15+
synthetic constructor •() → self::A<self::A::T%, self::A::U>
16+
;
17+
}
18+
class B<_ extends core::Object? = dynamic, _ extends self::AA> extends self::A<self::BB, self::BB> {
19+
synthetic constructor •() → self::B<self::B::_%, self::B::_>
20+
;
21+
method foo<_ extends self::BB>([wildcard core::int _ = 2]) → core::int
22+
;
23+
}
24+
class C<T extends core::Object? = dynamic, _ extends self::BB> extends self::A<self::C::T%, self::BB> {
25+
static const field core::int _ = 1;
26+
synthetic constructor •() → self::C<self::C::T%, self::C::_>
27+
;
28+
}
29+
class D<_ extends core::Object? = dynamic, _ extends core::Object? = dynamic> extends core::Object {
30+
synthetic constructor •() → self::D<self::D::_%, self::D::_%>
31+
;
32+
}
33+
class DoesNotUseTypeVariable<_ extends core::Object? = dynamic> extends core::Object {
34+
synthetic constructor •() → self::DoesNotUseTypeVariable<self::DoesNotUseTypeVariable::_%>
35+
;
36+
method returnsBB() → core::Type
37+
;
38+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
typedef _ = self::BB;
6+
class AA extends core::Object {
7+
synthetic constructor •() → self::AA
8+
: super core::Object::•()
9+
;
10+
}
11+
class BB extends self::AA {
12+
synthetic constructor •() → self::BB
13+
: super self::AA::•()
14+
;
15+
}
16+
class A<T extends core::Object? = dynamic, U extends self::AA> extends core::Object {
17+
synthetic constructor •() → self::A<self::A::T%, self::A::U>
18+
: super core::Object::•()
19+
;
20+
}
21+
class B<_ extends core::Object? = dynamic, _ extends self::AA> extends self::A<self::BB, self::BB> {
22+
synthetic constructor •() → self::B<self::B::_%, self::B::_>
23+
: super self::A::•()
24+
;
25+
method foo<_ extends self::BB>([wildcard core::int _ = #C1]) → core::int
26+
return 1;
27+
}
28+
class C<T extends core::Object? = dynamic, _ extends self::BB> extends self::A<self::C::T%, self::BB> {
29+
static const field core::int _ = #C2;
30+
synthetic constructor •() → self::C<self::C::T%, self::C::_>
31+
: super self::A::•()
32+
;
33+
}
34+
class D<_ extends core::Object? = dynamic, _ extends core::Object? = dynamic> extends core::Object {
35+
synthetic constructor •() → self::D<self::D::_%, self::D::_%>
36+
: super core::Object::•()
37+
;
38+
}
39+
class DoesNotUseTypeVariable<_ extends core::Object? = dynamic> extends core::Object {
40+
synthetic constructor •() → self::DoesNotUseTypeVariable<self::DoesNotUseTypeVariable::_%>
41+
: super core::Object::•()
42+
;
43+
method returnsBB() → core::Type {
44+
return #C3;
45+
}
46+
}
47+
48+
constants {
49+
#C1 = 2
50+
#C2 = 1
51+
#C3 = TypeLiteralConstant(self::BB)
52+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
typedef _ = BB;
2+
3+
class AA {}
4+
5+
class BB extends AA {}
6+
7+
class A<T, U extends AA> {}
8+
9+
class B<_, _ extends AA> extends A<_, _> {
10+
int foo<_ extends _>([int _ = 2]) => 1;
11+
}
12+
13+
class C<T, _ extends _> extends A<T, _> {
14+
static const int _ = 1;
15+
}
16+
17+
class D<_, _> {}
18+
19+
class DoesNotUseTypeVariable<_> {
20+
Type returnsBB() {}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class A<T, U extends AA> {}
2+
3+
class AA {}
4+
5+
class B<_, _ extends AA> extends A<_, _> {
6+
int foo<_ extends _>([int _ = 2]) => 1;
7+
}
8+
9+
class BB extends AA {}
10+
11+
class C<T, _ extends _> extends A<T, _> {
12+
static const int _ = 1;
13+
}
14+
15+
class D<_, _> {}
16+
17+
class DoesNotUseTypeVariable<_> {
18+
Type returnsBB() {}
19+
}
20+
21+
typedef _ = BB;

0 commit comments

Comments
 (0)