-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[cfe] Ensure reporting all supertype conflicts in extension types
Closes #53799 Part of #49731 Change-Id: Ic273541973de6377bb376f51850ec3d7d114c764 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/334180 Commit-Queue: Chloe Stefantsova <cstefantsova@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
- Loading branch information
1 parent
de7e3b7
commit 2ea55d4
Showing
16 changed files
with
1,234 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
class A<X> {} | ||
class B<X> extends A<X> {} | ||
class C extends A<String> {} | ||
extension type E<X>(X it) {} | ||
|
||
extension type E1(A<Never> it) implements A<String>, A<int> {} // Error. | ||
|
||
extension type E2(B<Never> it) implements B<String>, A<double> {} // Error. | ||
|
||
extension type E3(C it) implements C, A<num> {} // Error. | ||
|
||
extension type E41(A<Never> it) implements A<String> {} | ||
extension type E42(A<Never> it) implements E41, A<int> {} // Error. | ||
|
||
extension type E5(E<Never> it) implements E<String>, E<bool> {} // Error. | ||
|
||
extension type E61(E<Never> it) implements E<num> {} | ||
extension type E62(E<Never> it) implements E61, E<String> {} // Error. | ||
|
||
extension type E71(E<Never> it) implements E<double> {} | ||
extension type E72(E<Never> it) implements E<bool> {} | ||
extension type E73(E<Never> it) implements E71, E72 {} // Error. |
193 changes: 193 additions & 0 deletions
193
pkg/front_end/testcases/extension_types/issue53799.dart.strong.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
library; | ||
// | ||
// Problems in library: | ||
// | ||
// pkg/front_end/testcases/extension_types/issue53799.dart:10:16: Error: 'E1' can't implement both 'A<String>' and 'A<int>' | ||
// - 'A' is from 'pkg/front_end/testcases/extension_types/issue53799.dart'. | ||
// extension type E1(A<Never> it) implements A<String>, A<int> {} // Error. | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/extension_types/issue53799.dart:12:16: Error: 'E2' can't implement both 'A<String>' and 'A<double>' | ||
// - 'A' is from 'pkg/front_end/testcases/extension_types/issue53799.dart'. | ||
// extension type E2(B<Never> it) implements B<String>, A<double> {} // Error. | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/extension_types/issue53799.dart:14:16: Error: 'E3' can't implement both 'A<String>' and 'A<num>' | ||
// - 'A' is from 'pkg/front_end/testcases/extension_types/issue53799.dart'. | ||
// extension type E3(C it) implements C, A<num> {} // Error. | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/extension_types/issue53799.dart:17:16: Error: 'E42' can't implement both 'A<String>' and 'A<int>' | ||
// - 'A' is from 'pkg/front_end/testcases/extension_types/issue53799.dart'. | ||
// extension type E42(A<Never> it) implements E41, A<int> {} // Error. | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/extension_types/issue53799.dart:19:16: Error: 'E5' can't implement both 'E<String>' and 'E<bool>' | ||
// extension type E5(E<Never> it) implements E<String>, E<bool> {} // Error. | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/extension_types/issue53799.dart:22:16: Error: 'E62' can't implement both 'E<num>' and 'E<String>' | ||
// extension type E62(E<Never> it) implements E61, E<String> {} // Error. | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/extension_types/issue53799.dart:26:16: Error: 'E73' can't implement both 'E<double>' and 'E<bool>' | ||
// extension type E73(E<Never> it) implements E71, E72 {} // Error. | ||
// ^ | ||
// | ||
// pkg/front_end/testcases/extension_types/issue53799.dart:14:39: Error: The implemented interface 'A<num>' must be a supertype of the representation type 'C' of extension type 'E3'. | ||
// - 'A' is from 'pkg/front_end/testcases/extension_types/issue53799.dart'. | ||
// - 'C' is from 'pkg/front_end/testcases/extension_types/issue53799.dart'. | ||
// Try changing the interface type to a supertype of 'C' or the representation type to a subtype of 'A<num>'. | ||
// extension type E3(C it) implements C, A<num> {} // Error. | ||
// ^ | ||
// | ||
import self as self; | ||
import "dart:core" as core; | ||
|
||
class A<X extends core::Object? = dynamic> extends core::Object { | ||
synthetic constructor •() → self::A<self::A::X%> | ||
: super core::Object::•() | ||
; | ||
} | ||
class B<X extends core::Object? = dynamic> extends self::A<self::B::X%> { | ||
synthetic constructor •() → self::B<self::B::X%> | ||
: super self::A::•() | ||
; | ||
} | ||
class C extends self::A<core::String> { | ||
synthetic constructor •() → self::C | ||
: super self::A::•() | ||
; | ||
} | ||
extension type E<X extends core::Object? = dynamic>(X% it) { | ||
abstract inline-class-member representation-field get it() → X%; | ||
constructor • = self::E|constructor#; | ||
constructor tearoff • = self::E|constructor#_#new#tearOff; | ||
} | ||
extension type E1(self::A<Never> it) implements self::A<core::String>, self::A<core::int> { | ||
abstract inline-class-member representation-field get it() → self::A<Never>; | ||
constructor • = self::E1|constructor#; | ||
constructor tearoff • = self::E1|constructor#_#new#tearOff; | ||
} | ||
extension type E2(self::B<Never> it) implements self::B<core::String>, self::A<core::double> { | ||
abstract inline-class-member representation-field get it() → self::B<Never>; | ||
constructor • = self::E2|constructor#; | ||
constructor tearoff • = self::E2|constructor#_#new#tearOff; | ||
} | ||
extension type E3(self::C it) implements self::C, self::A<core::num> { | ||
abstract inline-class-member representation-field get it() → self::C; | ||
constructor • = self::E3|constructor#; | ||
constructor tearoff • = self::E3|constructor#_#new#tearOff; | ||
} | ||
extension type E41(self::A<Never> it) implements self::A<core::String> { | ||
abstract inline-class-member representation-field get it() → self::A<Never>; | ||
constructor • = self::E41|constructor#; | ||
constructor tearoff • = self::E41|constructor#_#new#tearOff; | ||
} | ||
extension type E42(self::A<Never> it) implements self::E41 /* = self::A<Never> */, self::A<core::int> { | ||
abstract inline-class-member representation-field get it() → self::A<Never>; | ||
constructor • = self::E42|constructor#; | ||
constructor tearoff • = self::E42|constructor#_#new#tearOff; | ||
} | ||
extension type E5(self::E<Never> /* = Never */ it) implements self::E<core::String> /* = core::String */, self::E<core::bool> /* = core::bool */ { | ||
abstract inline-class-member representation-field get it() → self::E<Never> /* = Never */; | ||
constructor • = self::E5|constructor#; | ||
constructor tearoff • = self::E5|constructor#_#new#tearOff; | ||
} | ||
extension type E61(self::E<Never> /* = Never */ it) implements self::E<core::num> /* = core::num */ { | ||
abstract inline-class-member representation-field get it() → self::E<Never> /* = Never */; | ||
constructor • = self::E61|constructor#; | ||
constructor tearoff • = self::E61|constructor#_#new#tearOff; | ||
} | ||
extension type E62(self::E<Never> /* = Never */ it) implements self::E61 /* = Never */, self::E<core::String> /* = core::String */ { | ||
abstract inline-class-member representation-field get it() → self::E<Never> /* = Never */; | ||
constructor • = self::E62|constructor#; | ||
constructor tearoff • = self::E62|constructor#_#new#tearOff; | ||
} | ||
extension type E71(self::E<Never> /* = Never */ it) implements self::E<core::double> /* = core::double */ { | ||
abstract inline-class-member representation-field get it() → self::E<Never> /* = Never */; | ||
constructor • = self::E71|constructor#; | ||
constructor tearoff • = self::E71|constructor#_#new#tearOff; | ||
} | ||
extension type E72(self::E<Never> /* = Never */ it) implements self::E<core::bool> /* = core::bool */ { | ||
abstract inline-class-member representation-field get it() → self::E<Never> /* = Never */; | ||
constructor • = self::E72|constructor#; | ||
constructor tearoff • = self::E72|constructor#_#new#tearOff; | ||
} | ||
extension type E73(self::E<Never> /* = Never */ it) implements self::E71 /* = Never */, self::E72 /* = Never */ { | ||
abstract inline-class-member representation-field get it() → self::E<Never> /* = Never */; | ||
constructor • = self::E73|constructor#; | ||
constructor tearoff • = self::E73|constructor#_#new#tearOff; | ||
} | ||
static inline-class-member method E|constructor#<X extends core::Object? = dynamic>(self::E|constructor#::X% it) → self::E<self::E|constructor#::X%> /* = self::E|constructor#::X% */ { | ||
lowered final self::E<self::E|constructor#::X%> /* = self::E|constructor#::X% */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E|constructor#_#new#tearOff<X extends core::Object? = dynamic>(self::E|constructor#_#new#tearOff::X% it) → self::E<self::E|constructor#_#new#tearOff::X%>% /* = self::E|constructor#_#new#tearOff::X% */ | ||
return self::E|constructor#<self::E|constructor#_#new#tearOff::X%>(it); | ||
static inline-class-member method E1|constructor#(self::A<Never> it) → self::E1 /* = self::A<Never> */ { | ||
lowered final self::E1 /* = self::A<Never> */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E1|constructor#_#new#tearOff(self::A<Never> it) → self::E1 /* = self::A<Never> */ | ||
return self::E1|constructor#(it); | ||
static inline-class-member method E2|constructor#(self::B<Never> it) → self::E2 /* = self::B<Never> */ { | ||
lowered final self::E2 /* = self::B<Never> */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E2|constructor#_#new#tearOff(self::B<Never> it) → self::E2 /* = self::B<Never> */ | ||
return self::E2|constructor#(it); | ||
static inline-class-member method E3|constructor#(self::C it) → self::E3 /* = self::C */ { | ||
lowered final self::E3 /* = self::C */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E3|constructor#_#new#tearOff(self::C it) → self::E3 /* = self::C */ | ||
return self::E3|constructor#(it); | ||
static inline-class-member method E41|constructor#(self::A<Never> it) → self::E41 /* = self::A<Never> */ { | ||
lowered final self::E41 /* = self::A<Never> */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E41|constructor#_#new#tearOff(self::A<Never> it) → self::E41 /* = self::A<Never> */ | ||
return self::E41|constructor#(it); | ||
static inline-class-member method E42|constructor#(self::A<Never> it) → self::E42 /* = self::A<Never> */ { | ||
lowered final self::E42 /* = self::A<Never> */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E42|constructor#_#new#tearOff(self::A<Never> it) → self::E42 /* = self::A<Never> */ | ||
return self::E42|constructor#(it); | ||
static inline-class-member method E5|constructor#(self::E<Never> /* = Never */ it) → self::E5 /* = Never */ { | ||
lowered final self::E5 /* = Never */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E5|constructor#_#new#tearOff(self::E<Never> /* = Never */ it) → self::E5 /* = Never */ | ||
return self::E5|constructor#(it); | ||
static inline-class-member method E61|constructor#(self::E<Never> /* = Never */ it) → self::E61 /* = Never */ { | ||
lowered final self::E61 /* = Never */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E61|constructor#_#new#tearOff(self::E<Never> /* = Never */ it) → self::E61 /* = Never */ | ||
return self::E61|constructor#(it); | ||
static inline-class-member method E62|constructor#(self::E<Never> /* = Never */ it) → self::E62 /* = Never */ { | ||
lowered final self::E62 /* = Never */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E62|constructor#_#new#tearOff(self::E<Never> /* = Never */ it) → self::E62 /* = Never */ | ||
return self::E62|constructor#(it); | ||
static inline-class-member method E71|constructor#(self::E<Never> /* = Never */ it) → self::E71 /* = Never */ { | ||
lowered final self::E71 /* = Never */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E71|constructor#_#new#tearOff(self::E<Never> /* = Never */ it) → self::E71 /* = Never */ | ||
return self::E71|constructor#(it); | ||
static inline-class-member method E72|constructor#(self::E<Never> /* = Never */ it) → self::E72 /* = Never */ { | ||
lowered final self::E72 /* = Never */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E72|constructor#_#new#tearOff(self::E<Never> /* = Never */ it) → self::E72 /* = Never */ | ||
return self::E72|constructor#(it); | ||
static inline-class-member method E73|constructor#(self::E<Never> /* = Never */ it) → self::E73 /* = Never */ { | ||
lowered final self::E73 /* = Never */ #this = it; | ||
return #this; | ||
} | ||
static inline-class-member method E73|constructor#_#new#tearOff(self::E<Never> /* = Never */ it) → self::E73 /* = Never */ | ||
return self::E73|constructor#(it); |
Oops, something went wrong.