Skip to content

Commit 67d4561

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Report error on bottom type used as representation type
Closes #53824 Part of #49731 Change-Id: I79776eb4f8b736f518898adff1078461895269f0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/331660 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent 216d985 commit 67d4561

33 files changed

+926
-461
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4455,6 +4455,16 @@ const MessageCode messageExtensionTypeMemberOneOfContext = const MessageCode(
44554455
problemMessage:
44564456
r"""This is one of the inherited extension type members.""");
44574457

4458+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4459+
const Code<Null> codeExtensionTypeRepresentationTypeBottom =
4460+
messageExtensionTypeRepresentationTypeBottom;
4461+
4462+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
4463+
const MessageCode messageExtensionTypeRepresentationTypeBottom =
4464+
const MessageCode("ExtensionTypeRepresentationTypeBottom",
4465+
analyzerCodes: <String>["EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM"],
4466+
problemMessage: r"""The representation type can't be a bottom type.""");
4467+
44584468
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
44594469
const Code<Null> codeExtensionTypeWith = messageExtensionTypeWith;
44604470

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ class SourceExtensionTypeDeclarationBuilder
259259
typeBuilder.fileUri);
260260
}
261261
}
262+
if (isBottom(representationType)) {
263+
libraryBuilder.addProblem(
264+
messageExtensionTypeRepresentationTypeBottom,
265+
representationFieldBuilder!.charOffset,
266+
representationFieldBuilder!.name.length,
267+
representationFieldBuilder!.fileUri);
268+
representationType = const InvalidType();
269+
}
262270
}
263271
} else {
264272
representationType = const DynamicType();

pkg/front_end/messages.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7440,3 +7440,10 @@ ExtensionTypeConstructorWithSuperFormalParameter:
74407440
script: |
74417441
extension type A(int foo) { A.named(this.foo, super.bar); }
74427442
analyzerCode: EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_FORMAL_PARAMETER
7443+
7444+
ExtensionTypeRepresentationTypeBottom:
7445+
problemMessage: "The representation type can't be a bottom type."
7446+
experiments: inline-class
7447+
script: |
7448+
extension type E1(Never foo) {}
7449+
analyzerCode: EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM

pkg/front_end/testcases/extension_types/implement_all.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extension type ET_Null(Null it) implements Null /* Error */ {}
3030

3131
extension type ET_Dynamic(dynamic it) implements dynamic /* Error */ {}
3232

33-
extension type ET_Void(Never it) implements void /* Error */ {}
33+
extension type ET_Void(Null it) implements void /* Error */ {}
3434

3535
extension type ET_Never(Never it) implements Never /* Error */ {}
3636

@@ -54,7 +54,7 @@ extension type ET_NullableExtensionType(int it)
5454
extension type ET_FutureOr(FutureOr<int> it)
5555
implements FutureOr<int> /* Error */ {}
5656

57-
extension type ET_Extension(Never it) implements Extension /* Error */ {}
57+
extension type ET_Extension(int it) implements Extension /* Error */ {}
5858

5959
extension type ET_TypeVariable<T>(T it) implements T /* Error */ {}
6060

pkg/front_end/testcases/extension_types/implement_all.dart.strong.expect

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/extension_types/implement_all.dart:33:45: Error: Type 'void' can't be used here.
5+
// pkg/front_end/testcases/extension_types/implement_all.dart:33:44: Error: Type 'void' can't be used here.
66
// Try removing 'void' keyword or replace it with 'var', 'final', or a type.
7-
// extension type ET_Void(Never it) implements void /* Error */ {}
8-
// ^^^^
7+
// extension type ET_Void(Null it) implements void /* Error */ {}
8+
// ^^^^
99
//
10-
// pkg/front_end/testcases/extension_types/implement_all.dart:33:45: Error: Type 'void' not found.
11-
// extension type ET_Void(Never it) implements void /* Error */ {}
12-
// ^^^^
10+
// pkg/front_end/testcases/extension_types/implement_all.dart:33:44: Error: Type 'void' not found.
11+
// extension type ET_Void(Null it) implements void /* Error */ {}
12+
// ^^^^
1313
//
14-
// pkg/front_end/testcases/extension_types/implement_all.dart:57:50: Error: 'Extension' isn't a type.
15-
// extension type ET_Extension(Never it) implements Extension /* Error */ {}
16-
// ^^^^^^^^^
14+
// pkg/front_end/testcases/extension_types/implement_all.dart:57:48: Error: 'Extension' isn't a type.
15+
// extension type ET_Extension(int it) implements Extension /* Error */ {}
16+
// ^^^^^^^^^
1717
//
1818
// pkg/front_end/testcases/extension_types/implement_all.dart:29:44: Error: The type 'Null' can't be implemented by an extension type.
1919
// extension type ET_Null(Null it) implements Null /* Error */ {}
@@ -23,14 +23,18 @@ library;
2323
// extension type ET_Dynamic(dynamic it) implements dynamic /* Error */ {}
2424
// ^
2525
//
26-
// pkg/front_end/testcases/extension_types/implement_all.dart:33:45: Error: The type 'void' can't be implemented by an extension type.
27-
// extension type ET_Void(Never it) implements void /* Error */ {}
28-
// ^
26+
// pkg/front_end/testcases/extension_types/implement_all.dart:33:44: Error: The type 'void' can't be implemented by an extension type.
27+
// extension type ET_Void(Null it) implements void /* Error */ {}
28+
// ^
2929
//
3030
// pkg/front_end/testcases/extension_types/implement_all.dart:35:46: Error: The type 'Never' can't be implemented by an extension type.
3131
// extension type ET_Never(Never it) implements Never /* Error */ {}
3232
// ^
3333
//
34+
// pkg/front_end/testcases/extension_types/implement_all.dart:35:31: Error: The representation type can't be a bottom type.
35+
// extension type ET_Never(Never it) implements Never /* Error */ {}
36+
// ^^
37+
//
3438
// pkg/front_end/testcases/extension_types/implement_all.dart:37:48: Error: The type 'Object' can't be implemented by an extension type.
3539
// extension type ET_Object(Object it) implements Object /* Error */ {}
3640
// ^
@@ -75,9 +79,9 @@ library;
7579
// implements FutureOr<int> /* Error */ {}
7680
// ^
7781
//
78-
// pkg/front_end/testcases/extension_types/implement_all.dart:57:50: Error: The type 'Extension' can't be implemented by an extension type.
79-
// extension type ET_Extension(Never it) implements Extension /* Error */ {}
80-
// ^
82+
// pkg/front_end/testcases/extension_types/implement_all.dart:57:48: Error: The type 'Extension' can't be implemented by an extension type.
83+
// extension type ET_Extension(int it) implements Extension /* Error */ {}
84+
// ^
8185
//
8286
// pkg/front_end/testcases/extension_types/implement_all.dart:59:52: Error: The type variable 'T' can't be implemented by an extension type.
8387
// extension type ET_TypeVariable<T>(T it) implements T /* Error */ {}
@@ -126,12 +130,12 @@ extension type ET_Dynamic(dynamic it) {
126130
constructor • = self::ET_Dynamic|constructor#;
127131
constructor tearoff • = self::ET_Dynamic|constructor#_#new#tearOff;
128132
}
129-
extension type ET_Void(Never it) {
130-
abstract inline-class-member representation-field get it() → Never;
133+
extension type ET_Void(Null it) {
134+
abstract inline-class-member representation-field get it() → Null;
131135
constructor • = self::ET_Void|constructor#;
132136
constructor tearoff • = self::ET_Void|constructor#_#new#tearOff;
133137
}
134-
extension type ET_Never(Never it) {
138+
extension type ET_Never(invalid-type it) {
135139
abstract inline-class-member representation-field get it() → Never;
136140
constructor • = self::ET_Never|constructor#;
137141
constructor tearoff • = self::ET_Never|constructor#_#new#tearOff;
@@ -176,8 +180,8 @@ extension type ET_FutureOr(FutureOr<core::int>it) {
176180
constructor • = self::ET_FutureOr|constructor#;
177181
constructor tearoff • = self::ET_FutureOr|constructor#_#new#tearOff;
178182
}
179-
extension type ET_Extension(Never it) {
180-
abstract inline-class-member representation-field get it() → Never;
183+
extension type ET_Extension(core::int it) {
184+
abstract inline-class-member representation-field get it() → core::int;
181185
constructor • = self::ET_Extension|constructor#;
182186
constructor tearoff • = self::ET_Extension|constructor#_#new#tearOff;
183187
}
@@ -240,17 +244,17 @@ static inline-class-member method ET_Dynamic|constructor#(dynamic it) → self::
240244
}
241245
static inline-class-member method ET_Dynamic|constructor#_#new#tearOff(dynamic it) → self::ET_Dynamic /* = dynamic */
242246
return self::ET_Dynamic|constructor#(it);
243-
static inline-class-member method ET_Void|constructor#(Never it) → self::ET_Void /* = Never */ {
244-
lowered final self::ET_Void /* = Never */ #this = it;
247+
static inline-class-member method ET_Void|constructor#(Null it) → self::ET_Void /* = Null */ {
248+
lowered final self::ET_Void /* = Null */ #this = it;
245249
return #this;
246250
}
247-
static inline-class-member method ET_Void|constructor#_#new#tearOff(Never it) → self::ET_Void /* = Never */
251+
static inline-class-member method ET_Void|constructor#_#new#tearOff(Null it) → self::ET_Void /* = Null */
248252
return self::ET_Void|constructor#(it);
249-
static inline-class-member method ET_Never|constructor#(Never it) → self::ET_Never /* = Never */ {
250-
lowered final self::ET_Never /* = Never */ #this = it;
253+
static inline-class-member method ET_Never|constructor#(Never it) → self::ET_Never /* = invalid-type */ {
254+
lowered final self::ET_Never /* = invalid-type */ #this = it;
251255
return #this;
252256
}
253-
static inline-class-member method ET_Never|constructor#_#new#tearOff(Never it) → self::ET_Never /* = Never */
257+
static inline-class-member method ET_Never|constructor#_#new#tearOff(Never it) → self::ET_Never /* = invalid-type */
254258
return self::ET_Never|constructor#(it);
255259
static inline-class-member method ET_Object|constructor#(core::Object it) → self::ET_Object /* = core::Object */ {
256260
lowered final self::ET_Object /* = core::Object */ #this = it;
@@ -300,10 +304,10 @@ static inline-class-member method ET_FutureOr|constructor#(FutureOr<core::int>it
300304
}
301305
static inline-class-member method ET_FutureOr|constructor#_#new#tearOff(FutureOr<core::int>it) → self::ET_FutureOr /* = FutureOr<core::int>*/
302306
return self::ET_FutureOr|constructor#(it);
303-
static inline-class-member method ET_Extension|constructor#_#new#tearOff(Never it) → self::ET_Extension /* = Never */
307+
static inline-class-member method ET_Extension|constructor#_#new#tearOff(core::int it) → self::ET_Extension /* = core::int */
304308
return self::ET_Extension|constructor#(it);
305-
static inline-class-member method ET_Extension|constructor#(Never it) → self::ET_Extension /* = Never */ {
306-
lowered final self::ET_Extension /* = Never */ #this = it;
309+
static inline-class-member method ET_Extension|constructor#(core::int it) → self::ET_Extension /* = core::int */ {
310+
lowered final self::ET_Extension /* = core::int */ #this = it;
307311
return #this;
308312
}
309313
static inline-class-member method ET_TypeVariable|constructor#<T extends core::Object? = dynamic>(self::ET_TypeVariable|constructor#::T% it) → self::ET_TypeVariable<self::ET_TypeVariable|constructor#::T%> /* = self::ET_TypeVariable|constructor#::T% */ {

