Skip to content

Commit 953a9cf

Browse files
committed
Auto merge of #57205 - petrochenkov:extrecov, r=estebank
Improve error recovery for some built-in macros Fixes #55897
2 parents 3ce6f6e + df4690d commit 953a9cf

13 files changed

+74
-47
lines changed

src/libsyntax/ext/base.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@ pub fn expr_to_spanned_string<'a>(
995995
cx: &'a mut ExtCtxt,
996996
expr: P<ast::Expr>,
997997
err_msg: &str,
998-
) -> Result<Spanned<(Symbol, ast::StrStyle)>, DiagnosticBuilder<'a>> {
998+
) -> Result<Spanned<(Symbol, ast::StrStyle)>, Option<DiagnosticBuilder<'a>>> {
999999
// Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation.
10001000
let expr = expr.map(|mut expr| {
10011001
expr.span = expr.span.apply_mark(cx.current_expansion.mark);
@@ -1007,16 +1007,17 @@ pub fn expr_to_spanned_string<'a>(
10071007
Err(match expr.node {
10081008
ast::ExprKind::Lit(ref l) => match l.node {
10091009
ast::LitKind::Str(s, style) => return Ok(respan(expr.span, (s, style))),
1010-
_ => cx.struct_span_err(l.span, err_msg)
1010+
_ => Some(cx.struct_span_err(l.span, err_msg))
10111011
},
1012-
_ => cx.struct_span_err(expr.span, err_msg)
1012+
ast::ExprKind::Err => None,
1013+
_ => Some(cx.struct_span_err(expr.span, err_msg))
10131014
})
10141015
}
10151016

10161017
pub fn expr_to_string(cx: &mut ExtCtxt, expr: P<ast::Expr>, err_msg: &str)
10171018
-> Option<(Symbol, ast::StrStyle)> {
10181019
expr_to_spanned_string(cx, expr, err_msg)
1019-
.map_err(|mut err| err.emit())
1020+
.map_err(|err| err.map(|mut err| err.emit()))
10201021
.ok()
10211022
.map(|s| s.node)
10221023
}

src/libsyntax/ext/source_util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T
8686
-> Box<dyn base::MacResult+'cx> {
8787
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
8888
Some(f) => f,
89-
None => return DummyResult::expr(sp),
89+
None => return DummyResult::any(sp),
9090
};
9191
// The file will be added to the code map by the parser
9292
let path = res_rel_file(cx, sp, file);

src/libsyntax_ext/compile_error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt,
1010
tts: &[tokenstream::TokenTree])
1111
-> Box<dyn base::MacResult + 'cx> {
1212
let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
13-
None => return DummyResult::expr(sp),
13+
None => return DummyResult::any(sp),
1414
Some(v) => v,
1515
};
1616

src/libsyntax_ext/concat.rs

