1
Fork 0

Only emit lint for local macros

This commit is contained in:
Aaron Hill 2021-07-24 17:44:57 -05:00
parent 886dea2bcd
commit cf167c9c9c
No known key found for this signature in database
GPG key ID: B4087E510E98B164
3 changed files with 32 additions and 7 deletions

View file

@ -45,6 +45,8 @@ crate struct ParserAnyMacro<'a> {
lint_node_id: NodeId, lint_node_id: NodeId,
is_trailing_mac: bool, is_trailing_mac: bool,
arm_span: Span, arm_span: Span,
/// Whether or not this macro is defined in the current crate
is_local: bool,
} }
crate fn annotate_err_with_kind( crate fn annotate_err_with_kind(
@ -124,6 +126,7 @@ impl<'a> ParserAnyMacro<'a> {
lint_node_id, lint_node_id,
arm_span, arm_span,
is_trailing_mac, is_trailing_mac,
is_local,
} = *self; } = *self;
let snapshot = &mut parser.clone(); let snapshot = &mut parser.clone();
let fragment = match parse_ast_fragment(parser, kind) { let fragment = match parse_ast_fragment(parser, kind) {
@ -138,6 +141,7 @@ impl<'a> ParserAnyMacro<'a> {
// `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`, // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
// but `m!()` is allowed in expression positions (cf. issue #34706). // but `m!()` is allowed in expression positions (cf. issue #34706).
if kind == AstFragmentKind::Expr && parser.token == token::Semi { if kind == AstFragmentKind::Expr && parser.token == token::Semi {
if is_local {
parser.sess.buffer_lint_with_diagnostic( parser.sess.buffer_lint_with_diagnostic(
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
parser.token.span, parser.token.span,
@ -145,6 +149,7 @@ impl<'a> ParserAnyMacro<'a> {
"trailing semicolon in macro used in expression position", "trailing semicolon in macro used in expression position",
BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident), BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
); );
}
parser.bump(); parser.bump();
} }
@ -162,6 +167,7 @@ struct MacroRulesMacroExpander {
lhses: Vec<mbe::TokenTree>, lhses: Vec<mbe::TokenTree>,
rhses: Vec<mbe::TokenTree>, rhses: Vec<mbe::TokenTree>,
valid: bool, valid: bool,
is_local: bool,
} }
impl TTMacroExpander for MacroRulesMacroExpander { impl TTMacroExpander for MacroRulesMacroExpander {
@ -183,6 +189,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
input, input,
&self.lhses, &self.lhses,
&self.rhses, &self.rhses,
self.is_local,
) )
} }
} }
@ -210,6 +217,7 @@ fn generic_extension<'cx>(
arg: TokenStream, arg: TokenStream,
lhses: &[mbe::TokenTree], lhses: &[mbe::TokenTree],
rhses: &[mbe::TokenTree], rhses: &[mbe::TokenTree],
is_local: bool,
) -> Box<dyn MacResult + 'cx> { ) -> Box<dyn MacResult + 'cx> {
let sess = &cx.sess.parse_sess; let sess = &cx.sess.parse_sess;
@ -311,6 +319,7 @@ fn generic_extension<'cx>(
lint_node_id: cx.current_expansion.lint_node_id, lint_node_id: cx.current_expansion.lint_node_id,
is_trailing_mac: cx.current_expansion.is_trailing_mac, is_trailing_mac: cx.current_expansion.is_trailing_mac,
arm_span, arm_span,
is_local,
}); });
} }
Failure(token, msg) => match best_failure { Failure(token, msg) => match best_failure {
@ -544,6 +553,9 @@ pub fn compile_declarative_macro(
lhses, lhses,
rhses, rhses,
valid, 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,
})) }))
} }

View file

@ -0,0 +1,4 @@
#[macro_export]
macro_rules! my_macro {
() => { true; }
}

View file

@ -0,0 +1,9 @@
// aux-build:foreign-crate.rs
// check-pass
extern crate foreign_crate;
// Test that we do not lint for a macro in a foreign crate
fn main() {
let _ = foreign_crate::my_macro!();
}