pkg/front_end/testcases/extension_types/implement_all.dart.strong.transformed.expect

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ library;
22
//
33
// Problems in library:
44
//
5-
// pkg/front_end/testcases/extension_types/implement_all.dart:33:45: Error: Type 'void' can't be used here.
5+
// pkg/front_end/testcases/extension_types/implement_all.dart:33:44: Error: Type 'void' can't be used here.
66
// Try removing 'void' keyword or replace it with 'var', 'final', or a type.
7-
// extension type ET_Void(Never it) implements void /* Error */ {}
8-
// ^^^^
7+
// extension type ET_Void(Null it) implements void /* Error */ {}
8+
// ^^^^
99
//
10-
// pkg/front_end/testcases/extension_types/implement_all.dart:33:45: Error: Type 'void' not found.
11-
// extension type ET_Void(Never it) implements void /* Error */ {}
12-
// ^^^^
10+
// pkg/front_end/testcases/extension_types/implement_all.dart:33:44: Error: Type 'void' not found.
11+
// extension type ET_Void(Null it) implements void /* Error */ {}
12+
// ^^^^
1313
//
14-
// pkg/front_end/testcases/extension_types/implement_all.dart:57:50: Error: 'Extension' isn't a type.
15-
// extension type ET_Extension(Never it) implements Extension /* Error */ {}
16-
// ^^^^^^^^^
14+
// pkg/front_end/testcases/extension_types/implement_all.dart:57:48: Error: 'Extension' isn't a type.
15+
// extension type ET_Extension(int it) implements Extension /* Error */ {}
16+
// ^^^^^^^^^
1717
//
1818
// pkg/front_end/testcases/extension_types/implement_all.dart:29:44: Error: The type 'Null' can't be implemented by an extension type.
1919
// extension type ET_Null(Null it) implements Null /* Error */ {}
@@ -23,14 +23,18 @@ library;
2323
// extension type ET_Dynamic(dynamic it) implements dynamic /* Error */ {}
2424
// ^
2525
//
26-
// pkg/front_end/testcases/extension_types/implement_all.dart:33:45: Error: The type 'void' can't be implemented by an extension type.
27-
// extension type ET_Void(Never it) implements void /* Error */ {}
28-
// ^
26+
// pkg/front_end/testcases/extension_types/implement_all.dart:33:44: Error: The type 'void' can't be implemented by an extension type.
27+
// extension type ET_Void(Null it) implements void /* Error */ {}
28+
// ^
2929
//
3030
// pkg/front_end/testcases/extension_types/implement_all.dart:35:46: Error: The type 'Never' can't be implemented by an extension type.
3131
// extension type ET_Never(Never it) implements Never /* Error */ {}
3232
// ^
3333
//
34+
// pkg/front_end/testcases/extension_types/implement_all.dart:35:31: Error: The representation type can't be a bottom type.
35+
// extension type ET_Never(Never it) implements Never /* Error */ {}
36+
// ^^
37+
//
3438
// pkg/front_end/testcases/extension_types/implement_all.dart:37:48: Error: The type 'Object' can't be implemented by an extension type.
3539
// extension type ET_Object(Object it) implements Object /* Error */ {}
3640
// ^
@@ -75,9 +79,9 @@ library;
7579
// implements FutureOr<int> /* Error */ {}
7680
// ^
7781
//
78-
// pkg/front_end/testcases/extension_types/implement_all.dart:57:50: Error: The type 'Extension' can't be implemented by an extension type.
79-
// extension type ET_Extension(Never it) implements Extension /* Error */ {}
80-
// ^
82+
// pkg/front_end/testcases/extension_types/implement_all.dart:57:48: Error: The type 'Extension' can't be implemented by an extension type.
83+
// extension type ET_Extension(int it) implements Extension /* Error */ {}
84+
// ^
8185
//
8286
// pkg/front_end/testcases/extension_types/implement_all.dart:59:52: Error: The type variable 'T' can't be implemented by an extension type.
8387
// extension type ET_TypeVariable<T>(T it) implements T /* Error */ {}
@@ -126,12 +130,12 @@ extension type ET_Dynamic(dynamic it) {
126130
constructor • = self::ET_Dynamic|constructor#;
127131
constructor tearoff • = self::ET_Dynamic|constructor#_#new#tearOff;
128132
}
129-
extension type ET_Void(Never it) {
130-
abstract inline-class-member representation-field get it() → Never;
133+
extension type ET_Void(Null it) {
134+
abstract inline-class-member representation-field get it() → Null;
131135
constructor • = self::ET_Void|constructor#;
132136
constructor tearoff • = self::ET_Void|constructor#_#new#tearOff;
133137
}
134-
extension type ET_Never(Never it) {
138+
extension type ET_Never(invalid-type it) {
135139
abstract inline-class-member representation-field get it() → Never;
136140
constructor • = self::ET_Never|constructor#;
137141
constructor tearoff • = self::ET_Never|constructor#_#new#tearOff;
@@ -176,8 +180,8 @@ extension type ET_FutureOr(FutureOr<core::int>it) {
176180
constructor • = self::ET_FutureOr|constructor#;
177181
constructor tearoff • = self::ET_FutureOr|constructor#_#new#tearOff;
178182
}
179-
extension type ET_Extension(Never it) {
180-
abstract inline-class-member representation-field get it() → Never;
183+
extension type ET_Extension(core::int it) {
184+
abstract inline-class-member representation-field get it() → core::int;
181185
constructor • = self::ET_Extension|constructor#;
182186
constructor tearoff • = self::ET_Extension|constructor#_#new#tearOff;
183187
}
@@ -240,17 +244,17 @@ static inline-class-member method ET_Dynamic|constructor#(dynamic it) → self::
240244
}
241245
static inline-class-member method ET_Dynamic|constructor#_#new#tearOff(dynamic it) → self::ET_Dynamic /* = dynamic */
242246
return self::ET_Dynamic|constructor#(it);
243-
static inline-class-member method ET_Void|constructor#(Never it) → self::ET_Void /* = Never */ {
244-
lowered final self::ET_Void /* = Never */ #this = it;
247+
static inline-class-member method ET_Void|constructor#(Null it) → self::ET_Void /* = Null */ {
248+
lowered final self::ET_Void /* = Null */ #this = it;
245249
return #this;
246250
}
247-
static inline-class-member method ET_Void|constructor#_#new#tearOff(Never it) → self::ET_Void /* = Never */
251+
static inline-class-member method ET_Void|constructor#_#new#tearOff(Null it) → self::ET_Void /* = Null */
248252
return self::ET_Void|constructor#(it);
249-
static inline-class-member method ET_Never|constructor#(Never it) → self::ET_Never /* = Never */ {
250-
lowered final self::ET_Never /* = Never */ #this = it;
253+
static inline-class-member method ET_Never|constructor#(Never it) → self::ET_Never /* = invalid-type */ {
254+
lowered final self::ET_Never /* = invalid-type */ #this = it;
251255
return #this;
252256
}
253-
static inline-class-member method ET_Never|constructor#_#new#tearOff(Never it) → self::ET_Never /* = Never */
257+
static inline-class-member method ET_Never|constructor#_#new#tearOff(Never it) → self::ET_Never /* = invalid-type */
254258
return self::ET_Never|constructor#(it);
255259
static inline-class-member method ET_Object|constructor#(core::Object it) → self::ET_Object /* = core::Object */ {
256260
lowered final self::ET_Object /* = core::Object */ #this = it;
@@ -300,10 +304,10 @@ static inline-class-member method ET_FutureOr|constructor#(FutureOr<core::int>it
300304
}
301305
static inline-class-member method ET_FutureOr|constructor#_#new#tearOff(FutureOr<core::int>it) → self::ET_FutureOr /* = FutureOr<core::int>*/
302306
return self::ET_FutureOr|constructor#(it);
303-
static inline-class-member method ET_Extension|constructor#_#new#tearOff(Never it) → self::ET_Extension /* = Never */
307+
static inline-class-member method ET_Extension|constructor#_#new#tearOff(core::int it) → self::ET_Extension /* = core::int */
304308
return self::ET_Extension|constructor#(it);
305-
static inline-class-member method ET_Extension|constructor#(Never it) → self::ET_Extension /* = Never */ {
306-
lowered final self::ET_Extension /* = Never */ #this = it;
309+
static inline-class-member method ET_Extension|constructor#(core::int it) → self::ET_Extension /* = core::int */ {
310+
lowered final self::ET_Extension /* = core::int */ #this = it;
307311
return #this;
308312
}
309313
static inline-class-member method ET_TypeVariable|constructor#<T extends core::Object? = dynamic>(self::ET_TypeVariable|constructor#::T% it) → self::ET_TypeVariable<self::ET_TypeVariable|constructor#::T%> /* = self::ET_TypeVariable|constructor#::T% */ {

