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

Generate checks at generic function instantiation with dynamically checked bound. #33726

Closed
eernstg opened this issue Jul 2, 2018 · 4 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). area-specification (deprecated) Deprecated: use area-language and a language- label.

Comments

@eernstg
Copy link
Member

eernstg commented Jul 2, 2018

Cf. the discussion in #31953: When a generic function is evaluated (as a tear-off, not as an invocation) in a context where (after inference, if any) the expected type is a non-generic function, generic function instantiation will take place. Please see the proposed feature specification for details.

That feature specification considers the situation where the inferred type argument list is not guaranteed to satisfy the declared bounds to be a compile-time error. However, as demonstrated by the discussion in #31953, it may be useful to accept such unsafe inferred type arguments in some cases, which brings up the question about when to fail in the case where the actual type argument list is indeed a bound violation.

We may produce the error at the location where the generic function instantiation takes place (considering that location to denote a tear-off operation which passes the type arguments), and we may produce the error at each invocation of the torn-off function (corresponding to an understanding of the generic instantiation as the implicit generation of a wrapper function).

The discussion in #31953 seems to have reached the conclusion that the former is preferable:@rakudrama said so here, @leafpetersen said 'lets go with an early (instantiation time) error for now' here, @lrhn said 'I prefer to check early' here. In the opposite direction, @sjindel-google argued here that it would require extra work in the VM to throw early.

This issue is concerned with making a decision in the language team to throw early or late.

@eernstg eernstg added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). area-specification (deprecated) Deprecated: use area-language and a language- label. labels Jul 2, 2018
@lrhn
Copy link
Member

lrhn commented Jul 11, 2018

Still voting for early errors unless someone has a concrete reason not to.
The extra code size only applies to tear-offs of generic methods with a class type parameter in the bound (either covariant or contravariant, I guess). Those cases should be rare and easily distinguishable.
The only issue could be that the check cannot be performed at the tear-off point because we don't actually have functionality to check a type argument against a bound without calling the method, and we'll have to add such code on all the classes with such methods.

I never remember how dynamic tear-offs work. They should not be doing type inference at run-time, so they probably shouldn't be affected.

@eernstg
Copy link
Member Author

eernstg commented Jul 11, 2018

Right, when a type argument list is expected, but missing at runtime (which means that a generic function was invoked dynamically and no type arguments were provided explicitly), the invocation must use a type argument list which is obtained using instantiate-to-bound.

That operation may fail (say, because we are calling void foo<X extends C<X>>() and instantiate-to-bound for X would produce a super-bounded type C<C<dynamic>>, and that type fails to satisfy the bound), but the failure can be detected at compile-time so we will simply need to set a flag on foo that it cannot be called dynamically without type arguments, and such invocations will then fail after argument evaluation. We won't need to worry about whether the actual arguments have suitable types (which would be hard anyway, because we don't know what a parameter type means if it contains a type variable that we just failed to choose an actual value for), because it's consistent with the left-to-right semantics of Dart to fail because of the "bad" type argument list.

@eernstg
Copy link
Member Author

eernstg commented Jul 11, 2018

I just noted that @leafpetersen said

My preference is to throw the error on instantiation [i.e., early]

as well, so I'll conclude that the language team has agreed on that, and land the above-mentioned feature specification and close this issue.

@eernstg
Copy link
Member Author

eernstg commented Jul 11, 2018

Closing: generic-function-instantiation.md was landed in b8098e9.

@eernstg eernstg closed this as completed Jul 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). area-specification (deprecated) Deprecated: use area-language and a language- label.
Projects
None yet
Development

No branches or pull requests

2 participants