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

typestrong const integers #30587

Merged
merged 13 commits into from
Mar 14, 2016
Merged

typestrong const integers #30587

merged 13 commits into from
Mar 14, 2016

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Dec 28, 2015

It would be great if someone could run crater on this PR, as this has a high danger of breaking valid code Crater ran. Good to go.


So this PR does a few things:

  1. const eval array values when const evaluating an array expression
  2. const eval repeat value when const evaluating a repeat expression
  3. const eval all struct and tuple fields when evaluating a struct/tuple expression
  4. remove the ConstVal::Int and ConstVal::Uint variants and replace them with a single enum (ConstInt) which has variants for all integral types
    • usize/isize are also enums with variants for 32 and 64 bit. At creation and various usage steps there are assertions in place checking if the target bitwidth matches with the chosen enum variant
  5. enum discriminants (ty::Disr) are now ConstInt
  6. trans has its own Disr type now (newtype around u64)

This obviously can't be done without breaking changes (the ones that are noticable in stable)
We could probably write lints that find those situations and error on it for a cycle or two. But then again, those situations are rare and really bugs imo anyway:

let v10 = 10 as i8;
let v4 = 4 as isize;
assert_eq!(v10 << v4 as usize, 160 as i8);

stops compiling because 160 is not a valid i8

struct S<T, S> {
    a: T,
    b: u8,
    c: S
}
let s = S { a: 0xff_ff_ff_ffu32, b: 1, c: 0xaa_aa_aa_aa as i32 };

stops compiling because 0xaa_aa_aa_aa is not a valid i32


cc @eddyb @pnkfelix

