]> git.lizzy.rs Git - rust.git/commitdiff
Point at type ascription before macro invocation on expansion parse error
authorEsteban Küber <esteban@kuber.com.ar>
Fri, 19 Jul 2019 01:36:19 +0000 (18:36 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Tue, 30 Jul 2019 16:16:27 +0000 (09:16 -0700)
src/libsyntax/ast.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/placeholders.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/mut_visit.rs
src/libsyntax/parse/parser.rs
src/libsyntax_ext/assert.rs
src/test/ui/type/ascription/issue-47666.stderr

index 58a1c4aee9ad90e53542d530cb3dd52f37f6c89e..76b67366f067120b494f83a57479375ffbe041d1 100644 (file)
@@ -1303,6 +1303,7 @@ pub struct Mac_ {
     pub path: Path,
     pub delim: MacDelimiter,
     pub tts: TokenStream,
+    pub prior_type_ascription: Option<(Span, bool)>,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
index bb7834a133f039a564681a514b1ab064d758071a..239fe55672e1293d95ed170f63100865794b360f 100644 (file)
@@ -713,6 +713,7 @@ pub struct ExpansionData {
     pub depth: usize,
     pub module: Rc<ModuleData>,
     pub directory_ownership: DirectoryOwnership,
+    pub prior_type_ascription: Option<(Span, bool)>,
 }
 
 /// One of these is made during expansion and incrementally updated as we go;
@@ -743,6 +744,7 @@ pub fn new(parse_sess: &'a parse::ParseSess,
                 depth: 0,
                 module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }),
                 directory_ownership: DirectoryOwnership::Owned { relative: None },
+                prior_type_ascription: None,
             },
             expansions: FxHashMap::default(),
             allow_derive_markers: [sym::rustc_attrs, sym::structural_match][..].into(),
index cd602d08c5baaf0e886cc9be4422800173a4eb06..6355f88195f03c469c558897f182568ddc49b2b0 100644 (file)
@@ -517,8 +517,11 @@ fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtensionKind) -> AstF
                     result
                 }
                 SyntaxExtensionKind::LegacyBang(expander) => {
+                    let prev = self.cx.current_expansion.prior_type_ascription;
+                    self.cx.current_expansion.prior_type_ascription =
+                        mac.node.prior_type_ascription;
                     let tok_result = expander.expand(self.cx, span, mac.node.stream());
-                    if let Some(result) = fragment_kind.make_from(tok_result) {
+                    let result = if let Some(result) = fragment_kind.make_from(tok_result) {
                         result
                     } else {
                         let msg = format!("non-{kind} macro in {kind} position: {path}",
@@ -526,7 +529,9 @@ fn expand_invoc(&mut self, invoc: Invocation, ext: &SyntaxExtensionKind) -> AstF
                         self.cx.span_err(span, &msg);
                         self.cx.trace_macros_diag();
                         fragment_kind.dummy(span)
-                    }
+                    };
+                    self.cx.current_expansion.prior_type_ascription = prev;
+                    result
                 }
                 _ => unreachable!()
             }
index 17d8bf3ab175ffe31b4b45f63e4899d929dc2961..b2b17b0fb287391c07379d0647faefaf68030290 100644 (file)
@@ -18,6 +18,7 @@ fn mac_placeholder() -> ast::Mac {
             path: ast::Path { span: DUMMY_SP, segments: Vec::new() },
             tts: TokenStream::empty().into(),
             delim: ast::MacDelimiter::Brace,
+            prior_type_ascription: None,
         })
     }
 
index 2a2df76d30c1d41111ba1c453d6b61bf736bada7..7d72a18ca3f6cafb72dd8e8f5ecbd6013c787367 100644 (file)
@@ -173,6 +173,7 @@ fn generic_extension<'cx>(
                 let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None);
                 p.root_module_name =
                     cx.current_expansion.module.mod_path.last().map(|id| id.as_str().to_string());
+                p.last_type_ascription = cx.current_expansion.prior_type_ascription;
 
                 p.process_potential_macro_variable();
                 // Let the context choose how to interpret the result.
