]> git.lizzy.rs Git - rust.git/commitdiff
Improve error recovery for some built-in macros
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 29 Dec 2018 21:56:55 +0000 (00:56 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 29 Dec 2018 22:43:35 +0000 (01:43 +0300)
13 files changed:
src/libsyntax/ext/base.rs
src/libsyntax/ext/source_util.rs
src/libsyntax_ext/compile_error.rs
src/libsyntax_ext/concat.rs
src/libsyntax_ext/concat_idents.rs
src/libsyntax_ext/env.rs
src/libsyntax_ext/format.rs
src/test/ui/extenv/issue-55897.rs [new file with mode: 0644]
src/test/ui/extenv/issue-55897.stderr [new file with mode: 0644]
src/test/ui/issues/issue-11692-1.rs
src/test/ui/issues/issue-11692-1.stderr
src/test/ui/issues/issue-11692-2.rs
src/test/ui/issues/issue-11692-2.stderr

index 7e8b7007b22895d65dbf053ad3c5dac3fa1ee8ae..2793754e1033afac623e321f2c0e435b4e5633ce 100644 (file)
@@ -995,7 +995,7 @@ pub fn expr_to_spanned_string<'a>(
     cx: &'a mut ExtCtxt,
     expr: P<ast::Expr>,
     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.
     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<ast::Expr>, 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)
 }
index 1101d7772b83964f5ab8e117eef92073f9dfb15d..e63042a420824642fc44efd6d293ce3ee1c0f529 100644 (file)
@@ -86,7 +86,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T
                            -> Box<dyn base::MacResult+'cx> {
     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);
index fd018885a26be01774d77aa992388293e15ee036..8f7f5deb091acf5edd1fbb8b7f261459889736eb 100644 (file)
@@ -10,7 +10,7 @@ pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt,
                               tts: &[tokenstream::TokenTree])
                               -> Box<dyn base::MacResult + 'cx> {
     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,
     };
 
index a19c7e427e34caeec4ebc65e19d01e81ff5f6c04..807f190cb6a1afffcf31efe773625d5b45024011 100644 (file)
@@ -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)))
index 9c49a59678fdbf434606aa99e41347db8e2c2d40..de96de4bdc2bc59e76fc4c4efb739eaa13fd5288 100644 (file)
@@ -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);
                 }
             }
         }
index 33669c8bc37ecf9d9604b140e999dcf8a933e36b..16fb64a5f391215ada625f55e99a93d5498982d9 100644 (file)
@@ -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)),
     };
index 95bb8c886abf2c7f912eba76e195988c2ad24187..ac1402a0faaa5749307e6828b7884cf8744a790e 100644 (file)
@@ -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 (file)
index 0000000..bd151c8
--- /dev/null
@@ -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 (file)
index 0000000..4d2e35d
--- /dev/null
@@ -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`.
index 2277778040292092af60a1ae95766b1716967e51..70b712c560830c5523b30a314bbe7ccb21bc8fba 100644 (file)
@@ -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
 }
index f4cc825803a3b53b9d6d77256a3ee0bf76460759..57a6a999544cf4952a7a9f0580b4b2eccd377b47 100644 (file)
@@ -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
 
index 6103931657342d77511e1c9e231f18c4b5983e00..61be284d7320eeaf3c82e17350ae38dc5922ac96 100644 (file)
@@ -1,4 +1,3 @@
 fn main() {
     concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
-                      //~| ERROR expected a literal
 }
index 848415435a78ba0d3feb891f5aaa06f01fe3d7e9..5d4467080f149dce9f0927179dea34f8d268cec0 100644 (file)
@@ -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