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: assertion failed: self.variance.is_some() #9597

Closed
netvl opened this issue Sep 28, 2013 · 7 comments
Closed

ICE: assertion failed: self.variance.is_some() #9597

netvl opened this issue Sep 28, 2013 · 7 comments
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@netvl
Copy link
Contributor

netvl commented Sep 28, 2013

Current compiler fails with the following error:

task '<unnamed>' failed at 'assertion failed: self.variance.is_some()', /.../rust/src/librustc/middle/typeck/rscope.rs:186error: internal compiler error: unexpected failure
note: the compiler hit an unexpected failure path. this is a bug
note: try running with RUST_LOG=rustc=1 to get further details and report the results to github.com/mozilla/rust/issues
task '<unnamed>' failed at 'explicit failure', /.../rust/src/librustc/rustc.rs:39

on the following code:

trait Test<'self> {
    fn method(&'self mut self);
}

struct RealTest<'self> {
    priv value: &'self mut int
}

impl<'self> RealTest<'self> {
    fn new<'a>(init: &'a mut int) -> RealTest<'a> {
        RealTest { value: init }
    }
}

impl<'self> Test<'self> for RealTest<'self> {
    fn method(&'self mut self) {
        self.value += 1;
        println(fmt!("%?", self.value));
    }
}

fn run_test<'a>(test: Test<'a>) {
    test.method();
    test.method();
}

fn main() {
    let mut cell = 0;
    let mut test = RealTest::new(&cell);

    run_test(test);
    println(fmt!("%?", cell));
}

The code above is a reduced version of an attempt to avoid the problem I have described in my message on the mailing list in August. I probably should open an issue for that too.

@bmaxa
Copy link

bmaxa commented Sep 28, 2013

Having lifetime parameter on trait does not have sense, but in any case triggers ICE.
All in all your program is incorrect (if you remove 'self on trait), and gives compile
errors.
If I were you I would use managed pointer instead of borrowed pointer. Effect is same
and there are no lifetime issues.

trait Test {
    fn method(&mut self);
}

struct RealTest {
    priv value: @mut int
}

impl RealTest{
    fn new(init: @mut int) -> RealTest {
        RealTest { value: init }
    }
}

impl Test for RealTest {
    fn method(&mut self) {
        *self.value += 1;
        println(fmt!("%?", self.value));
    }
}

fn run_test(test: &mut Test) {
    test.method();
    test.method();
}

fn main() {
    let cell = @mut 0;
    let test = &mut RealTest::new(cell) as &mut Test;

    run_test(test);
    println(fmt!("%?", cell));
}

@netvl
Copy link
Contributor Author

netvl commented Sep 28, 2013

Yeah, I'm pretty sure that the whole program is incorrect but I think that ICE is not the way by which I should be told about that incorrectness :)

I tried adding lifetime parameters to traits in order to circumvent another problem which I have just described in my message on the mailing list. Apparently, this is not a valid workaround.

And I deliberately try to avoid managed boxes because they limit the API.

@bmaxa
Copy link

bmaxa commented Sep 28, 2013

Well I think that following program solves your problem ;)
Again managed pointer!
BTW, how to wrap code to display as code in comment? ;)

trait Walker {  // Some business-logic trait
    fn walk(&mut self);
}

// A struct which is intended to be an implementor of Walker trait
// Note that it has lifetime parameter in order to work for any kind
// of pointer to a Reader
struct ReaderContainer {
    priv reader: @Reader,
    priv counter: int
}

// Some auxiliary structure for ReaderContainer
// It may be anything but it should have a reference to ReaderContainer
// We have to use lifetime parameter because this structure is 'attached'
// to ReaderContainer, hence it must be of the same lifetime
struct ReaderContainerIterator<'self> {
    priv container: &'self mut ReaderContainer
}

// Some made-up implementation of iterator protocol for our
// auxiliary structure, it does not really matter
impl<'self> Iterator<u8> for ReaderContainerIterator<'self> {
    fn next(&mut self) -> Option<u8> {
        if self.container.counter < 10 {
            self.container.counter += 1;
            Some(self.container.reader.read_byte() as u8)
        } else {
            None
        }
    }
}

impl ReaderContainer {
    // A constructor for ReaderContainer, nothing special
    fn new(reader: @Reader) -> ReaderContainer {
        ReaderContainer { reader: reader, counter: 0 }
    }

    // A method which returns our auxiliary structure, i.e. iterator
    // Note that self parameter has lifetime 'self, otherwise this naturally
    // does not compile
    fn iter<'r>(&'r mut self) -> ReaderContainerIterator<'r> {
        ReaderContainerIterator { container: self }
    }
}

// Here is the problem: we cannot implement Walker trait!
impl Walker for ReaderContainer {
    // See below for concrete errors description
    fn walk(&mut self) {  // <<<
        for b in self.iter() {
            println(fmt!("byte %?", b));
        }
    }
}

fn main() {
    use std::io;

    let r = io::stdin();
    let mut c = ReaderContainer::new(r);

    c.walk();
}

@huonw
Copy link
Member

huonw commented Sep 29, 2013

@bmaxa wrapping code in

```rust
code
code
code
```

will get it formatted/highlighted as Rust code (I've edited your comment to add this).

@erickt
Copy link
Contributor

erickt commented Oct 13, 2013

Probably a subbug of #4846.

@eminence
Copy link
Contributor

After updating the original code example to modern rust, and testing on the latest master (dc48adc) there is no longer any ICE. Instead, the following error:

a.rs:22:23: 22:31 error: reference to trait `Test<'a>` where a type is expected; try `@Test<'a>`, `~Test<'a>`, or `&Test<'a>`
a.rs:22 fn run_test<'a>(test: Test<'a>) {
                              ^~~~~~~~
error: aborting due to previous error

@erickt
Copy link
Contributor

erickt commented May 10, 2014

I've once again updated it to modern rust, and it compiles fine (although I'm tripping over #14098):

trait Test<'a> {
    fn method(&'a mut self);
}

struct RealTest<'a> {
    value: &'a mut int
}

impl<'a> RealTest<'a> {
    fn new<'a>(init: &'a mut int) -> RealTest<'a> {
        RealTest { value: init }
    }
}

impl<'a> Test<'a> for RealTest<'a> {
    fn method(&'a mut self) {
        *self.value += 1;
        println!("{}", *self.value);
    }
}

fn run_test<'a>(test: &'a mut Test<'a>) {
    test.method();
    //test.method();
}

fn main() {
    let mut cell = 0;
    {
        let mut test = RealTest::new(&mut cell);
        run_test(&mut test);
    }
    println!("{}", cell);
}

So I'm closing this bug.

@erickt erickt closed this as completed May 10, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

5 participants