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

instantiateToBounds sometimes fails to eliminate type parameters #27072

Closed
stereotype441 opened this issue Aug 12, 2016 · 8 comments
Closed

instantiateToBounds sometimes fails to eliminate type parameters #27072

stereotype441 opened this issue Aug 12, 2016 · 8 comments
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on

Comments

@stereotype441
Copy link
Member

stereotype441 commented Aug 12, 2016

When the following code snippet is analyzed in strong mode:

    class C<T extends C<T, U>, U extends num> {}
    C x;

The type of x is being instantiated to C<C<dynamic, U>, num>. This can't be right, since U is not in scope at the site of the declaration of x.

Reading through the code for StrongTypeSystemImpl.instantiateToBounds, it's not clear to me what the intended behavior is.

Note that if the order of generic args is reversed, i.e.:

    class C<S extends num, T extends C<S, T>> {}
    C x;

the type of x is instantiated to C<num, C<num, dynamic>>.

@stereotype441 stereotype441 added area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. analyzer-strong-mode labels Aug 12, 2016
@jmesserly jmesserly added P1 A high priority bug; for example, a single project is unusable or has many test failures P2 A bug or feature request we're likely to work on and removed P1 A high priority bug; for example, a single project is unusable or has many test failures labels Aug 15, 2016
@jmesserly
Copy link

ah it's a recursive bound. in general we don't handle those very well in strong mode.

@jmesserly
Copy link

Oh shoot. We had an (apparently incorrect) assumption that earlier type parameter bounds did not depend on later type parameters. But here the bound on T depends on U. Thoughts @leafpetersen ?

@leafpetersen
Copy link
Member

I had in mind that the F-bounded subtyping for strong mode would be ordered, rather than mutually recursive, in which case the initial example is broken code and should get an error.

This might be too restrictive - I'd like to consider supporting mutually recursive bounds. It covers some useful cases.

I also think I need to rethink the implicit instantiation logic - I am leaning towards just not allowing implicit instantiation for things with f-bounds. The answer you get there is almost never what you want.

@jmesserly
Copy link

I also think I need to rethink the implicit instantiation logic - I am leaning towards just not allowing implicit instantiation for things with f-bounds. The answer you get there is almost never what you want.

yeah, great idea.

another place this comes up is generic functions/methods, when the upper bounds can be the best result we get out of inference. Would we want to also disable inference in those cases?

@leafpetersen
Copy link
Member

Yeah, at least in the f-bounded case, I'm thinking that we should probably just ignore the bounds for inference. We could think about how to use them, but in general I don't think we can do so usefully. We may want to use them in the non-f-bounded case, but I think it's pretty marginal benefit.

scheglov added a commit that referenced this issue Oct 3, 2016
…e arguments.

There is internal code like the added test, which caused us to use
out of scope type parameter during inferred type computation.

Possibly related issues.
#26990
#27072

R=brianwilkerson@google.com, leafp@google.com, paulberry@google.com
BUG=

Review URL: https://codereview.chromium.org/2376213003 .
whesse pushed a commit that referenced this issue Oct 5, 2016
…e arguments.

There is internal code like the added test, which caused us to use
out of scope type parameter during inferred type computation.

Possibly related issues.
#26990
#27072

R=brianwilkerson@google.com, leafp@google.com, paulberry@google.com
BUG=

Review URL: https://codereview.chromium.org/2376213003 .
@MichaelRFairhurst
Copy link
Contributor

Question came to mind.

How is this being handled for cases like class Enum<E extends Enum<E>>?

In the case where you extend it you have to resolve the circular nature, ie, class IntEnum extends Enum<IntEnum>, but in this case the correct behavior as far as I can tell is to construct the infinite type Enum<Enum<Enum<Enum<Enum....

Maybe the correct behavior is to detect this and report that it cannot be instantiated without specifying the type parameters because they would be infinite. Or maybe the infinite nature could be handled with some tricky algorithms.

@jmesserly
Copy link

jmesserly commented Nov 28, 2016

that's a really good question :D. There's a lot of discussion over in this issue: #27526

edit: the short answer is it would be an error if a default cannot be computed.

@leafpetersen
Copy link
Member

This is now fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on
Projects
None yet
Development

No branches or pull requests

4 participants