/// The ident of the macro we're parsing
macro_ident: Ident,
lint_node_id: NodeId,
+ is_trailing_mac: bool,
arm_span: Span,
+ /// Whether or not this macro is defined in the current crate
+ is_local: bool,
}
crate fn annotate_err_with_kind(
impl<'a> ParserAnyMacro<'a> {
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
- let ParserAnyMacro { site_span, macro_ident, ref mut parser, lint_node_id, arm_span } =
- *self;
+ let ParserAnyMacro {
+ site_span,
+ macro_ident,
+ ref mut parser,
+ lint_node_id,
+ arm_span,
+ is_trailing_mac,
+ is_local,
+ } = *self;
let snapshot = &mut parser.clone();
let fragment = match parse_ast_fragment(parser, kind) {
Ok(f) => f,
// `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
// but `m!()` is allowed in expression positions (cf. issue #34706).
if kind == AstFragmentKind::Expr && parser.token == token::Semi {
- parser.sess.buffer_lint(
- SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
- parser.token.span,
- lint_node_id,
- "trailing semicolon in macro used in expression position",
- );
+ if is_local {
+ parser.sess.buffer_lint_with_diagnostic(
+ SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
+ parser.token.span,
+ lint_node_id,
+ "trailing semicolon in macro used in expression position",
+ BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
+ );
+ }
parser.bump();
}
lhses: Vec<mbe::TokenTree>,
rhses: Vec<mbe::TokenTree>,
valid: bool,
+ is_local: bool,
}
impl TTMacroExpander for MacroRulesMacroExpander {
input,
&self.lhses,
&self.rhses,
+ self.is_local,
)
}
}
arg: TokenStream,
lhses: &[mbe::TokenTree],
rhses: &[mbe::TokenTree],
+ is_local: bool,
) -> Box<dyn MacResult + 'cx> {
let sess = &cx.sess.parse_sess;
let mut p = Parser::new(sess, tts, false, None);
p.last_type_ascription = cx.current_expansion.prior_type_ascription;
- let lint_node_id = cx.resolver.lint_node_id(cx.current_expansion.id);
// Let the context choose how to interpret the result.
// Weird, but useful for X-macros.
// macro leaves unparsed tokens.
site_span: sp,
macro_ident: name,
- lint_node_id,
+ lint_node_id: cx.current_expansion.lint_node_id,
+ is_trailing_mac: cx.current_expansion.is_trailing_mac,
arm_span,
+ is_local,
});
}
Failure(token, msg) => match best_failure {
lhses,
rhses,
valid,
+ // Macros defined in the current crate have a real node id,
+ // whereas macros from an external crate have a dummy id.
+ is_local: def.id != DUMMY_NODE_ID,
}))
}