Skip to content

Commit 3c6aa76

Browse files
committed
Improve panic messages by embedding location
1 parent 2c7392d commit 3c6aa76

File tree

7 files changed

+33
-11
lines changed

7 files changed

+33
-11
lines changed

src/discouraged.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub trait Speculative {
167167
impl<'a> Speculative for ParseBuffer<'a> {
168168
fn advance_to(&self, fork: &Self) {
169169
if !crate::buffer::same_scope(self.cursor(), fork.cursor()) {
170-
panic!("fork was not derived from the advancing parse stream");
170+
crate::panic_with_location!("fork was not derived from the advancing parse stream");
171171
}
172172

173173
let (self_unexp, self_sp) = inner_unexpected(self);

src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,3 +1013,25 @@ pub fn parse_file(mut content: &str) -> Result<File> {
10131013
file.shebang = shebang;
10141014
Ok(file)
10151015
}
1016+
1017+
/// `panic!` macro that includes location information [file:line:column]
1018+
/// when inside of a proc-macro, because otherwise you don't get this information without
1019+
/// -Zmacro-backtrace, and enabling it is an extra step which makes debugging proc macros harder
1020+
macro_rules! panic_with_location {
1021+
($message:literal $($tt:tt)*) => {{
1022+
#[cfg(feature = "proc-macro")]
1023+
let is_available = proc_macro::is_available();
1024+
#[cfg(not(feature = "proc-macro"))]
1025+
let is_available = false;
1026+
if is_available {
1027+
let location = core::panic::Location::caller();
1028+
let file = location.file();
1029+
let line = location.line();
1030+
let column = location.column();
1031+
::core::panic!(concat!("[{}:{}:{}] ", $message), file, line, column $($tt)*)
1032+
} else {
1033+
::core::panic!($message $($tt)*)
1034+
}
1035+
}};
1036+
}
1037+
pub(crate) use panic_with_location;

src/lifetime.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,18 @@ impl Lifetime {
3737
/// ```
3838
pub fn new(symbol: &str, span: Span) -> Self {
3939
if !symbol.starts_with('\'') {
40-
panic!(
40+
crate::panic_with_location!(
4141
"lifetime name must start with apostrophe as in \"'a\", got {:?}",
4242
symbol
4343
);
4444
}
4545

4646
if symbol == "'" {
47-
panic!("lifetime name must not be empty");
47+
crate::panic_with_location!("lifetime name must not be empty");
4848
}
4949

5050
if !crate::ident::xid_ok(&symbol[1..]) {
51-
panic!("{:?} is not a valid lifetime name", symbol);
51+
crate::panic_with_location!("{:?} is not a valid lifetime name", symbol);
5252
}
5353

5454
Lifetime {

src/lit.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ impl LitInt {
424424
pub fn new(repr: &str, span: Span) -> Self {
425425
let (digits, suffix) = match value::parse_lit_int(repr) {
426426
Some(parse) => parse,
427-
None => panic!("not an integer literal: `{}`", repr),
427+
None => crate::panic_with_location!("not an integer literal: `{}`", repr),
428428
};
429429

430430
let mut token: Literal = repr.parse().unwrap();
@@ -504,7 +504,7 @@ impl From<Literal> for LitInt {
504504
}),
505505
}
506506
} else {
507-
panic!("not an integer literal: `{}`", repr);
507+
crate::panic_with_location!("not an integer literal: `{}`", repr);
508508
}
509509
}
510510
}
@@ -520,7 +520,7 @@ impl LitFloat {
520520
pub fn new(repr: &str, span: Span) -> Self {
521521
let (digits, suffix) = match value::parse_lit_float(repr) {
522522
Some(parse) => parse,
523-
None => panic!("not a float literal: `{}`", repr),
523+
None => crate::panic_with_location!("not a float literal: `{}`", repr),
524524
};
525525

526526
let mut token: Literal = repr.parse().unwrap();
@@ -578,7 +578,7 @@ impl From<Literal> for LitFloat {
578578
}),
579579
}
580580
} else {
581-
panic!("not a float literal: `{}`", repr);
581+
crate::panic_with_location!("not a float literal: `{}`", repr);
582582
}
583583
}
584584
}

src/parse_quote.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub fn parse<T: ParseQuote>(token_stream: TokenStream) -> T {
133133
let parser = T::parse;
134134
match parser.parse2(token_stream) {
135135
Ok(t) => t,
136-
Err(err) => panic!("{}", err),
136+
Err(err) => crate::panic_with_location!("{}", err),
137137
}
138138
}
139139

src/punctuated.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ where
504504
let mut nomore = false;
505505
for pair in i {
506506
if nomore {
507-
panic!("punctuated extended with items after a Pair::End");
507+
crate::panic_with_location!("punctuated extended with items after a Pair::End");
508508
}
509509
match pair {
510510
Pair::Punctuated(a, b) => punctuated.inner.push((a, b)),

src/verbatim.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub(crate) fn between<'a>(begin: ParseStream<'a>, end: ParseStream<'a>) -> Token
2222
cursor = inside;
2323
continue;
2424
} else {
25-
panic!("verbatim end must not be inside a delimited group");
25+
crate::panic_with_location!("verbatim end must not be inside a delimited group");
2626
}
2727
}
2828

0 commit comments

Comments
 (0)