related: rust-lang/rfcs#1071
#13768
#23833

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Aatch (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@bors
Copy link
Contributor

bors commented Dec 28, 2015

☔ The latest upstream changes (presumably #30588) made this pull request unmergeable. Please resolve the merge conflicts.

@@ -3677,10 +3677,10 @@ sites are:

* `let` statements where an explicit type is given.

For example, `128` is coerced to have type `i8` in the following:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, but probably should go into a separate rollable-up PR.

@pnkfelix pnkfelix added the S-waiting-on-crater Status: Waiting on a crater run to be completed. label Dec 29, 2015
@bors
Copy link
Contributor

bors commented Dec 31, 2015

☔ The latest upstream changes (presumably #30660) made this pull request unmergeable. Please resolve the merge conflicts.

@nagisa
Copy link
Member

nagisa commented Jan 6, 2016

This will have to be reviewed outside-of-github because of its tendency to censor.

@bors
Copy link
Contributor

bors commented Jan 11, 2016

☔ The latest upstream changes (presumably #30676) made this pull request unmergeable. Please resolve the merge conflicts.

@oli-obk oli-obk changed the title WIP: eager const evaluation + typestrong const integers WIP: typestrong const integers Jan 13, 2016
@oli-obk
Copy link
Contributor Author

oli-obk commented Jan 13, 2016

I removed the eager const eval to do that on its own. For now it's just the typestrong const integers.

I'm not sure what the expected behavior of something like 160 as i8 is, but if it's "random value" instead of an error, then I can easily introduce that by turning it into 42 deterministically outside of true constants (and emitting a warning oc).

@brson
Copy link
Contributor

brson commented Jan 13, 2016

I'll run crater.

@brson
Copy link
Contributor

brson commented Jan 14, 2016

Report. Only regression is a false positive.

@brson brson removed the S-waiting-on-crater Status: Waiting on a crater run to be completed. label Jan 14, 2016
@oli-obk
Copy link
Contributor Author

oli-obk commented Jan 14, 2016

wooohoo xD I'll split it up into multiple PRs for easier reviewing

@bors
Copy link
Contributor

bors commented Jan 15, 2016

☔ The latest upstream changes (presumably #30890) made this pull request unmergeable. Please resolve the merge conflicts.

bors added a commit that referenced this pull request Jan 17, 2016
This is groundwork for #30587 (typestrong constant integrals), but imo it's a change that in itself is good, too, since we don't just juggle `u64`s around anymore.

`ty::Disr` will be changed to a `ConstInt` in #30587
`assert_eq!(-9223372036854775808isize as u64, 0x8000000000000000);`

fails on 32 bit and succeeds on 64 bit. These commits don't change that behavior.

The following worked before my changes, because the discriminant was
always processed as `u64`.
Now it fails, because the discriminant of `Bu64` is now `0` instead of `-9223372036854775808`. This is more in line with the above assertion's code, since
`-9223372036854775808isize as u64` on 32 bit yielded `0`.

```rust
enum Eu64 {
    Au64 = 0,
    Bu64 = 0x8000_0000_0000_0000
}
```
@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 11, 2016

As the commit message of fcee002 states:

assert_eq!(-9223372036854775808isize as u64, 0x8000000000000000);

fails on 32 bit and succeeds on 64 bit. These commits don't change that behavior.

The following worked before my changes, because the discriminant was
always processed as u64.
Now it fails, because on 32 bit the discriminant of Bu64 is now 0 instead of -9223372036854775808. This is more in line with the above assertion's code, since
-9223372036854775808isize as u64 on 32 bit yielded 0.

enum Eu64 {
    Au64 = 0,
    Bu64 = 0x8000_0000_0000_0000
}

@nikomatsakis
Copy link
Contributor

@oli-obk thanks; can't say I'm entirely happy with the rules here, but this seems like the best step for now.

@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Mar 11, 2016

📌 Commit 08c448a has been approved by nikomatsakis

@bors
Copy link
Contributor

bors commented Mar 11, 2016

⌛ Testing commit 08c448a with merge f5dbfb4...

@bors
Copy link
Contributor

bors commented Mar 11, 2016

💔 Test failed - auto-linux-64-opt-rustbuild

@arielb1
Copy link
Contributor

arielb1 commented Mar 13, 2016

Try to add rustc_const_eval to the rustbuild config. cc @alexcrichton

@alexcrichton
Copy link
Member

Yeah if this is adding a new crate it'll just need a Cargo.toml plus the necessary dependency edges to be made as well.

@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 14, 2016

can't test locally, because the boostrap crate's build script doesn't know about --enable-clang

but I added the dependencies to every crate that has extern crate rustc_const_eval

@alexcrichton
Copy link
Member

@bors: r=nikomatsakis f665c39

@bors
Copy link
Contributor

bors commented Mar 14, 2016

⌛ Testing commit f665c39 with merge 0111892...

bors added a commit that referenced this pull request Mar 14, 2016
typestrong const integers

~~It would be great if someone could run crater on this PR, as this has a high danger of breaking valid code~~ Crater ran. Good to go.

----

So this PR does a few things:

1. ~~const eval array values when const evaluating an array expression~~
2. ~~const eval repeat value when const evaluating a repeat expression~~
3. ~~const eval all struct and tuple fields when evaluating a struct/tuple expression~~
4. remove the `ConstVal::Int` and `ConstVal::Uint` variants and replace them with a single enum (`ConstInt`) which has variants for all integral types
  * `usize`/`isize` are also enums with variants for 32 and 64 bit. At creation and various usage steps there are assertions in place checking if the target bitwidth matches with the chosen enum variant
5. enum discriminants (`ty::Disr`) are now `ConstInt`
6. trans has its own `Disr` type now (newtype around `u64`)

This obviously can't be done without breaking changes (the ones that are noticable in stable)
We could probably write lints that find those situations and error on it for a cycle or two. But then again, those situations are rare and really bugs imo anyway:

```rust
let v10 = 10 as i8;
let v4 = 4 as isize;
assert_eq!(v10 << v4 as usize, 160 as i8);
 ```

stops compiling because 160 is not a valid i8

```rust
struct S<T, S> {
    a: T,
    b: u8,
    c: S
}
let s = S { a: 0xff_ff_ff_ffu32, b: 1, c: 0xaa_aa_aa_aa as i32 };
```

stops compiling because `0xaa_aa_aa_aa` is not a valid i32

----

cc @eddyb @pnkfelix

related: rust-lang/rfcs#1071
@bors bors merged commit f665c39 into rust-lang:master Mar 14, 2016
@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 14, 2016

🎉 🎈

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

Successfully merging this pull request may close these issues.