-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enum mixin not used as runtime Type #51730
Comments
Which compiler gives the error? (The error itself seems correct, a value of type Can you show the code which causes the error? My own attempts on dartpad.dev shows no problem. For example (I'd use |
@lrhn Here's the example: import 'dart:math';
mixin LinkEnum on Enum {
String get link;
}
enum GitWebsites implements LinkEnum {
google('bitbucket.org'),
github('github.com');
const GitWebsites(this.link);
final String link;
}
enum SearchWebsites implements LinkEnum {
google('google.com'),
github('bing.com');
const SearchWebsites(this.link);
final String link;
}
void main() {
final randomNumberGenerator = Random();
final condition = randomNumberGenerator.nextBool();
final link = (condition ? GitWebsites.values : SearchWebsites.values)
.map((e) => e.link);
final allWebsites = [...GitWebsites.values, ...SearchWebsites.values];
final allLinks = allWebsites.map((e) => e.link);
}
Edited with a more complete example |
That does look like an inconsistency between analyzer and front-end. A simpler example: void main(List<String> args) {
var rnd = DateTime.now().millisecondsSinceEpoch.isEven;
// LUB of `E1`, `E2`.
//
// Type hierarchy used by analyzer/front-end
//
// Object or Object
// | |
// Enum Enum
// | / \
// Inf _Enum Inf
// | \ /
// E1, E2 E1, E2
//
var o = rnd ? E1.e1 : E2.e2;
print(o.staticType);
o.expectStaticType<Exactly<Enum>>(); // Successful on front-end
// o.expectStaticType<Exactly<Inf>>(); // Successful on analyzer
}
abstract class Inf implements Enum {
int get i;
}
enum E1 implements Inf {
e1;
int get i => 1;
}
enum E2 implements Inf {
e2;
int get i => 2;
}
// Check static type.
extension <T> on T {
Type get staticType => T;
T expectStaticType<R extends Exactly<T>>() {
return this;
}
}
typedef Exactly<T> = T Function(T); This is actually correct and expected behavior for our LUB (least upper bound) operation when presented with two different type hierarchies. And why our LUB is sometimes completely unpredictable. If I remove the So, the issue is that the analyzer and the front-end are working on different type hierarchies, because the analyzer doesn't include the internal I'm not sure what to do. Pretending |
It sounds like this is a language issue? Analyzer team should not take action until a language decision is made. |
This is a consistency issue. That doesn't mean that we can't choose to make the compilers work differently. Currently there is an But currently it's there, and is a superclass of (It does mean that changing whether we have the |
Why don't we? |
It was never an issue before, and it provided an easy way to introduce the And it shouldn't be an issue that a class has a private superclass somewhere that nobody can directly access. |
@eernstg I think you just closed an issue similar to this that was based on a language decision. Is this now resolved as well? |
Good catch, @srawlins! The language team has decided that the analyzer should take The specification update occurs in dart-lang/language#3671, and it will be implemented soon. |
When we have an Enum class that implements a mixin, the analyzer will accept any uses of that enum as it would any class, but when tried to run the code, the compiler will complain something along the lines of
Error: A value of type 'Enum?' can't be assigned to a variable of type 'LinkEnum?'.
Even if the variable was originally of LinkEnum,
Casting the variable to LinkEnum works, but raises an
unnecessary_cast
warning.Example code below:
Dart SDK version: 2.18.4 (stable) (Tue Nov 1 15:15:07 2022 +0000) on "macos_arm64"
The text was updated successfully, but these errors were encountered: