Skip to content

Adjust #[macro_export]/doctest help suggestion for non_local_defs lint #124568

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, th
[one] `{$body_name}`
*[other] `{$body_name}` and up {$depth} bodies
}
.help_doctest =
remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`
.non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
.exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module

Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1350,14 +1350,18 @@ pub enum NonLocalDefinitionsDiag {
const_anon: Option<Span>,
},
#[diag(lint_non_local_definitions_macro_rules)]
#[help]
#[note(lint_non_local)]
#[note(lint_exception)]
#[note(lint_non_local_definitions_deprecation)]
MacroRules {
depth: u32,
body_kind_descr: &'static str,
body_name: String,
#[help]
help: Option<()>,
#[help(lint_help_doctest)]
doctest_help: Option<()>,
#[note(lint_non_local)]
#[note(lint_exception)]
#[note(lint_non_local_definitions_deprecation)]
notes: (),
#[subdiagnostic]
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
},
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_lint/src/non_local_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
ItemKind::Macro(_macro, MacroKind::Bang)
if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
{
// determining we if are in a doctest context can't currently be determined
// by the code it-self (no specific attrs), but fortunatly rustdoc sets a
// perma-unstable env for libtest so we just re-use that env for now
let is_at_toplevel_doctest =
self.body_depth == 2 && std::env::var("UNSTABLE_RUSTDOC_TEST_PATH").is_ok();

cx.emit_span_lint(
NON_LOCAL_DEFINITIONS,
item.span,
Expand All @@ -242,6 +248,9 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
.map(|s| s.to_ident_string())
.unwrap_or_else(|| "<unnameable>".to_string()),
cargo_update: cargo_update(),
help: (!is_at_toplevel_doctest).then_some(()),
doctest_help: is_at_toplevel_doctest.then_some(()),
notes: (),
},
)
}
Expand Down
10 changes: 10 additions & 0 deletions tests/rustdoc-ui/doctest/non_local_defs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//@ check-pass
//@ compile-flags:--test --test-args --test-threads=1 --nocapture -Zunstable-options
//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"

//! ```
//! #[macro_export]
//! macro_rules! a_macro { () => {} }
//! ```
14 changes: 14 additions & 0 deletions tests/rustdoc-ui/doctest/non_local_defs.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
--> $DIR/non_local_defs.rs:9:1
|
LL | macro_rules! a_macro { () => {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }`
= note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
= note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
= note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
= note: `#[warn(non_local_definitions)]` on by default

warning: 1 warning emitted

6 changes: 6 additions & 0 deletions tests/rustdoc-ui/doctest/non_local_defs.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

running 1 test
test $DIR/non_local_defs.rs - (line 7) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME

Loading