mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #57205 - petrochenkov:extrecov, r=estebank
Improve error recovery for some built-in macros Fixes https://github.com/rust-lang/rust/issues/55897
This commit is contained in:
commit
953a9cf10d
@ -995,7 +995,7 @@ pub fn expr_to_spanned_string<'a>(
|
|||||||
cx: &'a mut ExtCtxt,
|
cx: &'a mut ExtCtxt,
|
||||||
expr: P<ast::Expr>,
|
expr: P<ast::Expr>,
|
||||||
err_msg: &str,
|
err_msg: &str,
|
||||||
) -> Result<Spanned<(Symbol, ast::StrStyle)>, DiagnosticBuilder<'a>> {
|
) -> Result<Spanned<(Symbol, ast::StrStyle)>, Option<DiagnosticBuilder<'a>>> {
|
||||||
// Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation.
|
// Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation.
|
||||||
let expr = expr.map(|mut expr| {
|
let expr = expr.map(|mut expr| {
|
||||||
expr.span = expr.span.apply_mark(cx.current_expansion.mark);
|
expr.span = expr.span.apply_mark(cx.current_expansion.mark);
|
||||||
@ -1007,16 +1007,17 @@ pub fn expr_to_spanned_string<'a>(
|
|||||||
Err(match expr.node {
|
Err(match expr.node {
|
||||||
ast::ExprKind::Lit(ref l) => match l.node {
|
ast::ExprKind::Lit(ref l) => match l.node {
|
||||||
ast::LitKind::Str(s, style) => return Ok(respan(expr.span, (s, style))),
|
ast::LitKind::Str(s, style) => return Ok(respan(expr.span, (s, style))),
|
||||||
_ => cx.struct_span_err(l.span, err_msg)
|
_ => Some(cx.struct_span_err(l.span, err_msg))
|
||||||
},
|
},
|
||||||
_ => cx.struct_span_err(expr.span, err_msg)
|
ast::ExprKind::Err => None,
|
||||||
|
_ => Some(cx.struct_span_err(expr.span, err_msg))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_to_string(cx: &mut ExtCtxt, expr: P<ast::Expr>, err_msg: &str)
|
pub fn expr_to_string(cx: &mut ExtCtxt, expr: P<ast::Expr>, err_msg: &str)
|
||||||
-> Option<(Symbol, ast::StrStyle)> {
|
-> Option<(Symbol, ast::StrStyle)> {
|
||||||
expr_to_spanned_string(cx, expr, err_msg)
|
expr_to_spanned_string(cx, expr, err_msg)
|
||||||
.map_err(|mut err| err.emit())
|
.map_err(|err| err.map(|mut err| err.emit()))
|
||||||
.ok()
|
.ok()
|
||||||
.map(|s| s.node)
|
.map(|s| s.node)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T
|
|||||||
-> Box<dyn base::MacResult+'cx> {
|
-> Box<dyn base::MacResult+'cx> {
|
||||||
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
|
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
|
||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
None => return DummyResult::expr(sp),
|
None => return DummyResult::any(sp),
|
||||||
};
|
};
|
||||||
// The file will be added to the code map by the parser
|
// The file will be added to the code map by the parser
|
||||||
let path = res_rel_file(cx, sp, file);
|
let path = res_rel_file(cx, sp, file);
|
||||||
|
@ -10,7 +10,7 @@ pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt,
|
|||||||
tts: &[tokenstream::TokenTree])
|
tts: &[tokenstream::TokenTree])
|
||||||
-> Box<dyn base::MacResult + 'cx> {
|
-> Box<dyn base::MacResult + 'cx> {
|
||||||
let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
|
let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
|
||||||
None => return DummyResult::expr(sp),
|
None => return DummyResult::any(sp),
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ pub fn expand_syntax_ext(
|
|||||||
};
|
};
|
||||||
let mut accumulator = String::new();
|
let mut accumulator = String::new();
|
||||||
let mut missing_literal = vec![];
|
let mut missing_literal = vec![];
|
||||||
|
let mut has_errors = false;
|
||||||
for e in es {
|
for e in es {
|
||||||
match e.node {
|
match e.node {
|
||||||
ast::ExprKind::Lit(ref lit) => match lit.node {
|
ast::ExprKind::Lit(ref lit) => match lit.node {
|
||||||
@ -41,6 +42,9 @@ pub fn expand_syntax_ext(
|
|||||||
cx.span_err(e.span, "cannot concatenate a byte string literal");
|
cx.span_err(e.span, "cannot concatenate a byte string literal");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ast::ExprKind::Err => {
|
||||||
|
has_errors = true;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
missing_literal.push(e.span);
|
missing_literal.push(e.span);
|
||||||
}
|
}
|
||||||
@ -50,6 +54,9 @@ pub fn expand_syntax_ext(
|
|||||||
let mut err = cx.struct_span_err(missing_literal, "expected a literal");
|
let mut err = cx.struct_span_err(missing_literal, "expected a literal");
|
||||||
err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`");
|
err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`");
|
||||||
err.emit();
|
err.emit();
|
||||||
|
return base::DummyResult::expr(sp);
|
||||||
|
} else if has_errors {
|
||||||
|
return base::DummyResult::expr(sp);
|
||||||
}
|
}
|
||||||
let sp = sp.apply_mark(cx.current_expansion.mark);
|
let sp = sp.apply_mark(cx.current_expansion.mark);
|
||||||
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
|
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
|
||||||
|
@ -24,7 +24,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
|
|||||||
|
|
||||||
if tts.is_empty() {
|
if tts.is_empty() {
|
||||||
cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
|
cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
|
||||||
return DummyResult::expr(sp);
|
return DummyResult::any(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut res_str = String::new();
|
let mut res_str = String::new();
|
||||||
@ -34,7 +34,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
|
|||||||
TokenTree::Token(_, token::Comma) => {}
|
TokenTree::Token(_, token::Comma) => {}
|
||||||
_ => {
|
_ => {
|
||||||
cx.span_err(sp, "concat_idents! expecting comma.");
|
cx.span_err(sp, "concat_idents! expecting comma.");
|
||||||
return DummyResult::expr(sp);
|
return DummyResult::any(sp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -43,7 +43,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
|
|||||||
res_str.push_str(&ident.as_str()),
|
res_str.push_str(&ident.as_str()),
|
||||||
_ => {
|
_ => {
|
||||||
cx.span_err(sp, "concat_idents! requires ident args.");
|
cx.span_err(sp, "concat_idents! requires ident args.");
|
||||||
return DummyResult::expr(sp);
|
return DummyResult::any(sp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt,
|
|||||||
let e = match env::var(&*var.as_str()) {
|
let e = match env::var(&*var.as_str()) {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
cx.span_err(sp, &msg.as_str());
|
cx.span_err(sp, &msg.as_str());
|
||||||
cx.expr_usize(sp, 0)
|
return DummyResult::expr(sp);
|
||||||
}
|
}
|
||||||
Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
|
Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
|
||||||
};
|
};
|
||||||
|
@ -748,18 +748,20 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
|
|||||||
fmt
|
fmt
|
||||||
}
|
}
|
||||||
Ok(fmt) => fmt,
|
Ok(fmt) => fmt,
|
||||||
Err(mut err) => {
|
Err(err) => {
|
||||||
let sugg_fmt = match args.len() {
|
if let Some(mut err) = err {
|
||||||
0 => "{}".to_string(),
|
let sugg_fmt = match args.len() {
|
||||||
_ => format!("{}{{}}", "{} ".repeat(args.len())),
|
0 => "{}".to_string(),
|
||||||
};
|
_ => format!("{}{{}}", "{} ".repeat(args.len())),
|
||||||
err.span_suggestion_with_applicability(
|
};
|
||||||
fmt_sp.shrink_to_lo(),
|
err.span_suggestion_with_applicability(
|
||||||
"you might be missing a string literal to format with",
|
fmt_sp.shrink_to_lo(),
|
||||||
format!("\"{}\", ", sugg_fmt),
|
"you might be missing a string literal to format with",
|
||||||
Applicability::MaybeIncorrect,
|
format!("\"{}\", ", sugg_fmt),
|
||||||
);
|
Applicability::MaybeIncorrect,
|
||||||
err.emit();
|
);
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
return DummyResult::raw_expr(sp, true);
|
return DummyResult::raw_expr(sp, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
15
src/test/ui/extenv/issue-55897.rs
Normal file
15
src/test/ui/extenv/issue-55897.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
use prelude::*; //~ ERROR unresolved import `prelude`
|
||||||
|
|
||||||
|
mod unresolved_env {
|
||||||
|
use env;
|
||||||
|
|
||||||
|
include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
|
||||||
|
//~^ ERROR cannot determine resolution for the macro `env`
|
||||||
|
}
|
||||||
|
|
||||||
|
mod nonexistent_env {
|
||||||
|
include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
|
||||||
|
//~^ ERROR environment variable `NON_EXISTENT` not defined
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
23
src/test/ui/extenv/issue-55897.stderr
Normal file
23
src/test/ui/extenv/issue-55897.stderr
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
error: environment variable `NON_EXISTENT` not defined
|
||||||
|
--> $DIR/issue-55897.rs:11:22
|
||||||
|
|
|
||||||
|
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0432]: unresolved import `prelude`
|
||||||
|
--> $DIR/issue-55897.rs:1:5
|
||||||
|
|
|
||||||
|
LL | use prelude::*; //~ ERROR unresolved import `prelude`
|
||||||
|
| ^^^^^^^ did you mean `std::prelude`?
|
||||||
|
|
||||||
|
error: cannot determine resolution for the macro `env`
|
||||||
|
--> $DIR/issue-55897.rs:6:22
|
||||||
|
|
|
||||||
|
LL | include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= note: import resolution is stuck, try simplifying macro imports
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0432`.
|
@ -1,5 +1,3 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
print!(testo!());
|
print!(testo!()); //~ ERROR cannot find macro `testo!` in this scope
|
||||||
//~^ ERROR: format argument must be a string literal
|
|
||||||
//~| ERROR: cannot find macro `testo!` in this scope
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,8 @@
|
|||||||
error: format argument must be a string literal
|
|
||||||
--> $DIR/issue-11692-1.rs:2:12
|
|
||||||
|
|
|
||||||
LL | print!(testo!());
|
|
||||||
| ^^^^^^^^
|
|
||||||
help: you might be missing a string literal to format with
|
|
||||||
|
|
|
||||||
LL | print!("{}", testo!());
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error: cannot find macro `testo!` in this scope
|
error: cannot find macro `testo!` in this scope
|
||||||
--> $DIR/issue-11692-1.rs:2:12
|
--> $DIR/issue-11692-1.rs:2:12
|
||||||
|
|
|
|
||||||
LL | print!(testo!());
|
LL | print!(testo!()); //~ ERROR cannot find macro `testo!` in this scope
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
|
concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
|
||||||
//~| ERROR expected a literal
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
error: expected a literal
|
|
||||||
--> $DIR/issue-11692-2.rs:2:13
|
|
||||||
|
|
|
||||||
LL | concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
|
||||||
= note: only literals (like `"foo"`, `42` and `3.14`) can be passed to `concat!()`
|
|
||||||
|
|
||||||
error: cannot find macro `test!` in this scope
|
error: cannot find macro `test!` in this scope
|
||||||
--> $DIR/issue-11692-2.rs:2:13
|
--> $DIR/issue-11692-2.rs:2:13
|
||||||
|
|
|
|
||||||
LL | concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
|
LL | concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user