-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Higher-ranked trait bounds #387
Conversation
## Update syntax of fn types | ||
|
||
The existing bare fn types will be updated to use the same `for` | ||
notation. Therefore, `<'a> fn(&'a int)` becomes `for<'a> fn(&'a int)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current syntax for higher-ranked lifetimes in bare functions is fn<'a>(&'a int)
, not <'a> fn(&'a int)
. Perhaps bare functions could stay the same, Fn{,Mut,Once}
could use a similar syntax with the sugar (Fn<'a>(&'a int)
), and any other trait would have to use the for
syntax (for<'a> Foo<&'a int>
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On Fri, Oct 10, 2014 at 02:06:51PM -0700, P1start wrote:
The current syntax for higher-ranked lifetimes in bare functions is
fn<'a>(&'a int)
, not<'a> fn(&'a int)
. Perhaps bare functions could stay the same,Fn{,Mut,Once}
could use a similar syntax with the sugar (Fn<'a>(&'a int)
), and any other trait would have to use thefor
syntax (for<'a> Foo<&'a int>
).
I considered this. The main reason I did not propose it is that it
makes the parsing much more subtle. How do I know whether Foo<
is
going to be Foo<A,B>
or Foo<'a>(...)
? It seems to require quite a
bit of lookahead, particularly if you don't want to rely on the
lifetime vs type distinction (which I don't, for reasons described in
the RFC). I suppose that there is a cover grammar, nonetheless, so
in principle it doesn't require extraordinary lookahead.
Of course, there is also some appeal to having a single syntax that is
uniformly applicable to all types.
In any case I certainly ought to have included a section on it for the
RFC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we allow the for <'a>
format at the fn
definition point as well (in addition to the type expression form)?
i.e. support as an item for <'a> fn(x: &'a mut int) -> &'a mut int { *x = *x + 1; x }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose that we have +1 to the proposal overall. |
With the new higher-order lifetimes and the new where clauses, would some version of trait Iterable<T, 'a> {
type IT where IT : Iterator<T> + 'a;
fn iter(self) -> IT;
}
fn test<T>(i: &T) where for<'a> &'a T: Iterable<uint, 'a> be legal? |
Looks good, I eagerly await this feature! 3 questions:
|
On Sat, Oct 11, 2014 at 01:00:48PM -0700, arielb1 wrote:
Hmm, so, this was not covered by the RFC, though in principle it is In any case, to accommodate this requires basically requires only In the impl itself, there aren't many changes either, as the scope of |
On Sat, Oct 11, 2014 at 01:52:52PM -0700, John Ericson wrote:
Type parametes are seperate, but higher-ranked fn types are possible
I've tried to look ahead and I believe the for syntax scales.
I considered this previously, when we were deciding how to handle |
Nice! Note that if you take the associated type -> fundep desugar, you should get something like trait Iterable<T, IT, 'a> {
fn iter(self) -> IT;
}
fn test<T>(i: &T) where for<'a, IT> &'a T: Iterable<uint, 'a, IT>
IT: Iterator<T>+'a So associated types seems to be a non-conservative extension (is this the right term here?) over fundeps+HRLT. Is this correct? (However, this is not seem to be the same as full 2RT, as IT is a formula with no free type variables). By the way, aren't "late-bound" lifetimes just lifetime parameters that the impl-ee is bivariant in? |
Looks good to me! Is there any reason not to allow higher-rank lifetimes on normal
and then
Edit: Also, I wonder if there's any theoretical difference between |
Universal quantifiers can always be moved around in a covariant context – so |
Yeah, that's what I figured... it's only the fact that this is a trait, with some form of implicit existential quantification going on, which makes me a bit uncertain. (Probably you're right, I just didn't feel like thinking it all the way through.) |
Accepted. Discussion. Tracking. |
An interesting question which occurred to me: Is there a difference between (Relatedly, my earlier question, "Is there any reason not to allow higher-rank lifetimes on normal |
I think the answer is yes, depending on the variance of |
Yes, it definitely seems to be different in the contravariant case. |
This reminds me, if |
That was one of the next thoughts I had, along with existentially quantified lifetimes (which are nonsensical for the covariant case, but perhaps not for the contravariant one). The lower bound would presumably be the empty lifetime, but given that (By "contravariant" in the above I mean "expects a reference type as argument"; last time I checked the terminology was accepted as being vice-versa for the lifetimes themselves.) |
A description of higher-ranked trait bounds, which is the remaining piece needed to make unboxed closures equal to normal closures.
Rendered view.