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

ICE in borrow checker #27480

Closed
eefriedman opened this issue Aug 2, 2015 · 4 comments
Closed

ICE in borrow checker #27480

eefriedman opened this issue Aug 2, 2015 · 4 comments
Labels
A-borrow-checker Area: The borrow checker I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@eefriedman
Copy link
Contributor

https://play.rust-lang.org/?gist=23de822c03921663ae66&version=nightly .

Error message:

<anon>:110:25: 110:60 error: cannot assign to `*entry` because it is borrowed
<anon>:110                         *entry = FragmentRepr::Enum(discrs);
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of if let expansion
<anon>:108:21: 111:22 note: expansion site
note: in expansion of for loop expansion
<anon>:100:5: 150:6 note: expansion site
<anon>:112:64: 112:78 note: borrow of `*entry` occurs here
<anon>:112                     let mut discrs = if let FragmentRepr::Enum(ref mut discrs) = *entry {
                                                                          ^~~~~~~~~~~~~~
note: in expansion of if let expansion
<anon>:112:38: 116:22 note: expansion site
note: in expansion of for loop expansion
<anon>:100:5: 150:6 note: expansion site
<anon>:112:64: 112:78 error: cannot borrow `entry.0` as mutable more than once at a time
<anon>:112                     let mut discrs = if let FragmentRepr::Enum(ref mut discrs) = *entry {
                                                                          ^~~~~~~~~~~~~~
note: in expansion of if let expansion
<anon>:112:38: 116:22 note: expansion site
note: in expansion of for loop expansion
<anon>:100:5: 150:6 note: expansion site
<anon>:112:64: 112:78 note: previous borrow of `entry.0` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `entry.0` until the borrow ends
<anon>:112                     let mut discrs = if let FragmentRepr::Enum(ref mut discrs) = *entry {
                                                                          ^~~~~~~~~~~~~~
note: in expansion of if let expansion
<anon>:112:38: 116:22 note: expansion site
note: in expansion of for loop expansion
<anon>:100:5: 150:6 note: expansion site
<anon>:150:6: 150:6 note: previous borrow ends here
<anon>:100     for &move_path_index in paths {
...
<anon>:150     }
               ^
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'rustc' panicked at 'assertion failed: `(left == right)` (left: `collections::vec::Vec<(u32, FragmentRepr)>`, right: `Box<FragmentRepr>`)', ../src/librustc_borrowck/borrowck/mod.rs:454
@sfackler sfackler added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Aug 2, 2015
@Aatch
Copy link
Contributor

Aatch commented Aug 3, 2015

Could you maybe try to reduce the case down a bit more?

@eefriedman
Copy link
Contributor Author

Reduced:

pub enum FragmentRepr {
    Boxed(Box<FragmentRepr>),
    Enum(Vec<FragmentRepr>),
}
fn bar() -> u32 { panic!(); }
pub fn foo(mut entry: &mut FragmentRepr) {
    loop {
        match bar() {
            1 => {
                let mut discrs = if let FragmentRepr::Enum(ref mut discrs) = *entry {
                    discrs
                } else {
                    return;
                };
                entry = &mut discrs[0];
            }
            _ => {
                entry = if let FragmentRepr::Boxed(ref mut contents) = *entry {
                    contents
                } else {
                    return;
                };
            }
        }
    }
}
fn main() {}

@jroesch jroesch added the A-borrow-checker Area: The borrow checker label Aug 3, 2015
@arielb1
Copy link
Contributor

arielb1 commented Aug 9, 2015

Much reduced:

pub enum FragmentRepr {
    Boxed(Box<FragmentRepr>),
    Enum(()),
}
fn unconstrained<T>() -> T { loop {} }
pub fn foo(mut entry: &mut FragmentRepr) {
    entry = if let &mut FragmentRepr::Boxed(ref mut contents) = entry {
        contents
    } else {
        unconstrained()
    };
    match *entry {
        FragmentRepr::Enum(ref mut discrs) => {},
        _ => {}
    };
}
fn main() {}

Somehow &mut &mut FragmentRepr became &mut FragmentRepr (wut?)

Seems like we don't handle deref-coercions somewhere.

@arielb1
Copy link
Contributor

arielb1 commented Jun 11, 2016

duplicate of #27844.

@arielb1 arielb1 closed this as completed Jun 11, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

5 participants