Skip to content

False double-borrow and/or ICE in macro expansion (only with macro arguments) #7971

Closed
@bblum

Description

@bblum
fn main() {
    macro_rules! foo(
        ($a: expr) => {{
            let mut x = ~[0];
            x.push($a);
            x.push($a);
        }}
    );
    foo!(1);
}

Error:

shit.rs:6:12: 6:13 error: cannot borrow `x` as mutable more than once at a time
shit.rs:6             x.push($a);
                      ^
shit.rs:2:4: 8:6 note: in expansion of foo!
shit.rs:9:4: 9:12 note: expansion site
shit.rs:6:12: 6:13 note: second borrow of `x` as mutable occurs here
shit.rs:6             x.push($a);
                      ^

If the macro is written with no arguments, or if the argument is not used in the expansion, then the error goes away. I believe the double-borrow error is because the borrow-checker tracks on a line-granularity instead of an expression-granularity, but I've no idea why the arguments affect it.

Here is a variation that causes an ICE instead:

fn main() {
    macro_rules! foo(
        ($a: expr) => {{
            let mut x = ~[$a];
            x.push(0);
            x.push($a);
        }}
    );
    foo!(1);
}

The ICE error, with an old build of rustc, is:

rust: task failed at 'assertion failed: region_maps.scopes_intersect(old_loan.kill_scope,
new_loan.kill_scope)', /home/bblum/rust/src/librustc/middle/borrowck/check_loans.rs:181

and with a new (today) build, is:

rust: task failed at 'index out of bounds: the len is 41 but the index is 41',
/home/bblum/rust/src/librustc/middle/lang_items.rs:374

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lifetimesArea: Lifetimes / regionsA-syntaxextArea: Syntax extensionsI-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions