Skip to content

New guideline to refer to names with global paths in a macro #76

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 3 commits into from
May 20, 2025
Merged
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
69 changes: 69 additions & 0 deletions src/coding-guidelines/macros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,72 @@ Macros
fn example_function() {
// Compliant implementation
}

.. guideline:: Names in a macro definition shall use a fully qualified path
:id: gui_SJMrWDYZ0dN4
:category: required
:status: draft
:release: 1.85.0;1.85.1
:fls: fls_7kb6ltajgiou
:decidability: decidable
:scope: module
:tags: reduce-human-error

Each name inside of the definition of a macro shall either use a global path or path prefixed with $crate.

.. rationale::
:id: rat_VRNXaxmW1l2s
:status: draft

Using a path that refers to an entity relatively inside of a macro subjects it to path resolution
results which may change depending on where the macro is used. The intended path to refer to an entity
can be shadowed when using a macro leading to unexpected behaviors. This could lead to developer confusion
about why a macro behaves differently in diffenent locations, or confusion about where entity in a macro
will resolve to.

.. non_compliant_example::
:id: non_compl_ex_m2XR1ihTbCQS
:status: draft

The following is a macro which shows referring to a vector entity using a non-global path. Depending on
where the macro is used a different `Vec` could be used than is intended. If scope where this is used
defines a struct `Vec` which is not preset at the macro defintion, the macro user might be intending to
use that in the macro.

.. code-block:: rust

#[macro_export]
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new(); // non-global path
$(
temp_vec.push($x);
)*
temp_vec
}
};
}

.. compliant_example::
:id: compl_ex_xyaShvxL9JAM
:status: draft

The following is a macro refers to Vec using a global path. Even if there is a different struct called
`Vec` defined in the scope of the macro usage, this macro will unambigiously use the `Vec` from the
Standard Library.

.. code-block:: rust

#[macro_export]
macro_rules! vec {
( $( $x:expr ),* ) => {
{
let mut temp_vec = ::std::vec::Vec::new(); // global path
$(
temp_vec.push($x);
)*
temp_vec
}
};
}