Skip to content

Fix for #31267 and additional zero-width constant bug #31326

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

Merged
merged 2 commits into from
Feb 4, 2016
Merged

Fix for #31267 and additional zero-width constant bug #31326

merged 2 commits into from
Feb 4, 2016

Conversation

sdleffler
Copy link
Contributor

After the truly incredible and embarrassing mess I managed to make in my last pull request, this should be a bit less messy.

Fixes #31267 - with this change, the code mentioned in the issue compiles.

Found and fixed another issue as well - constants of zero-size types, when used in ExprRepeats inside associated constants, were causing the compiler to crash at the same place as #31267. An example of this:

#![feature(associated_consts)]

#[derive(Clone, Copy, Debug)]
struct Bar;

const BAZ: Bar = Bar;

#[derive(Debug)]
struct Foo([Bar; 1]);

struct Biz;

impl Biz {
    const BAZ: Foo = Foo([BAZ; 1]);
}

fn main() {
    let foo = Biz::BAZ;
    println!("{:?}", foo);
}

However, I'm fairly certain that my fix for this is not as elegant as it could be. The problem seems to occur only with an associated constant of a tuple struct containing a fixed size array which is initialized using a repeat expression, and when the element to be repeated provided to the repeat expression is another constant which is of a zero-sized type. The fix works by looking for constants and associated constants which are zero-width and consequently contain no data, but for which rustc is still attempting to emit an LLVM value; it simply stops rustc from attempting to emit anything. By my logic, this should work fine since the only values that are emitted in this case (according to the comments) are for closures with side effects, and constants will never have side effects, so it's fine to simply get rid of them. It fixes the error and things compile fine with it, but I have a sneaking suspicion that it could be done in a far better manner.

r? @nikomatsakis

@rust-highfive
Copy link
Contributor

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (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.

// should be able to just discard it, since const expressions are guaranteed not to
// have side effects. This seems to be reached through tuple struct constructors being
// passed zero-size constants.
if let hir::ExprPath(..) = expr.node {
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, it'd be nice to have an assertion here about the fact that the type is zero-sized.

@nikomatsakis
Copy link
Contributor

@sdleffler you up for adding an assertion? I'm not sure what the best helper method is, but I can dig around if you want :)

@sdleffler
Copy link
Contributor Author

@nikomatsakis added one, should do the trick I think!

@nikomatsakis
Copy link
Contributor

@bors r+

Looks good!

@bors
Copy link
Collaborator

bors commented Feb 3, 2016

📌 Commit fb00e60 has been approved by nikomatsakis

@bors
Copy link
Collaborator

bors commented Feb 4, 2016

⌛ Testing commit fb00e60 with merge f511b21...

bors added a commit that referenced this pull request Feb 4, 2016
After the truly incredible and embarrassing mess I managed to make in my last pull request, this should be a bit less messy.

Fixes #31267 - with this change, the code mentioned in the issue compiles.

Found and fixed another issue as well - constants of zero-size types, when used in ExprRepeats inside associated constants, were causing the compiler to crash at the same place as #31267. An example of this:
```

struct Bar;

const BAZ: Bar = Bar;

struct Foo([Bar; 1]);

struct Biz;

impl Biz {
    const BAZ: Foo = Foo([BAZ; 1]);
}

fn main() {
    let foo = Biz::BAZ;
    println!("{:?}", foo);
}
```
However, I'm fairly certain that my fix for this is not as elegant as it could be. The problem seems to occur only with an associated constant of a tuple struct containing a fixed size array which is initialized using a repeat expression, and when the element to be repeated provided to the repeat expression is another constant which is of a zero-sized type. The fix works by looking for constants and associated constants which are zero-width and consequently contain no data, but for which rustc is still attempting to emit an LLVM value; it simply stops rustc from attempting to emit anything. By my logic, this should work fine since the only values that are emitted in this case (according to the comments) are for closures with side effects, and constants will never have side effects, so it's fine to simply get rid of them. It fixes the error and things compile fine with it, but I have a sneaking suspicion that it could be done in a far better manner.

r? @nikomatsakis
@bors bors merged commit fb00e60 into rust-lang:master Feb 4, 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.

ICE on use of associated constants with array expression
4 participants