-
Notifications
You must be signed in to change notification settings - Fork 1.7k
inconsistencies in constants representations with CFE #32511
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
Comments
The type of Am I missing something? |
I'd say that the factory declaration ought to be a compile-time error because it will not satisfy the requirement that the factory returns an instance of the required type. Let's assume that the requirement is satisfied for all So the factory is unsafe in the sense that the actual type arguments passed to the However, the language specification does not make this an error (Dart 1 lingo: a static warning), it basically specifies that invocations of redirecting factories should be checked as if they had been desugared at the call site; so for This means that, in general, there is no reason to believe that That cannot be the intention, so we need to add some constraints on factories. We do have an update in the pipeline which will make it an error to violate redirecting (factory or not) constructor type annotations in an invocation, but we still do not cover anything which directly says "a redirecting factory constructor which passes actual type arguments to the redirectee constructor must do so in a way where every actual type argument list to the enclosing class which satisfies the type variable bounds must also satisfy the type variable bounds on the redirectee". I'd suggest that we assume the language specification will specify that a redirecting factory must return an object of the apparent type (e.g., @lrhn, @leafpetersen, do you agree that we will definitely end up having such a requirement? |
It's more than reasonable, it's essential. The static type of At the very least, the attempt to return a |
I think we should make unsafe redirection in a redirecting factory constructor a compile-time error at least when redirecting to a generative constructor: In that case the static type of the newly created object is known exactly from the redirection expression, so it's not just a downcast (or sidecast, the two types could be completely unrelated with today's treatment), it is a downcast which is statically guaranteed to fail every single time. Just like For a redirecting factory whose redirectee may return a subtype (say, it's redirecting to another redirecting factory and at some point to a regular factory) we could say that this is a regular downcast, it may or may not succeed, so we allow it (and prohibit it with |
Which is saying that we should treat it as a normal assignment. If the RHS is known exactly, we can make the guaranteed cast error into a compile-time error, otherwise (if redirecting to another factory constructor) we fall back on an implicit down-cast. We can choose to special-case chains of redirecting factory constructors, because we know that the value is unchanged along the chain, but it's probably not worth it. (Sorry about hijacking this issue, do go back to the regularly scheduled issue handling). |
I just made this issue part of the background material for the CL on checking redirections. |
Thanks for looking into this - I had not looked in detail at the inconsistencies of this example with 2.0 semantics (there are more in
The reason I filed this bug was that I noticed that dart2js has different representations for these constants when using its old front-end and when using the new front-end. Even in 2.0 valid code like: class A implements B { const A(); }
class B { const factory B() = A; } Dart2js shows differences. Here if you creating the constant |
@sigmundch - I moved this to Beta 3 (trying to delete the beta1 milestone). Is this still an open for dart2js? @lrhn - Is there a separate issue to file for the for the CFE here? Siggi's original example is a static error in Analyzer (assignability error) but allowed by CFE. I.e.. the following is a static error in DDC but just prints class A<T> implements B {}
class B<S> {
const factory B() = A<B<S>>;
}
void main() {
print(new B<int>() is B<int>);
} |
still relevant, beta3 sounds good |
The current specification seems to allow (or even mandate) that a redirecting constructor (factory or generative) must be considered as a syntactic shorthand for an invocation of the redirection target, with no checks applied statically or dynamically according to the declarations in the redirected constructor. So the following would be OK: class A { A(num n) { print(n); } A.foo(int i): this(i); } main() => new A.foo(3.0); This CL changes dartLangSpec.tex to mandate all the checks (static and dynamic) for the declaration of the redirecting constructor as well as each one of the redirection targets. Note that the analyzer already rejects the above program, which lessens the disruption and the implementation burden, but compilers would presumably need to have the dynamic checks implemented. Underlying issues: #31590, #32049, #32511. Change-Id: Icc15da6b817e4e678cdfc8829a1e06458756eb4b Reviewed-on: https://dart-review.googlesource.com/28140 Reviewed-by: Leaf Petersen <[email protected]> Reviewed-by: Lasse R.H. Nielsen <[email protected]>
The current specification seems to allow (or even mandate) that a redirecting constructor (factory or generative) must be considered as a syntactic shorthand for an invocation of the redirection target, with no checks applied statically or dynamically according to the declarations in the redirected constructor. So the following would be OK: class A { A(num n) { print(n); } A.foo(int i): this(i); } main() => new A.foo(3.0); This CL changes dartLangSpec.tex to mandate all the checks (static and dynamic) for the declaration of the redirecting constructor as well as each one of the redirection targets. Note that the analyzer already rejects the above program, which lessens the disruption and the implementation burden, but compilers would presumably need to have the dynamic checks implemented. Underlying issues: dart-lang/sdk#31590, dart-lang/sdk#32049, dart-lang/sdk#32511. Change-Id: Icc15da6b817e4e678cdfc8829a1e06458756eb4b Reviewed-on: https://dart-review.googlesource.com/28140 Reviewed-by: Leaf Petersen <[email protected]> Reviewed-by: Lasse R.H. Nielsen <[email protected]>
Dart2js with the new frontend produces a different representation of constants that:
Examples:
1 != 2
is represented as!(1 == 2)
with the CFEwith the following code,
const B<int>()
is represented asconst A<B<int>>
Some of these cases are seen in
tests/compiler/dart2js/model/constant_expression_test.dart
/cc @johnniwinther
The text was updated successfully, but these errors were encountered: