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

internal compiler error: no ref #11450

Closed
hannobraun opened this issue Jan 10, 2014 · 1 comment · Fixed by #12638
Closed

internal compiler error: no ref #11450

hannobraun opened this issue Jan 10, 2014 · 1 comment · Fixed by #12638
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@hannobraun
Copy link

Compiling the following file:

// vec.rs

mod test {
    #[test]
    fn it_should_scale_a_vector() {
        ::Vec2 { x: 1.0, y: 2.0 } * 2.0
    }
}


pub struct Vec2 {
    x: f64,
    y: f64
}

impl Mul<Vec2, f64> for Vec2 {
    fn mul(&self, s: f64) -> Vec2 {
        Vec2 {
            x: self.x * s,
            y: self.y * s }
    }
}

Leads to the following error message:

$ rustc --test vec.rs 
vec.rs:6:31: 6:34 error: internal compiler error: no ref
This message reflects a bug in the Rust compiler. 
We would appreciate a bug report: https://github.com/mozilla/rust/wiki/HOWTO-submit-a-Rust-bug-report
vec.rs:6        ::Vec2 { x: 1.0, y: 2.0 } * 2.0
                                            ^~~
task 'rustc' failed at 'explicit failure', /home/hanno/Desktop/Stuff/tmp/rust/src/libsyntax/diagnostic.rs:41
task '<main>' failed at 'explicit failure', /home/hanno/Desktop/Stuff/tmp/rust/src/librustc/lib.rs:453

Rust version:

$ rustc --version
rustc 0.9 (6ea218d 2014-01-09 23:26:20 -0800)
host: x86_64-unknown-linux-gnu

Please note that moving the test function into the top-level module reveals what seems to be the root cause of the problem.

New file:

// vec.rs

pub struct Vec2 {
    x: f64,
    y: f64
}

impl Mul<Vec2, f64> for Vec2 {
    fn mul(&self, s: f64) -> Vec2 {
        Vec2 {
            x: self.x * s,
            y: self.y * s }
    }
}

#[test]
fn it_should_scale_a_vector() {
    ::Vec2 { x: 1.0, y: 2.0 } * 2.0
}

New compiler error:

$ rustc --test vec.rs 
vec.rs:9:2: 13:3 error: method `mul` has an incompatible type: expected &-ptr but found f64
vec.rs:9    fn mul(&self, s: f64) -> Vec2 {
vec.rs:10       Vec2 {
vec.rs:11           x: self.x * s,
vec.rs:12           y: self.y * s }
vec.rs:13   }
vec.rs:18:30: 18:33 error: internal compiler error: no ref
This message reflects a bug in the Rust compiler. 
We would appreciate a bug report: https://github.com/mozilla/rust/wiki/HOWTO-submit-a-Rust-bug-report
vec.rs:18   ::Vec2 { x: 1.0, y: 2.0 } * 2.0
                                        ^~~
task 'rustc' failed at 'explicit failure', /home/hanno/Desktop/Stuff/tmp/rust/src/libsyntax/diagnostic.rs:41
task '<main>' failed at 'explicit failure', /home/hanno/Desktop/Stuff/tmp/rust/src/librustc/lib.rs:453

This fixed version compiles without any errors:

// vec.rs

pub struct Vec2 {
    x: f64,
    y: f64
}

impl Mul<f64, Vec2> for Vec2 {
    fn mul(&self, s: &f64) -> Vec2 {
        Vec2 {
            x: self.x * *s,
            y: self.y * *s }
    }
}

#[test]
fn it_should_scale_a_vector() {
    ::Vec2 { x: 1.0, y: 2.0 } * 2.0;
}
@luqmana
Copy link
Member

luqmana commented Mar 1, 2014

So, the easy fix for this (as seen above) is to correct the signature of the mul method since the Mul trait expects the argument to be of the type &RHS (so in your case &f64 instead of just f64).

The reason for the ICE is because for operators rustc does a little bit of magic. Notice that while you implement the Mul trait for some type &T (i.e a reference to some T), you can simply do Vec2 {..} * 2.0f32. That is, 2.0f32 is f32 and not &f32. This works because rustc will automatically take a reference. So what's happening is that with foo * T, the compiler is expecting the mul method to take some &U and then it can compare to make sure T == U (or more specifically that T coerces to U). But in this case, the argument of the mul method is not a reference and hence the "no ref" error.

I don't think we should ICE in this case since we do catch the mismatched trait/impl method and hence provide a better error message that way. (As you can see if you move the impl Mul block higher like in the second code example).

bors added a commit that referenced this issue Mar 1, 2014
From my comment on #11450:

The reason for the ICE is because for operators `rustc` does a little bit of magic. Notice that while you implement the `Mul` trait for some type `&T` (i.e a reference to some T), you can simply do `Vec2 {..} * 2.0f32`. That is, `2.0f32` is `f32` and not `&f32`. This works because `rustc` will automatically take a reference. So what's happening is that with `foo * T`, the compiler is expecting the `mul` method to take some `&U` and then it can compare to make sure `T == U` (or more specifically that `T` coerces to `U`). But in this case, the argument of the `mul` method is not a reference and hence the "no ref" error.

I don't think we should ICE in this case since we do catch the mismatched trait/impl method and hence provide a better error message that way.

Fixes #11450
@luqmana luqmana closed this as completed in a174941 Mar 1, 2014
flip1995 pushed a commit to flip1995/rust that referenced this issue Sep 7, 2023
`never_loop` catches `loop { panic!() }`

* Depends on: rust-lang#11447

This is an outgrowth of rust-lang#11447 which I felt would best be done as a separate PR because it yields significant new results.

This uses typecheck results to determine divergence, meaning we can now detect cases like `loop { std::process::abort() }` or `loop { panic!() }`. A downside is that `loop { unimplemented!() }` is also being linted, which is arguably a false positive. I'm not really sure how to check this from HIR though, and it seems best to leave this epicycle for a later PR.

changelog: [`never_loop`]: Now lints on `loop { panic!() }` and similar constructs
flip1995 pushed a commit to flip1995/rust that referenced this issue Sep 7, 2023
skip `todo!()` in  `never_loop`

As promised in rust-lang#11450, here is an implementation which skips occurrences of the `todo!()` macro.

changelog: [`never_loop`]: skip loops containing `todo!()`
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

Successfully merging a pull request may close this issue.

3 participants