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

Make macro expansion backtraces shorter #28351

Merged
merged 4 commits into from
Sep 15, 2015
Merged

Make macro expansion backtraces shorter #28351

merged 4 commits into from
Sep 15, 2015

Conversation

jonas-schievink
Copy link
Contributor

The second commit in this PR will stop printing the macro definition site in backtraces, which cuts their length in half and increases readability (the definition site was only correct for local macros).

The third commit will not print an invocation if the last one printed occurred at the same place (span). This will make backtraces caused by a self-recursive macro much shorter.

(A possible alternative would be to capture the backtrace first, then limit it to a few frames at the start and end of the chain and print ... inbetween. This would also work with multiple macros calling each other, which is not addressed by this PR - although the backtrace will still be halved)

Example:

macro_rules! m {
 ( 0 $($t:tt)* ) => ( m!($($t)*); );
 () => ( fn main() {0} );
}

m!(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0);

On a semi-recent nightly, this yields:

test.rs:3:21: 3:22 error: mismatched types:
 expected `()`,
    found `_`
(expected (),
    found integral variable) [E0308]
test.rs:3  () => ( fn main() {0} );
                              ^
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:6:1: 6:35 note: expansion site
test.rs:3:21: 3:22 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error

After this patch:

test.rs:3:21: 3:22 error: mismatched types:
 expected `()`,
    found `_`
(expected (),
    found integral variable) [E0308]
test.rs:3  () => ( fn main() {0} );
                              ^
test.rs:2:23: 2:34 note: in this expansion of m!
test.rs:6:1: 6:35 note: in this expansion of m!
test.rs:3:21: 3:22 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error

This halves the backtrace length. The definition site wasn't very useful
anyways, since it may be invalid (for compiler expansions) or located in
another crate. Since the macro name is still printed, grepping for it is
still an easy way of finding the definition.
@rust-highfive
Copy link
Collaborator

r? @nrc

(rust_highfive has picked a reviewer for you, use r? to override)

@jonas-schievink
Copy link
Contributor Author

Another option that doesn't lose the macro definition site completely would be:

test.rs:6:1: 6:35 note: in this expansion of m! (defined in test.rs)
test.rs:6:1: 6:35 note: in this expansion of println! (defined in <std macros>)
test.rs:6:1: 6:35 note: in this expansion of for loop expansion

Codemap::span_to_filename() should work for this

@nrc
Copy link
Member

nrc commented Sep 14, 2015

@jonas-schievink the last option you suggest in the comment sounds like a good compromise to me. I am often frustrated by these macro expansion back traces, but OTOH I have occasionally found the definition site of the macro useful.

cc @rust-lang/compiler

@jonas-schievink
Copy link
Contributor Author

Done!

Example:

<std macros>:1:33: 1:58 error: invalid reference to argument `0` (no arguments given)
<std macros>:1 ( $ fmt : expr ) => ( print ! ( concat ! ( $ fmt , "\n" ) ) ) ; (
                                               ^~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:1:33: 1:58 note: in this expansion of concat!
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:1:23: 1:60 note: in this expansion of print! (defined in <std macros>)
test.rs:3:25: 3:39 note: in this expansion of println! (defined in <std macros>)
test.rs:2:26: 2:37 note: in this expansion of m! (defined in test.rs)
test.rs:6:1: 6:35 note: in this expansion of m! (defined in test.rs)
error: aborting due to previous error

@eddyb
Copy link
Member

eddyb commented Sep 14, 2015

👍 This looks nice.

@nikomatsakis
Copy link
Contributor

Certainly progress.

@Aatch
Copy link
Contributor

Aatch commented Sep 14, 2015

Looks good to me. I wonder if having the line/column in the "defined in file.rs" would be good. So note: in this expansion of m! (defined in test.rs:6:1).

@jonas-schievink
Copy link
Contributor Author

@Aatch Since the spans are only correct for the local crate, in which I usually know where macros are defined (and grepping is trivial, especially when the file name is given), this would require checking if the macro is defined in the current crate, which - at a first glance - doesn't seem easy. Or just print <std macros>:1:1 like it's done now (ugh!).

@Aatch
Copy link
Contributor

Aatch commented Sep 14, 2015

@jonas-schievink fair enough, just a thought.

@nrc
Copy link
Member

nrc commented Sep 15, 2015

@bors: r+

@bors
Copy link
Contributor

bors commented Sep 15, 2015

📌 Commit 0be755c has been approved by nrc

@bors
Copy link
Contributor

bors commented Sep 15, 2015

⌛ Testing commit 0be755c with merge f3e6d31...

bors added a commit that referenced this pull request Sep 15, 2015
The second commit in this PR will stop printing the macro definition site in backtraces, which cuts their length in half and increases readability (the definition site was only correct for local macros).

The third commit will not print an invocation if the last one printed occurred at the same place (span). This will make backtraces caused by a self-recursive macro much shorter.

(A possible alternative would be to capture the backtrace first, then limit it to a few frames at the start and end of the chain and print `...` inbetween. This would also work with multiple macros calling each other, which is not addressed by this PR - although the backtrace will still be halved)

Example:
```rust
macro_rules! m {
 ( 0 $($t:tt)* ) => ( m!($($t)*); );
 () => ( fn main() {0} );
}

m!(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0);
```

On a semi-recent nightly, this yields:
```
test.rs:3:21: 3:22 error: mismatched types:
 expected `()`,
    found `_`
(expected (),
    found integral variable) [E0308]
test.rs:3  () => ( fn main() {0} );
                              ^
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:2:23: 2:34 note: expansion site
test.rs:1:1: 4:2 note: in expansion of m!
test.rs:6:1: 6:35 note: expansion site
test.rs:3:21: 3:22 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error
```

After this patch:
```
test.rs:3:21: 3:22 error: mismatched types:
 expected `()`,
    found `_`
(expected (),
    found integral variable) [E0308]
test.rs:3  () => ( fn main() {0} );
                              ^
test.rs:2:23: 2:34 note: in this expansion of m!
test.rs:6:1: 6:35 note: in this expansion of m!
test.rs:3:21: 3:22 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error
```
@bors bors merged commit 0be755c into rust-lang:master Sep 15, 2015
@jonas-schievink jonas-schievink deleted the macro-bt branch December 26, 2015 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants