Skip to content
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

Implicit cast-and-construct from dynamic to extension type? #3369

Closed
srawlins opened this issue Sep 26, 2023 · 3 comments
Closed

Implicit cast-and-construct from dynamic to extension type? #3369

srawlins opened this issue Sep 26, 2023 · 3 comments

Comments

@srawlins
Copy link
Member

The (only?) implicit cast we have left (I think I'm not including coersions...) is "from dynamic to anything". So in this code:

extension type E(int it) {}

void main() {
  dynamic i = 7;
  E j = i;
}

Is this legal? Does i get implicitly cast to E which invokes E's primary constructor? I think this is all expected and fine, but it's not really spelled out in the spec, I think.

CC @eernstg

@srawlins srawlins added question Further information is requested extension-types and removed question Further information is requested labels Sep 26, 2023
@eernstg
Copy link
Member

eernstg commented Sep 26, 2023

Yes, I would expect E j = i; to be accepted without errors. At run time it would check that i is an int (and it wouldn't do anything beyond that).

I think it's fair to say that this treatment is covered by the existing specification of assignability, so there shouldn't be a need to put anything into the extension type specification about it.

However, I would also hope that this initialization could be flagged by a lint saying that a cast to an extension type is a questionable action (cf. dart-lang/sdk#58838).

@lrhn
Copy link
Member

lrhn commented Sep 26, 2023

extension type E(int it) {}

void main() {
 dynamic i = 7;
 E j = i;
}

Is this legal?

Yes.

Does i get implicitly cast to E

Yes.
After type inference, this should be equivalent to:

 extension type E(int it) {}
 void main() {
   dynamic i = 7;
   E j = i as E; // Implicit downcast from dynamic to context type.
}

There is an implicit downcast from dynamic to the non-top context type, like always.
It doesn't matter that the context type is an extension type.

which invokes E's primary constructor?

No. It just gets cast.

Casts are runtime operations. At runtime, extension types do not exist. They're completely gone, replaced by their representation type.

The code that actually runs will be:

void main() {
  dynamic /*aka Object?*/ i = 7;
  int j = i as int;
}

I think this is all expected and fine, but it's not really spelled out in the spec, I think.

I think it is. It might be implicit, because it is a consequence of the interaction of how extension types work at compile-time and at runtime, and completely standard behavior.

  • Implicit downcasts do not care about extension types. They will downcast to any type.
  • Casts to extension types happen at runtime where it will be a cast to the representation type.

@srawlins
Copy link
Member Author

Thanks! Filed dart-lang/sdk#59310

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants