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

Implicitly tear off call from receiver whose type is a type variable #54351

Closed
eernstg opened this issue Dec 14, 2023 · 6 comments
Closed

Implicitly tear off call from receiver whose type is a type variable #54351

eernstg opened this issue Dec 14, 2023 · 6 comments
Labels
area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...). type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@eernstg
Copy link
Member

eernstg commented Dec 14, 2023

Thanks to @johnniwinther for noticing this. Consider the following program:

class A {
  void call() {}
}

Function f<X extends A>(X x) => x;

void main() {
  print(f(A()));
}

This program is rejected by the analyzer as well as the common front end (DartPad based on SDK 3.3.0-213.0.dev). However, the interface of a receiver of type X is the interface of the bound A, which implies that the interface of x does include a method named call, which means that we should be able to tear it off implicitly when the context type is Function or a function type.

The missing support for call is concerned with implicit tear-offs only, the implicit insertion of call that enables an invocation is working in the analyzer as well as the CFE.

@eernstg eernstg added area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...). type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Dec 14, 2023
@johnniwinther
Copy link
Member

Should we also handle access of call on record types?

  var r = (call: () {},);
  Function f = r; // = r.call ?
  r(); // = r.call() ?

@eernstg
Copy link
Member Author

eernstg commented Dec 15, 2023

I do not think we should support an implicit invocation of a call getter on a record type based on a context type mismatch: The corresponding situation with a receiver whose static type is a class that has a call getter is a compile-time error.

@johnniwinther
Copy link
Member

So we still restrict this to finding a call method on the underlying interface? I can see the CFE doesn't allow the found call member to be a getter/field.

@eernstg
Copy link
Member Author

eernstg commented Dec 15, 2023

method

Yes. It is highly likely that support for call method tear-off will be removed from the language in the future. However, the language team ended up keeping call method tear-offs for now, and even adding it for extension typed receivers in dart-lang/language#3467 (because it would be an odd exception if we hadn't done that).

On the other hand, there's no reason to start introducing support for statically resolved implicit call getter invocation—there is nothing else to be consistent with.

We do have a somewhat similar situation with dynamic calls where implicit call getter invocations do occur with the current implementations, but I still think we should stick to the specified behavior for the statically resolved case. This will also keep the situation at the same level of trade-offs in dart-lang/language#3482, rather than pushing the balance in any specific direction.

@srawlins
Copy link
Member

I think both front-ends have landed a fix. OK to close, @eernstg ?

@eernstg
Copy link
Member Author

eernstg commented Jan 22, 2024

Sounds good, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...). type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

3 participants