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: unprintable span #26480

Closed
strega-nil opened this issue Jun 21, 2015 · 2 comments
Closed

ICE: unprintable span #26480

strega-nil opened this issue Jun 21, 2015 · 2 comments
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@strega-nil
Copy link
Contributor

I don't know the version, but play.rust-lang.org nightly (and stable, for that matter, as well -- the error printed there is thread 'rustc' panicked at 'capacity overflow').

This is a weird one:

extern {
    fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
}

#[inline(always)]
fn size_of<T>(_: T) -> usize {
    ::std::mem::size_of::<T>()
}

macro_rules! write {
    ($arr:expr) => {{
        #[allow(non_upper_case_globals)]
        const stdout: i32 = 1;
        unsafe {
            write(stdout, $arr.as_ptr() as *const i8,
                  $arr.len() * size_of($arr[0]));
        }
    }}
}

fn main() {
    let hello = ['H', 'e', 'y'];
    write!(hello);
}

errors with

<anon>:23:12: 16:48 error: mismatched types:
 expected `u64`,
    found `usize`
(expected u64,
    found usize) [E0308]
(internal compiler error: unprintable span) # << Notice the ICE
<anon>:10:1: 19:2 note: in expansion of write!
<anon>:23:5: 23:19 note: expansion site
<anon>:23:12: 16:48 help: see the detailed explanation for E0308
error: aborting due to previous error
playpen: application terminated with error code 101

But, if you add parentheses around $arr.len() * size_of($arr[0]), the ICE disappears, and

<anon>:16:19: 16:50 error: mismatched types:
 expected `u64`,
    found `usize`
(expected u64,
    found usize) [E0308]
<anon>:16                   ($arr.len() * size_of($arr[0])));
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:10:1: 19:2 note: in expansion of write!
<anon>:23:5: 23:19 note: expansion site
<anon>:16:19: 16:50 help: see the detailed explanation for E0308
error: aborting due to previous error
playpen: application terminated with error code 101

is printed instead.

Also, on a completely unrelated note, a C-style sizeof(x) would be very useful, instead of having to use size_of::<T>().

@jdm jdm added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jun 21, 2015
@KokaKiwi
Copy link

KokaKiwi commented Jul 2, 2015

Had the same issue, it seems to me that it's caused by macros: https://gist.github.com/2084b4bb800dd6a08939

macro_rules! jerry(
    ($name:expr) => {
        pub static NAME: *mut u8 = $name as *mut u8;
    }
);

jerry!(b"Kiwi\0");
lib.rs:8:8: 4:52 error: illegal cast: `&'static [u8; 5]` as `*mut u8`
(internal compiler error: unprintable span)
lib.rs:2:1: 6:3 note: in expansion of jerry!
lib.rs:8:1: 8:19 note: expansion site
error: aborting due to previous error

@chris-morgan
Copy link
Member

I just hit this myself. Most error spans deal with only a single token tree, but the one around casts is different as the start and end points come from two different token trees, because it’s EXPR as TY. In these cases where the expression is a macro argument and the type is written inline, you then end up with a span starting inside the macro invocation site but ending inside the macro definition. This span, quite understandably, cannot be printed.

Minimal test case:

macro_rules! cast {
    ($x:expr) => ($x as ())
}

fn main() {
    cast!(2);
}
<anon>:6:11: 2:27 error: non-scalar cast: `i32` as `()`
(internal compiler error: unprintable span)
<anon>:1:1: 3:2 note: in expansion of cast!
<anon>:6:5: 6:14 note: expansion site
error: aborting due to previous error

Of course, if the expression and type both come from the macro invocation and are in order, you’ll end up with a rather odd span too:

macro_rules! cast_aspersions {
    ($expr:expr, various stuff here, $ty:ty) => ($expr as $ty)
}

fn main() {
    cast_aspersions!(2, various stuff here, ());
}
<anon>:6:22: 6:47 error: non-scalar cast: `i32` as `()`
<anon>:6     cast_aspersions!(2, various stuff here, ());
                              ^~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:1:1: 3:2 note: in expansion of cast_aspersions!
<anon>:6:5: 6:49 note: expansion site
error: aborting due to previous error

Really, for an error like this you need two distinct spans rather than one like these two examples below. I wonder how many other of our error messages are like that?

<anon>:6:22: 6:47 error: non-scalar cast: `i32` as `()`
<anon>:6     cast_aspersions!(2, various stuff here, ());
                              ^                      ^~
<anon>:1:1: 3:2 note: in expansion of cast_aspersions!
<anon>:6:5: 6:49 note: expansion site
error: aborting due to previous error
<anon>:6:11: 2:27 error: non-scalar cast: `i32` as `()`
<anon>:6     cast!(2);
                   ^
<anon>:2     ($x:expr) => ($x as ())
                                 ^~
<anon>:1:1: 3:2 note: in expansion of cast!
<anon>:6:5: 6:14 note: expansion site
error: aborting due to previous error

I think this should be labelled A-diagnostics; it doesn’t hold up compilation, just causes it to be unable to print that span.

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

4 participants