pub path: Path,
pub delim: MacDelimiter,
pub tts: TokenStream,
+ pub prior_type_ascription: Option<(Span, bool)>,
}
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)]
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;
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(),
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}",
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!()
}
path: ast::Path { span: DUMMY_SP, segments: Vec::new() },
tts: TokenStream::empty().into(),
delim: ast::MacDelimiter::Brace,
+ prior_type_ascription: None,
})
}
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.
}
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);
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.
// 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;
// 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 => {
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())))
}
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));
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)
}
))
}).into(),
delim: MacDelimiter::Parenthesis,
+ prior_type_ascription: None,
};
let if_expr = cx.expr_if(
sp,
--> $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