pkg/front_end/testcases/extension_types/implement_all.dart.textual_outline.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ extension type ExtensionType(int it) {}
1212
extension type GenericExtensionType<T>(T it) {}
1313
extension type ET_Null(Null it) implements Null {}
1414
extension type ET_Dynamic(dynamic it) implements dynamic {}
15-
extension type ET_Void(Never it) implements void {}
15+
extension type ET_Void(Null it) implements void {}
1616
extension type ET_Never(Never it) implements Never {}
1717
extension type ET_Object(Object it) implements Object {}
1818
extension type ET_Record(Record it) implements Record {}
@@ -22,7 +22,7 @@ extension type ET_FunctionType(FunctionType it) implements FunctionType {}
2222
extension type ET_NullableInterfaceType(NullableInterfaceType it) implements NullableInterfaceType {}
2323
extension type ET_NullableExtensionType(int it) implements NullableExtensionType {}
2424
extension type ET_FutureOr(FutureOr<int> it) implements FutureOr<int> {}
25-
extension type ET_Extension(Never it) implements Extension {}
25+
extension type ET_Extension(int it) implements Extension {}
2626
extension type ET_TypeVariable<T>(T it) implements T {}
2727
extension type ET_Class(Class it) implements Class {}
2828
extension type ET_GenericClass<T>(GenericClass<T> it) implements GenericClass<T> {}

0 commit comments

Comments
 (0)