-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Dart2JS and DDC differ in reified typedef signature #34429
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
This is a bug in DDC: #32785 ... they should be equal, as they are equivalent function types. Let me dig up my old branch with the fix and see what the status is of that branch. |
merging into the other bug. |
I was confused, the other bug is about I'll check the spec on In general, I would not recommend relying on For example once #32785 is fixed, I'd like to change DDC so it doesn't canonicalize all (non-typedef) function types. So |
Thanks! I wish we could 😢 Unfortunately we use That is, we want Dart2JS to always emit:
I think at minimum that will make DDC match the Dart2JS experience, which is important for us. From our perspective, we are evaluating either (a) banning using |
You may have to special case Type, and not just for typedefs/function types. Generic classes do not need to be identical either. In other words |
Just had another idea that might help you. If y'all need canonicalization, you could implement that on top of Type.==: final _injectionTypes = HashSet<Type>();
Type canonicalizeType(Type type) =>
_injectionTypes.add(type) ? type : _injectionTypes.lookup(type); The benefit of that is you have control over which Types to canonicalize, and can decide how to manage the GC issues. That way the canonicalization cost isn't imposed on all Types, only on those that really need it (e.g. for injection). It's a neat trick for speeding up |
One extra confusing point for Dart2JS. The following triggers an error in analyzer: void main() {
// ERROR: Two keys in a map literal can't be equal.
print(const {Fn1: 'Fn1', Fn2: 'Fn2'});
}
typedef Fn1 = String Function();
typedef Fn2 = String Function(); ... but Dart2JS executes this program fine, printing /cc @rakudrama @jmesserly - is this correct? |
@jmesserly wrote:
Yes, but the answer is actually not entirely obvious. There is one exception: 'A simple or qualified identifier denoting a class or type alias that is not qualified by a deferred prefix' is a constant expression and must be canonicalized. So But no such promises are made for other terms denoting types, e.g., Type typeOf<X>() => X;
main() {
print(typeOf<List<int>>() == typeOf<List<int>>()); // (1).
print(identical(typeOf<List<int>>(), typeOf<List<int>>())); // (2).
} However, I believe that the specification is silent on the expectations about equality (where I'd like to require cases like (1) to yield 'true') and We have language team support for #32782 ' Similarly, generalized-void.md specifies that
So it turns out that we haven't actually specified it completely yet, but the only approach that matches the cases where we get close is that we'd require equality based on the structure of types (so I've noted that we will probably need to clarify the spec on this topic. |
regarding:
That sounds like a bug, probably in the CFE. They haven't implemented all of the static checking for constants yet. |
@rakudrama, I suppose you changed this to 'area-language' because there is a need to clarify the rules? I created issue #34447 in order to get that done. So we may keep this as 'area-language' until #34447 has been resolved (with a language team decision), or we could mark this one as blocked on #34447, depending on how you'd usually handle such situations. |
@rakudrama, cf. my question in #34429 (comment), I'm removing 'area-language' from this issue. Please re-adjust if you prefer to handle it differently. Note that #34447 may be closed when this CL is landed. |
#34447 is now closed. |
Update: now that DDC behavior matches dart2js (identical for both cases) & Erik added the spec, can we close this? |
This is affecting prod customers for AngularDart internally, as the program works as intended during local development and in tests (DDC), and fails mysteriously in production (Dart2JS). Here is a minimal example showing this difference in behavior:
This seems to work-as-expected for DDC, but not Dart2JS.
Is this intended? If so, we'll need to ban
typedef
as being used as a dependency injection token-type in AngularDart, as it is dangerous to use. If this is fixable, then lets fix it! Let me know (this is P1 internally)./cc @rakudrama @vsmenon @jmesserly
The text was updated successfully, but these errors were encountered: