From: Vadim Petrochenkov Date: Sat, 29 Dec 2018 21:56:55 +0000 (+0300) Subject: Improve error recovery for some built-in macros X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=df4690ddf4b6eb699bc5c283934c26f6c9a05df6;p=rust.git Improve error recovery for some built-in macros --- diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7e8b7007b22..2793754e103 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -995,7 +995,7 @@ pub fn expr_to_spanned_string<'a>( cx: &'a mut ExtCtxt, expr: P, err_msg: &str, -) -> Result, DiagnosticBuilder<'a>> { +) -> Result, Option>> { // Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation. let expr = expr.map(|mut expr| { 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 { ast::ExprKind::Lit(ref l) => match l.node { 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, err_msg: &str) -> Option<(Symbol, ast::StrStyle)> { expr_to_spanned_string(cx, expr, err_msg) - .map_err(|mut err| err.emit()) + .map_err(|err| err.map(|mut err| err.emit())) .ok() .map(|s| s.node) } diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 1101d7772b8..e63042a4208 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -86,7 +86,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T -> Box { let file = match get_single_str_from_tts(cx, sp, tts, "include!") { 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 let path = res_rel_file(cx, sp, file); diff --git a/src/libsyntax_ext/compile_error.rs b/src/libsyntax_ext/compile_error.rs index fd018885a26..8f7f5deb091 100644 --- a/src/libsyntax_ext/compile_error.rs +++ b/src/libsyntax_ext/compile_error.rs @@ -10,7 +10,7 @@ pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt, tts: &[tokenstream::TokenTree]) -> Box { 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, }; diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index a19c7e427e3..807f190cb6a 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -18,6 +18,7 @@ pub fn expand_syntax_ext( }; let mut accumulator = String::new(); let mut missing_literal = vec![]; + let mut has_errors = false; for e in es { match e.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"); } }, + ast::ExprKind::Err => { + has_errors = true; + } _ => { 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"); err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`"); 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); base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator))) diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 9c49a59678f..de96de4bdc2 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -24,7 +24,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, if tts.is_empty() { 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(); @@ -34,7 +34,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, TokenTree::Token(_, token::Comma) => {} _ => { cx.span_err(sp, "concat_idents! expecting comma."); - return DummyResult::expr(sp); + return DummyResult::any(sp); } } } else { @@ -43,7 +43,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, res_str.push_str(&ident.as_str()), _ => { cx.span_err(sp, "concat_idents! requires ident args."); - return DummyResult::expr(sp); + return DummyResult::any(sp); } } } diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index 33669c8bc37..16fb64a5f39 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -79,7 +79,7 @@ pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, let e = match env::var(&*var.as_str()) { Err(_) => { 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)), }; diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 95bb8c886ab..ac1402a0faa 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -748,18 +748,20 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, fmt } Ok(fmt) => fmt, - Err(mut err) => { - let sugg_fmt = match args.len() { - 0 => "{}".to_string(), - _ => format!("{}{{}}", "{} ".repeat(args.len())), - }; - err.span_suggestion_with_applicability( - fmt_sp.shrink_to_lo(), - "you might be missing a string literal to format with", - format!("\"{}\", ", sugg_fmt), - Applicability::MaybeIncorrect, - ); - err.emit(); + Err(err) => { + if let Some(mut err) = err { + let sugg_fmt = match args.len() { + 0 => "{}".to_string(), + _ => format!("{}{{}}", "{} ".repeat(args.len())), + }; + err.span_suggestion_with_applicability( + fmt_sp.shrink_to_lo(), + "you might be missing a string literal to format with", + format!("\"{}\", ", sugg_fmt), + Applicability::MaybeIncorrect, + ); + err.emit(); + } return DummyResult::raw_expr(sp, true); } }; diff --git a/src/test/ui/extenv/issue-55897.rs b/src/test/ui/extenv/issue-55897.rs new file mode 100644 index 00000000000..bd151c8a4e4 --- /dev/null +++ b/src/test/ui/extenv/issue-55897.rs @@ -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() {} diff --git a/src/test/ui/extenv/issue-55897.stderr b/src/test/ui/extenv/issue-55897.stderr new file mode 100644 index 00000000000..4d2e35dff46 --- /dev/null +++ b/src/test/ui/extenv/issue-55897.stderr @@ -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`. diff --git a/src/test/ui/issues/issue-11692-1.rs b/src/test/ui/issues/issue-11692-1.rs index 22777780402..70b712c5608 100644 --- a/src/test/ui/issues/issue-11692-1.rs +++ b/src/test/ui/issues/issue-11692-1.rs @@ -1,5 +1,3 @@ fn main() { - print!(testo!()); - //~^ ERROR: format argument must be a string literal - //~| ERROR: cannot find macro `testo!` in this scope + print!(testo!()); //~ ERROR cannot find macro `testo!` in this scope } diff --git a/src/test/ui/issues/issue-11692-1.stderr b/src/test/ui/issues/issue-11692-1.stderr index f4cc825803a..57a6a999544 100644 --- a/src/test/ui/issues/issue-11692-1.stderr +++ b/src/test/ui/issues/issue-11692-1.stderr @@ -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 --> $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 diff --git a/src/test/ui/issues/issue-11692-2.rs b/src/test/ui/issues/issue-11692-2.rs index 61039316573..61be284d732 100644 --- a/src/test/ui/issues/issue-11692-2.rs +++ b/src/test/ui/issues/issue-11692-2.rs @@ -1,4 +1,3 @@ fn main() { concat!(test!()); //~ ERROR cannot find macro `test!` in this scope - //~| ERROR expected a literal } diff --git a/src/test/ui/issues/issue-11692-2.stderr b/src/test/ui/issues/issue-11692-2.stderr index 848415435a7..5d4467080f1 100644 --- a/src/test/ui/issues/issue-11692-2.stderr +++ b/src/test/ui/issues/issue-11692-2.stderr @@ -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 --> $DIR/issue-11692-2.rs:2:13 | LL | concat!(test!()); //~ ERROR cannot find macro `test!` in this scope | ^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error