Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upType conversions #401
Conversation
This comment has been minimized.
This comment has been minimized.
Gankro
reviewed
Oct 16, 2014
|
|
||
| * `&mut T` to `&T`; | ||
|
|
||
| * `*mut T` to `*const T`; |
This comment has been minimized.
This comment has been minimized.
Gankro
reviewed
Oct 16, 2014
|
|
||
| * coerce_inner(`(..., T)`) = `(..., coerce_inner(T))`. | ||
|
|
||
| Note that coercing from sub-trait to a super-trait it a new coercion and is non- |
This comment has been minimized.
This comment has been minimized.
Gankro
reviewed
Oct 16, 2014
| Here is an example implementation of `CoerceUnsized` for `Rc`: | ||
|
|
||
| ``` | ||
| impl<Sized? T, Sized? U> CoerceUnsized<Rc<T>> for Rc<U> { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nrc
Oct 16, 2014
Author
Member
No, I don't think so. U is just the pointed-to data, it does not need to be coercible. The RcBox is unsized using the fat_pointer_convert intrinsic and automatically has the required Unsize bound.
This comment has been minimized.
This comment has been minimized.
comex
Oct 16, 2014
How does that work? As written, it seems like you could [manually] call coerce() to convert any Rc<T> to any other.
This comment has been minimized.
This comment has been minimized.
nrc
Oct 16, 2014
Author
Member
Yeah, actually I guess you do need a where clause on the impl - where U: Unsize<T>. Given that where clause the compiler can derive that RcBox<U>: Unsize<RcBox<T>> an thus that we can call fat_pointer_convert.
ben0x539
reviewed
Oct 16, 2014
| ## Casts | ||
|
|
||
| Casting is indicated by the `as` keyword. A cast `e as U` is valid if one of the | ||
| following holds: |
This comment has been minimized.
This comment has been minimized.
ben0x539
Oct 16, 2014
I don't see it spelled out here (but I guess neither are numeric casts), *T -> *U is gonna remain a cast, right?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nrc
Oct 16, 2014
Author
Member
Numeric casts are an omission, I'll add them in.
@ben0x539 what are T and U here? Do you mean an arbitrary cast from one raw pointer type to another?
This comment has been minimized.
This comment has been minimized.
ben0x539
Oct 16, 2014
Yeah, *T -> *U for any T and U with any combination of mutability seems to be accepted right now but I'm not seeing it listed here. Would be sad to see it go away!
ben0x539
reviewed
Oct 16, 2014
| it is embedded in the search for candidate methods, but from the point of view | ||
| of type conversions, that is not relevant). | ||
|
|
||
| Alternatively, a recevier coercion may be thought of as a two stage process. |
This comment has been minimized.
This comment has been minimized.
ben0x539
reviewed
Oct 16, 2014
| given by the `Deref` trait), one or zero applications of `coerce_inner` or use | ||
| of the `CoerceUnsized` trait (as defined above, note that this requires we are | ||
| at a type which has neither references nor dereferences at the top level), and | ||
| up to two address-of operations (i.e., `T` to `&T`, `&mut T`, `*const T`, or |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nrc
Oct 16, 2014
Author
Member
When the impl is for &T (for some T) and the method takes self by reference (&self). This was common pre-DST, but even with DST it still happens enough to be required.
michaelsproul
reviewed
Oct 16, 2014
| # Summary | ||
|
|
||
| Describe the various kinds of type conversions available in Rust and suggest | ||
| some tweeks. |
This comment has been minimized.
This comment has been minimized.
Gankro
reviewed
Oct 16, 2014
|
|
||
| * `T == u8` and `U == char`; | ||
|
|
||
| * `T == &[V]` or `T == &[V, ..n]` and `U == *V`. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nrc
Oct 16, 2014
Author
Member
This is not new (afaik, I'm sure I pulled this out of the compiler, but it was a while back).
I don't see a reason not to allow the corresponding string cast. Anyone object?
This comment has been minimized.
This comment has been minimized.
ben0x539
Oct 16, 2014
&[V] -> *const V doesn't seem to work, only &[V, .. n] -> *const V.
Also is the mut equivalent intentionally omitted?
This comment has been minimized.
This comment has been minimized.
nrc
Oct 23, 2014
Author
Member
Hmm, I probably shouldn't allow casts from &[V] since that is a fat pointer, better to use a function for that. And I guess the same goes for &str to *u8.
ghost
reviewed
Oct 16, 2014
|
|
||
| * `&T` to `*const T`; | ||
|
|
||
| * `&mut T` to `*mut T`; |
This comment has been minimized.
This comment has been minimized.
ghost
Oct 16, 2014
How does this interact with raw pointers that denote arrays, like *mut u8 almost always does?
This comment has been minimized.
This comment has been minimized.
nrc
Oct 16, 2014
Author
Member
This only allows casts TO *mut T, so I don't think there is an interaction - unless I am missing something?
This comment has been minimized.
This comment has been minimized.
ghost
Oct 16, 2014
If I pass a &mut u8 to copy_memory() that is not an array, will it silently cause a buffer overflow?
This comment has been minimized.
This comment has been minimized.
huonw
Oct 16, 2014
Member
It won't be a buffer overrun if the length is less than or equal to 1; it's trivial to get a buffer overrun with copy_memory even with a real array, by just passing a length greater than the length of the array.
Also, note that we currently support this &mut to *mut coercion; I don't think it has caused too many problems in practice.
This comment has been minimized.
This comment has been minimized.
|
Is this the opportunity to discuss possibly allowing numeric types to implicitly coerce when there's no loss of precision, e.g. |
This comment has been minimized.
This comment has been minimized.
|
@bstrie I think that is a big enough change that it deserves its own RFC |
comex
reviewed
Oct 16, 2014
| ``` | ||
|
|
||
| The `Unsize` trait is a marker trait and a lang item. It should not be | ||
| implemented by users and user implementations will be ignored. The compiler will |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nrc
Oct 16, 2014
Author
Member
That is a reasonable alternative. It would require an ad-hoc check in the type checker though
comex
reviewed
Oct 16, 2014
| ``` | ||
| intrinsic fn fat_pointer_convert<Sized? T, Sized? U>(t: *const T) -> *const U | ||
| where T : Unsize<U>; | ||
| ``` |
This comment has been minimized.
This comment has been minimized.
comex
Oct 16, 2014
What is the difference between this and t as *const U?
Alternately, can this be part of the Unsize trait?
This comment has been minimized.
This comment has been minimized.
nrc
Oct 16, 2014
Author
Member
t as *const U would allow more conversions than the intrinsic would. E.g., numeric conversions.
This comment has been minimized.
This comment has been minimized.
|
Does this make coercion an special case of casts? Eg, is is true that with the changes every implicit coercion can also be written as an explicit cast? |
nrc
self-assigned this
Oct 16, 2014
This comment has been minimized.
This comment has been minimized.
nodakai
commented
Oct 17, 2014
|
Will generic integer literals be covered by this RFC? (Perhaps they aren't technically coercion...) I have a little frustration about generic literals with minus sign: fn main() {
for x in std::iter::range_step(3u32, 0, -1) {
println!("{}", x);
}
}I don't like |
This comment has been minimized.
This comment has been minimized.
ben0x539
commented
Oct 17, 2014
|
@nodakai fwiw that's unrelated to generics, a plain |
This comment has been minimized.
This comment has been minimized.
nodakai
commented
Oct 18, 2014
|
@ben0x539 When you say "generics," you mean the fn main() {
0.f();
}
|
This comment has been minimized.
This comment has been minimized.
ben0x539
commented
Oct 18, 2014
|
@nodakai Yeah, I thought you were talking about the |
This comment has been minimized.
This comment has been minimized.
abonander
commented
Oct 18, 2014
|
I would like |
alexcrichton
force-pushed the
rust-lang:master
branch
from
b9e2b8c
to
5020131
Oct 29, 2014
aturon
merged commit d65c19d
into
rust-lang:master
Oct 30, 2014
This comment has been minimized.
This comment has been minimized.
|
Merged. Discussion. Tracking. |
nrc commentedOct 16, 2014
Casting and coercions. Adds custom DST coercions for smart pointers. Otherwise, mostly descriptive, with a few bits of tidying up.
rfc
text/