Skip to content
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

Use the size of numeric literals to inform the inferred numeric type #8337

Closed
bstrie opened this issue Aug 6, 2013 · 5 comments
Closed

Use the size of numeric literals to inform the inferred numeric type #8337

bstrie opened this issue Aug 6, 2013 · 5 comments

Comments

@bstrie
Copy link
Contributor

bstrie commented Aug 6, 2013

I've annotated the following program with its current output:

fn foo<T: Signed>(x: T, y: T) {
    printfln!("%?, %?", x, y);
}

fn main() {
    foo(1, 8_000_000_000);      // 1, -589934592
    foo(1, 8_000_000_000i64);   // 1, 8000000000
    foo(1i8, 8_000_000_000);    // 1, 0
    //foo(1, 8_000_000_000i8);  // error: literal out of range for its type
}

As shown by the last (commented-out) line, Rust is already smart enough to reject numeric literals whose values are larger than the maximum value that can be represented by their type, but only when their type is specified by a suffix:

  1. As shown by the first call to foo, it's perfectly willing to infer the default type of int, even when the value is too large to be contained in an int.
  2. As shown by the third call to foo, it's perfectly willing to infer a concrete type from a previously-given numeric suffix, even when that type is too small to hold the value of the later, un-suffixed literal.

This might be naive of me, but it would be wonderful if these issues could be addressed somehow. The first issue would be complicated by the fact that int is a different size on different architectures, and that inferring the type to i64 would require assigning the same type to the prior literal. The second issue would require recognizing that 1i8 and 8_000_000_000 cannot be the same type without overflow, and would throw an error just as the 8_000_000_000i8 line does today.

@bstrie
Copy link
Contributor Author

bstrie commented Aug 6, 2013

Related to #4220, which is just about enforcing overflow on unsuffixed literals whose type is known rather than actually using the literal value to inform the type inference.

@thestinger
Copy link
Contributor

There are going to be many overflow bugs in Rust code resulting from generic literals falling back to int when there are no type hints. I'm strongly against adding more magic because I already think the existing magic needs to be removed.

It's very odd to assume a fixed-size signed integer wrapping on overflow is desired as the default in most applications. I think 90% of use cases are going to want uint (sizes) or big integers (application logic).

@huonw
Copy link
Member

huonw commented Nov 3, 2013

Triage: no progress, although #4220 is will be fixed by #10018.

(FWIW, I mostly agree with @thestinger, we just need a fast bigint in the stdlib and real generic literals.)

@steveklabnik
Copy link
Member

Now that Rust no longer infers literals, is this still relevant?

@thestinger
Copy link
Contributor

I think it can be closed since the decision was to remove the fallback altogether.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants