Skip to content

Commit fbe0061

Browse files
authored
New guideline to refer to names with global paths in a macro (#76)
* Initial draft of global paths in modules * Update to required, and mention $crate * Add more explanation to the examples
1 parent d41cb20 commit fbe0061

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

src/coding-guidelines/macros.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,3 +426,72 @@ Macros
426426
fn example_function() {
427427
// Compliant implementation
428428
}
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

Comments
 (0)