-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add safe integral auto-coercions #225
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
Conversation
|
||
# Drawbacks | ||
|
||
? |
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.
Drawback: silent conversions are confusing.
fn bar(x: u32) { /* ... */ }
fn foo(x: u32) {
let y = x + mystery_func(); // clearly a u32, right? It's derived from x
// ... code goes here
bar(y); // error, argument must be u32?
}
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.
What is the type of bar()
?
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.
Oops, I re-used the name bar()
, that's a bit confusing. I'll fix it. I meant for the first call to bar()
to be some unknown function with an unknown return value. The expectation is if the line let y = x + bar()
compiles, then bar()
's return value must be compatible with x
, which is a u32
, and addition on integral types is known to return the receiver type.
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.
Ok, but let's say that mystery_func()
returns u64
. Today the compiler would give the error (mismatched types: expected u32
, found u64
) on the line: let y = x + mystery_func();
. If this RFC lands, then the compiler would give the same error on the line: bar(y);
. I don't see this (the location of the error) as a big issue; after all, you can fix your code by down-casting either mystery_func()
or y
to u32
, so it's not that clear what the best place for the error is anyway.
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 problem is it divorces the reported error from the actual error. The line bar(y);
is not the bad code. The line let y = x + mystery_func();
is the bad code. Yes, you can get the same issue today merely by using a bad type, e.g. if bar()
took x: i32
instead of x: u32
. But in the cited example, it looks straightforward, it looks like the typing should all match, and the error on bar(y);
is therefore confusing.
@zwarich and I discussed this at some length a few weeks ago. We came to the conclusion that we didn't think there would be any problems with widening within signedness, but that changing signedness could be confusing, especially in the face of overflow. I can't find the IRC logs from it, he may recall more, but I remember wanting to find numbers of something. We were discussing it in the context of int/uint always being u32/i32 (ie, using an LP64 model). Perhaps we wanted to know how many uses would need explicit casts. |
Regarding my "Unresolved Questions" section, at least the following auto-coercions should be safe: from |
An example where the conversions, if allowed, lead to unintended result:
Anyway, the idea probably comes to mind to every person who encounters Rust for the first time, but the conversions are still prohibited. Wasn't it discussed at least for a dozen times and rejected? |
@petrochenkov How does your example demonstrate my RFC leading to an unintended result? Just to break it down... your example's Today you'd have to write |
@tommit If compiler wants you to write |
Example 2: Interaction with traits.
Of course, it is possible to specify all the cases, but then built-in types become special, built-in operators become special, initializations of variables and function arguments may become different, rules become more complex, hello C++.
but I'm not sure about it either. |
@petrochenkov Ok, I can see how getting the error message in the That said, I do think the interplay between traits and auto-coercible integral types could work and that some more magic in the built-in integral types wouldn't make the language that much more complicated. Numeric types are already a bit special in that they, unlike user-defined types, can be cast using the But, since I do think that helping to catch that
|
@tommit I'd suggest just using uint for sizes and indexes, as the standard library does. Of course, there are some exceptions, but it reduces the conversion noise to minimum. |
6357402
to
e0acdf4
Compare
Thank you for the RFC @tommit but we're not interested in adding such coercions right now. |
At least why not allow all unsigned number types to index an array ? See the issue above. |
…arams Allow {{mount}} syntax to accept parameters
View