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 on assert!("test") #28308

Closed
wesleywiser opened this issue Sep 9, 2015 · 2 comments
Closed

ICE on assert!("test") #28308

wesleywiser opened this issue Sep 9, 2015 · 2 comments
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@wesleywiser
Copy link
Member

While playing around on the playground, I found that this reports an ICE:

fn main() {
    assert!("test");
}
<std macros>:2:4: 2:19 error: cannot apply unary operator `!` to type `&'static str`
(internal compiler error: unprintable span)
<std macros>:1:1: 5:46 note: in expansion of assert!
<anon>:2:5: 2:21 note: expansion site
error: aborting due to previous error
playpen: application terminated with error code 101

This repros on stable, beta, and nightly

@steveklabnik steveklabnik added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Sep 28, 2015
steveklabnik added a commit to rust-lang/glacier that referenced this issue Oct 23, 2015
steveklabnik added a commit to rust-lang/glacier that referenced this issue Oct 23, 2015
@jld
Copy link
Contributor

jld commented Dec 11, 2015

I ran into this by accidentally typing assert! instead of assert_eq! too early in the morning, so I did some git grep and experimenting, and I think I know what's happening here: this is a SpanLinesError::DistinctSources, because assert! expands to if !$cond { ... }, so the compiler wants to complain about !$cond, and it sees that that expression starts at the ! in libcore/macros.rs and ends at the end of… the expression given as the $cond argument to the macro in the code being compiled.

There's an easier way to see this:

#![allow(unused_parens)]
macro_rules! my_assert1 { ($e:expr) => { if !$e { panic!() } } }
macro_rules! my_assert2 { ($e:expr) => { if !($e) { panic!() } } }
// Meaningless text goes here
// And some more meaningless text
fn main() {
   my_assert2!("test");
}

This fails nicely:

issue28308.rs:3:45: 3:50 error: cannot apply unary operator `!` to type `&'static str`
issue28308.rs:3 macro_rules! my_assert2 { ($e:expr) => { if !($e) { panic!() } } }
                                                            ^~~~~
issue28308.rs:7:4: 7:24 note: in this expansion of my_assert2! (defined in issue28308.rs)

But change the last part to my_assert1!:

issue28308.rs:2:45: 7:22 error: cannot apply unary operator `!` to type `&'static str`
issue28308.rs:2 macro_rules! my_assert1 { ($e:expr) => { if !$e { panic!() } } }
issue28308.rs:3 macro_rules! my_assert2 { ($e:expr) => { if !($e) { panic!() } } }
issue28308.rs:4 // Meaningless text goes here
issue28308.rs:5 // And some more meaningless text
issue28308.rs:6 fn main() {
issue28308.rs:7    my_assert1!("test");
issue28308.rs:7:4: 7:24 note: in this expansion of my_assert1! (defined in issue28308.rs)

Alternately, with a macro variable at the start of an offending expression, like this:

macro_rules! as_isize { ($e:expr) => { $e as isize } }
fn main() { as_isize!("test"); }

…we get the other kind of unprintable span, where the beginning is after the end:

issue28308alt.rs:2:23: 1:51 error: casting `&'static str` as `isize` is invalid
(internal compiler error: unprintable span)

@jld
Copy link
Contributor

jld commented Dec 11, 2015

It looks like #25385 already discovered that last one.

bors added a commit that referenced this issue Jan 27, 2016
This is a  work in progress PR that potentially should fix #29084, #28308, #25385, #28288, #31011. I think this may also adresse parts of  #2887.

The problem in this issues seems to be that when transcribing macro arguments, we just clone the argument Nonterminal, which still has to original spans. This leads to the unprintable spans. One solution would be to update the spans of the inserted argument to match the argument in the macro definition. So for [this testcase](https://github.com/rust-lang/rust/compare/master...fhahn:macro-ice?expand=1#diff-f7def7420c51621640707b6337726876R2) the error message would be displayed in the macro definition:

    src/test/compile-fail/issue-31011.rs:4:12: 4:22 error: attempted access of field `trace` on type `&T`, but no field with that name was found
    src/test/compile-fail/issue-31011.rs:4         if $ctx.trace {

Currently I've added a very simple `update_span` function, which updates the span of the outer-most expression of a `NtExpr`, but this `update_span` function should be updated to handle all Nonterminals. But I'm pretty new to the macro system and would like to check if this approach makes sense, before doing that.
@bors bors closed this as completed in b285ebc Jan 27, 2016
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

3 participants