index 43b6bea69d9ed5522decbdf2d10c1332fb44e83c..f215a321cb3c05bd7b02950e73cb9b4c5d821d07 100644 (file)
@@ -530,7 +530,7 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
 }
 
 pub fn noop_visit_mac<T: MutVisitor>(Spanned { node, span }: &mut Mac, vis: &mut T) {
-    let Mac_ { path, delim: _, tts } = node;
+    let Mac_ { path, delim: _, tts, .. } = node;
     vis.visit_path(path);
     vis.visit_tts(tts);
     vis.visit_span(span);
index 6cb965bf817d170892e56254d973553e1ff4c440..d15419f615ff694bd561fd7dbb38705ecd216f75 100644 (file)
@@ -1414,7 +1414,12 @@ fn parse_ty_common(&mut self, allow_plus: bool, allow_qpath_recovery: bool,
             if self.eat(&token::Not) {
                 // Macro invocation in type position
                 let (delim, tts) = self.expect_delimited_token_tree()?;
-                let node = Mac_ { path, tts, delim };
+                let node = Mac_ {
+                    path,
+                    tts,
+                    delim,
+                    prior_type_ascription: self.last_type_ascription,
+                };
                 TyKind::Mac(respan(lo.to(self.prev_span), node))
             } else {
                 // Just a type path or bound list (trait object type) starting with a trait.
@@ -2245,7 +2250,12 @@ macro_rules! parse_lit {
                         // MACRO INVOCATION expression
                         let (delim, tts) = self.expect_delimited_token_tree()?;
                         hi = self.prev_span;
-                        ex = ExprKind::Mac(respan(lo.to(hi), Mac_ { path, tts, delim }));
+                        ex = ExprKind::Mac(respan(lo.to(hi), Mac_ {
+                            path,
+                            tts,
+                            delim,
+                            prior_type_ascription: self.last_type_ascription,
+                        }));
                     } else if self.check(&token::OpenDelim(token::Brace)) {
                         if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
                             return expr;
@@ -3971,7 +3981,12 @@ fn parse_pat_with_range_pat(
                         // Parse macro invocation
                         self.bump();
                         let (delim, tts) = self.expect_delimited_token_tree()?;
-                        let mac = respan(lo.to(self.prev_span), Mac_ { path, tts, delim });
+                        let mac = respan(lo.to(self.prev_span), Mac_ {
+                            path,
+                            tts,
+                            delim,
+                            prior_type_ascription: self.last_type_ascription,
+                        });
                         pat = PatKind::Mac(mac);
                     }
                     token::DotDotDot | token::DotDotEq | token::DotDot => {
@@ -4417,7 +4432,12 @@ fn parse_stmt_without_recovery(
                 MacStmtStyle::NoBraces
             };
 
-            let mac = respan(lo.to(hi), Mac_ { path, tts, delim });
+            let mac = respan(lo.to(hi), Mac_ {
+                path,
+                tts,
+                delim,
+                prior_type_ascription: self.last_type_ascription,
+            });
             let node = if delim == MacDelimiter::Brace ||
                           self.token == token::Semi || self.token == token::Eof {
                 StmtKind::Mac(P((mac, style, attrs.into())))
@@ -7550,7 +7570,12 @@ fn parse_macro_use_or_failure(
             }
 
             let hi = self.prev_span;
-            let mac = respan(mac_lo.to(hi), Mac_ { path, tts, delim });
+            let mac = respan(mac_lo.to(hi), Mac_ {
+                path,
+                tts,
+                delim,
+                prior_type_ascription: self.last_type_ascription,
+            });
             let item =
                 self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs);
             return Ok(Some(item));
@@ -7600,7 +7625,12 @@ fn parse_assoc_macro_invoc(&mut self, item_kind: &str, vis: Option<&Visibility>,
                 self.expect(&token::Semi)?;
             }
 
-            Ok(Some(respan(lo.to(self.prev_span), Mac_ { path, tts, delim })))
+            Ok(Some(respan(lo.to(self.prev_span), Mac_ {
+                path,
+                tts,
+                delim,
+                prior_type_ascription: self.last_type_ascription,
+            })))
         } else {
             Ok(None)
         }
index 235565314f5e29e891bec55c74b17a8c7058d8f1..9e27909dc9663a7c57bc22c0a54d7d5c1b8f8433 100644 (file)
@@ -38,6 +38,7 @@ pub fn expand_assert<'cx>(
             ))
         }).into(),
         delim: MacDelimiter::Parenthesis,
+        prior_type_ascription: None,
     };
     let if_expr = cx.expr_if(
         sp,
index 7aa899f795c7d6b452e977ec5830c5864073a19f..965bbe5ea41f7078e88452cb12b57b4a5ef46d2b 100644 (file)
@@ -2,11 +2,14 @@ error: expected type, found reserved keyword `box`
   --> $DIR/issue-47666.rs:2:25
    |
 LL |     let _ = Option:Some(vec![0, 1]);
-   |                         ^^^^^^^^^^
-   |                         |
-   |                         expected type
-   |                         in this macro invocation
+   |                   -     ^^^^^^^^^^
+   |                   |     |
+   |                   |     expected type
+   |                   |     in this macro invocation
+   |                   help: maybe write a path separator here: `::`
    |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
    = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 error: aborting due to previous error