-
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
RFC: Type Ascribed Coercions #2623
Conversation
@@ -161,7 +161,7 @@ as an lvalue (i.e., no new temporary), then there is potential for unsoundness: | |||
``` | |||
let mut foo: S = ...; | |||
{ | |||
let bar = &mut (foo: T); // S <: T, no coercion required | |||
let bar = &mut (foo: T); // S <: T, coercion from S to T |
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.
In case you wonder: "no coercion required" was wrong because this is one type of coercion.
The change is now covered by the paper of RFC 2623
It's not clear to me if this needs an RFC? (i.e. is there anything here for the general public to discuss?) RFCs are not authorative, especially with regards to implementation, and in cases like this where an "obvious right solution" arises somewhere down the road, I believe the course of action taken in the past has been to simply implement that obvious right solution. (unless perhaps somebody believes this change is not so "obviously right" as I suggest? :P) Personally, I am familiar with the concept of coercion sites as defined in the Rust reference, and the very first thing I thought of upon seeing the unsound example was, "I don't think that's a coercion site?" I'd probably just shrug it off on the basis that the RFC is 3 years old, knowing how much our vocabulary and concepts for discussing the language have changed since then. |
I guess the most accessible thing to focus on is the disadvantages.
This snippet uses a Also, I assume this still works for selecting types for type inference? // should be ok, since `V where V: FromIterator<i32>` can be unified with Vec<i32>?
let _ = (0..1).collect(): Vec<i32>;
let _ = (&(0..1).collect()): &Vec<i32>;
// presumably this is not ok since it requires a coercion?
let _ = (&(0..1).collect::<Vec<_>>()): &[i32];
fn reborrow<'b, 'a: 'b>(x: &'a i32) -> &'b i32 {
// hopefully okay since subtyping doesn't *require* a coercion site?
// (or does it?)
x: &'b i32
} |
I came to Rust 2 weeks ago and am still unfamiliar with the processes.
I also thought about that being a possible reason, why it's not already like I proposed.
Like stated: Once RFC #2522 gets merged, we can help type inference at the left side of the assignment, even with arbitrary patterns. Example: let (alpha: u8, beta: i16, gamma: bool) = (1, -2, true); If there'd still be code that surprisingly doesn't compile, we could still fix it later. |
It's okay, but for a different reason: The last expression of a block is a coercion site. |
Ah, indeed. After reading the RFC more thoroughly that does sound like the correct explanation for the third example.
This is still pretty good! The RFC is excellently written, I just mention this because writing an RFC can be a pretty big time sink (so when the process can be avoided, that's a good idea). Proposing these ideas first on internals as a Pre-RFC can also garner suggestions on how to get things moving in the right direction.
In this vein, mind: The reference is a Pretty New Thing (TM) and still a work in progress. For a long time, the only big resources on Rust were RTPL (which isn't much of a reference), the Nomicon (which has stagnated and is limited in topics), and any language features documented in the standard library documentation (which is very limited in scope). |
Hmm, so, I like the overall definition here, but I think perhaps there may be different expectations as to what constitutes a "coercion site". In particular, I would have assumed that the "initializer in a I guess I have to revisit the "pattern binding" RFC. It seems like in general we could make On the other hand, that might just mean that the RFC is basically "identical" to the existing, already accepted solution? (Since any non-coercion site is a "reference site"?) I do agree with @ExpHP that this doesn't have to be an RFC per se, but it's the sort of conversation where our current process doesn't have an ideal home. Something I'd like to change. =) |
Man, I just re-read this RFC -- uh -- over a year later and I had completely forgotten that I had read it before. I think I still approve of its general argument, though the comment I made above is still relevant -- I would consider |
We discussed this in the backlog bonanza and decided to close the RFC as unnecessary -- this feels like it falls well within the realm of "implementation detail". So what I am going to do is to open a tracking issue that corresponds to this RFC and link it from the type ascription issue as a suggested implementation path. There are however some doubts within the lang-team about whether the existing type ascription syntax is the right one, as you can see in this recent Zulip thread. |
Er, I meant to add, thanks @haslersn for the suggestion, though, this seems like it is indeed a better approach! |
By the way, I think a better example of where this approach might differ from the original RFC would be something like |
Rendered
This improves on the merged RFC 803.
Motivation and summary
The subsection "Type ascription and temporaries" of the merged RFC 803 defines certain contexts (so-called reference contexts) in which a type ascription that needs coercion can not occur. Meanwhile and in contrast, the Rust reference defines coercion sites which are contexts in which a coercion can occur.
For consistency, we change the specification as of RFC 803 such that a type ascribed expression that needs to be coerced can only occur at these coercion sites. The aim is to reduce language complexity and increase consistency.
This change shouldn't in any way conflict with RCF 2522.