@@ -426,3 +426,72 @@ Macros
426
426
fn example_function() {
427
427
// Compliant implementation
428
428
}
429
+
430
+ .. guideline :: Names in a macro definition shall use a fully qualified path
431
+ :id: gui_SJMrWDYZ0dN4
432
+ :category: required
433
+ :status: draft
434
+ :release: 1.85.0;1.85.1
435
+ :fls: fls_7kb6ltajgiou
436
+ :decidability: decidable
437
+ :scope: module
438
+ :tags: reduce-human-error
439
+
440
+ Each name inside of the definition of a macro shall either use a global path or path prefixed with $crate.
441
+
442
+ .. rationale ::
443
+ :id: rat_VRNXaxmW1l2s
444
+ :status: draft
445
+
446
+ Using a path that refers to an entity relatively inside of a macro subjects it to path resolution
447
+ results which may change depending on where the macro is used. The intended path to refer to an entity
448
+ can be shadowed when using a macro leading to unexpected behaviors. This could lead to developer confusion
449
+ about why a macro behaves differently in diffenent locations, or confusion about where entity in a macro
450
+ will resolve to.
451
+
452
+ .. non_compliant_example ::
453
+ :id: non_compl_ex_m2XR1ihTbCQS
454
+ :status: draft
455
+
456
+ The following is a macro which shows referring to a vector entity using a non-global path. Depending on
457
+ where the macro is used a different `Vec ` could be used than is intended. If scope where this is used
458
+ defines a struct `Vec ` which is not preset at the macro defintion, the macro user might be intending to
459
+ use that in the macro.
460
+
461
+ .. code-block :: rust
462
+
463
+ #[macro_export]
464
+ macro_rules! vec {
465
+ ( $( $x:expr ),* ) => {
466
+ {
467
+ let mut temp_vec = Vec::new(); // non-global path
468
+ $(
469
+ temp_vec.push($x);
470
+ )*
471
+ temp_vec
472
+ }
473
+ };
474
+ }
475
+
476
+ .. compliant_example ::
477
+ :id: compl_ex_xyaShvxL9JAM
478
+ :status: draft
479
+
480
+ The following is a macro refers to Vec using a global path. Even if there is a different struct called
481
+ `Vec ` defined in the scope of the macro usage, this macro will unambigiously use the `Vec ` from the
482
+ Standard Library.
483
+
484
+ .. code-block :: rust
485
+
486
+ #[macro_export]
487
+ macro_rules! vec {
488
+ ( $( $x:expr ),* ) => {
489
+ {
490
+ let mut temp_vec = ::std::vec::Vec::new(); // global path
491
+ $(
492
+ temp_vec.push($x);
493
+ )*
494
+ temp_vec
495
+ }
496
+ };
497
+ }
0 commit comments