+7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub fn expand_syntax_ext(
1818
};
1919
let mut accumulator = String::new();
2020
let mut missing_literal = vec![];
21+
let mut has_errors = false;
2122
for e in es {
2223
match e.node {
2324
ast::ExprKind::Lit(ref lit) => match lit.node {
@@ -41,6 +42,9 @@ pub fn expand_syntax_ext(
4142
cx.span_err(e.span, "cannot concatenate a byte string literal");
4243
}
4344
},
45+
ast::ExprKind::Err => {
46+
has_errors = true;
47+
}
4448
_ => {
4549
missing_literal.push(e.span);
4650
}
@@ -50,6 +54,9 @@ pub fn expand_syntax_ext(
5054
let mut err = cx.struct_span_err(missing_literal, "expected a literal");
5155
err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`");
5256
err.emit();
57+
return base::DummyResult::expr(sp);
58+
} else if has_errors {
59+
return base::DummyResult::expr(sp);
5360
}
5461
let sp = sp.apply_mark(cx.current_expansion.mark);
5562
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))

src/libsyntax_ext/concat_idents.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
2424

2525
if tts.is_empty() {
2626
cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
27-
return DummyResult::expr(sp);
27+
return DummyResult::any(sp);
2828
}
2929

3030
let mut res_str = String::new();
@@ -34,7 +34,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
3434
TokenTree::Token(_, token::Comma) => {}
3535
_ => {
3636
cx.span_err(sp, "concat_idents! expecting comma.");
37-
return DummyResult::expr(sp);
37+
return DummyResult::any(sp);
3838
}
3939
}
4040
} else {
@@ -43,7 +43,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
4343
res_str.push_str(&ident.as_str()),
4444
_ => {
4545
cx.span_err(sp, "concat_idents! requires ident args.");
46-
return DummyResult::expr(sp);
46+
return DummyResult::any(sp);
4747
}
4848
}
4949
}

src/libsyntax_ext/env.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt,
7979
let e = match env::var(&*var.as_str()) {
8080
Err(_) => {
8181
cx.span_err(sp, &msg.as_str());
82-
cx.expr_usize(sp, 0)
82+
return DummyResult::expr(sp);
8383
}
8484
Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
8585
};

src/libsyntax_ext/format.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -748,18 +748,20 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
748748
fmt
749749
}
750750
Ok(fmt) => fmt,
751-
Err(mut err) => {
752-
let sugg_fmt = match args.len() {
753-
0 => "{}".to_string(),
754-
_ => format!("{}{{}}", "{} ".repeat(args.len())),
755-
};
756-
err.span_suggestion_with_applicability(
757-
fmt_sp.shrink_to_lo(),
758-
"you might be missing a string literal to format with",
759-
format!("\"{}\", ", sugg_fmt),
760-
Applicability::MaybeIncorrect,
761-
);
762-
err.emit();
751+
Err(err) => {
752+
if let Some(mut err) = err {
753+
let sugg_fmt = match args.len() {
754+
0 => "{}".to_string(),
755+
_ => format!("{}{{}}", "{} ".repeat(args.len())),
756+
};
757+
err.span_suggestion_with_applicability(
758+
fmt_sp.shrink_to_lo(),
759+
"you might be missing a string literal to format with",
760+
format!("\"{}\", ", sugg_fmt),
761+
Applicability::MaybeIncorrect,
762+
);
763+
err.emit();
764+
}
763765
return DummyResult::raw_expr(sp, true);
764766
}
765767
};

src/test/ui/extenv/issue-55897.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use prelude::*; //~ ERROR unresolved import `prelude`
2+
3+
mod unresolved_env {
4+
use env;
5+
6+
include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
7+
//~^ ERROR cannot determine resolution for the macro `env`
8+
}
9+
10+
mod nonexistent_env {
11+
include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
12+
//~^ ERROR environment variable `NON_EXISTENT` not defined
13+
}
14+
15+
fn main() {}

src/test/ui/extenv/issue-55897.stderr

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
error: environment variable `NON_EXISTENT` not defined
2+
--> $DIR/issue-55897.rs:11:22
3+
|
4+
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
7+
error[E0432]: unresolved import `prelude`
8+
--> $DIR/issue-55897.rs:1:5
9+
|
10+
LL | use prelude::*; //~ ERROR unresolved import `prelude`
11+
| ^^^^^^^ did you mean `std::prelude`?
12+
13+
error: cannot determine resolution for the macro `env`
14+
--> $DIR/issue-55897.rs:6:22
15+
|
16+
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
17+
| ^^^
18+
|
19+
= note: import resolution is stuck, try simplifying macro imports
20+
21+
error: aborting due to 3 previous errors
22+
23+
For more information about this error, try `rustc --explain E0432`.

src/test/ui/issues/issue-11692-1.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
fn main() {
2-
print!(testo!());
3-
//~^ ERROR: format argument must be a string literal
4-
//~| ERROR: cannot find macro `testo!` in this scope
2+
print!(testo!()); //~ ERROR cannot find macro `testo!` in this scope
53
}
+2-12
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,8 @@
1-
error: format argument must be a string literal
2-
--> $DIR/issue-11692-1.rs:2:12
3-
|
4-
LL | print!(testo!());
5-
| ^^^^^^^^
6-
help: you might be missing a string literal to format with
7-
|
8-
LL | print!("{}", testo!());
9-
| ^^^^^
10-
111
error: cannot find macro `testo!` in this scope
122
--> $DIR/issue-11692-1.rs:2:12
133
|
14-
LL | print!(testo!());
4+
LL | print!(testo!()); //~ ERROR cannot find macro `testo!` in this scope
155
| ^^^^^
166

17-
error: aborting due to 2 previous errors
7+
error: aborting due to previous error
188

src/test/ui/issues/issue-11692-2.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
fn main() {
22
concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
3-
//~| ERROR expected a literal
43
}
+1-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
1-
error: expected a literal
2-
--> $DIR/issue-11692-2.rs:2:13
3-
|
4-
LL | concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
5-
| ^^^^^^^
6-
|
7-
= note: only literals (like `"foo"`, `42` and `3.14`) can be passed to `concat!()`
8-
91
error: cannot find macro `test!` in this scope
102
--> $DIR/issue-11692-2.rs:2:13
113
|
124
LL | concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
135
| ^^^^
146

15-
error: aborting due to 2 previous errors
7+
error: aborting due to previous error
168

0 commit comments

Comments
 (0)