Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions active/0000-safe-integral-auto-coercions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
- Start Date: 2014-09-03
- RFC PR #:
- Rust Issue #:

# Summary

Enable implicit coercion from some integral type `A` to some integral type `B` if type `B` can represent all the values type `A` can.

# Motivation

This would improve both programming convenience and code readability.

# Detailed design

All unsigned integral types should auto-coerce to a wider integral type. All signed integral types should auto-coerce to a wider signed integral type. For example, `u16` would auto-coerce to any of the following: `u32`, `u64`, `i32`, `i64`. But `i16` would auto-coerce only to `i32` and `i64`.

# Drawbacks

?
Copy link
Contributor

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?
}

Copy link
Author

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()?

Copy link
Contributor

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.

Copy link
Author

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.

Copy link
Contributor

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.


# Alternatives

?

# Unresolved questions

What about auto-coercion to `int` and `uint`?