6 files changed +49
-4
lines changed Original file line number Diff line number Diff line change @@ -456,6 +456,8 @@ lint_non_local_definitions_macro_rules = non-local `macro_rules!` definition, th
456
456
[ one ] `{ $body_name } `
457
457
*[ other ] `{ $body_name } ` and up { $depth } bodies
458
458
}
459
+ .help_doctest =
460
+ remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { " { " } ... { " } " } `
459
461
.non_local = a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
460
462
.exception = one exception to the rule are anon-const (`const _: () = { " { " } ... { " } " } `) at top-level module
461
463
Original file line number Diff line number Diff line change @@ -1350,14 +1350,18 @@ pub enum NonLocalDefinitionsDiag {
1350
1350
const_anon : Option < Span > ,
1351
1351
} ,
1352
1352
#[ diag( lint_non_local_definitions_macro_rules) ]
1353
- #[ help]
1354
- #[ note( lint_non_local) ]
1355
- #[ note( lint_exception) ]
1356
- #[ note( lint_non_local_definitions_deprecation) ]
1357
1353
MacroRules {
1358
1354
depth : u32 ,
1359
1355
body_kind_descr : & ' static str ,
1360
1356
body_name : String ,
1357
+ #[ help]
1358
+ help : Option < ( ) > ,
1359
+ #[ help( lint_help_doctest) ]
1360
+ doctest_help : Option < ( ) > ,
1361
+ #[ note( lint_non_local) ]
1362
+ #[ note( lint_exception) ]
1363
+ #[ note( lint_non_local_definitions_deprecation) ]
1364
+ notes : ( ) ,
1361
1365
#[ subdiagnostic]
1362
1366
cargo_update : Option < NonLocalDefinitionsCargoUpdateNote > ,
1363
1367
} ,
Original file line number Diff line number Diff line change @@ -233,6 +233,12 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
233
233
ItemKind :: Macro ( _macro, MacroKind :: Bang )
234
234
if cx. tcx . has_attr ( item. owner_id . def_id , sym:: macro_export) =>
235
235
{
236
+ // determining we if are in a doctest context can't currently be determined
237
+ // by the code it-self (no specific attrs), but fortunatly rustdoc sets a
238
+ // perma-unstable env for libtest so we just re-use that env for now
239
+ let is_at_toplevel_doctest =
240
+ self . body_depth == 2 && std:: env:: var ( "UNSTABLE_RUSTDOC_TEST_PATH" ) . is_ok ( ) ;
241
+
236
242
cx. emit_span_lint (
237
243
NON_LOCAL_DEFINITIONS ,
238
244
item. span ,
@@ -243,6 +249,9 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
243
249
. map ( |s| s. to_ident_string ( ) )
244
250
. unwrap_or_else ( || "<unnameable>" . to_string ( ) ) ,
245
251
cargo_update : cargo_update ( ) ,
252
+ help : ( !is_at_toplevel_doctest) . then_some ( ( ) ) ,
253
+ doctest_help : is_at_toplevel_doctest. then_some ( ( ) ) ,
254
+ notes : ( ) ,
246
255
} ,
247
256
)
248
257
}
Original file line number Diff line number Diff line change
1
+ //@ check-pass
2
+ //@ compile-flags:--test --test-args --test-threads=1 --nocapture -Zunstable-options
3
+ //@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
4
+ //@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
5
+ //@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
6
+
7
+ //! ```
8
+ //! #[macro_export]
9
+ //! macro_rules! a_macro { () => {} }
10
+ //! ```
Original file line number Diff line number Diff line change
1
+ warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
2
+ --> $DIR/non_local_defs.rs:9:1
3
+ |
4
+ LL | macro_rules! a_macro { () => {} }
5
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6
+ |
7
+ = help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }`
8
+ = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
9
+ = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
10
+ = 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>
11
+ = note: `#[warn(non_local_definitions)]` on by default
12
+
13
+ warning: 1 warning emitted
14
+
Original file line number Diff line number Diff line change
1
+
2
+ running 1 test
3
+ test $DIR/non_local_defs.rs - (line 7) ... ok
4
+
5
+ test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
6
+
0 commit comments