Skip to content

Add relative_path_in_macro_definition lint (#14472) #14645 #14648

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

KunWuChan
Copy link

@KunWuChan KunWuChan commented Apr 18, 2025

Add relative_path_in_macro_definition lint (#14472) #14645

Implements the relative_path_in_macro_definition lint to warn about relative paths to core or kernel in macro definitions, as requested in #14472.
Includes tests in tests/ui/relative_path_in_macro_definition.rs and updates existing tests (incompatible_msrv.rs, swap_ptr_to_ref_unfixable.rs, arithmetic_side_effects.rs) with #![allow] to avoid interference.

Fixes New lint: relative_path_in_macro_definition #14472
Tests pass: cargo test, cargo test --test compile-test, cargo test --test integration
cargo fmt clean

changelog: add 'relative_path_in_macro_definition' lint.

Signed-off-by: Kunwu Chan [email protected]
Co-developed-by: Grace Deng [email protected]
Signed-off-by: Grace Deng [email protected]

Implement lint to warn about relative `core`/`kernel` paths in macro
definitions.

Signed-off-by: Kunwu Chan <[email protected]>
Co-developed-by: Grace Deng <[email protected]>
Signed-off-by: Grace Deng <[email protected]>
Create `tests/ui/relative_path_in_macro_definition.rs` with positive and
negative cases to verify lint behavior.

Signed-off-by: Kunwu Chan <[email protected]>
Co-developed-by: Grace Deng <[email protected]>
Signed-off-by: Grace Deng <[email protected]>
Add `#![allow(clippy::relative_path_in_macro_definition)]` to
`incompatible_msrv.rs`, `swap_ptr_to_ref_unfixable.rs`, and
`arithmetic_side_effects.rs` to avoid lint interference. Update
corresponding `.stderr` files.

Signed-off-by: Kunwu Chan <[email protected]>
Co-developed-by: Grace Deng <[email protected]>
Signed-off-by: Grace Deng <[email protected]>
@rustbot
Copy link
Collaborator

rustbot commented Apr 18, 2025

r? @llogiq

rustbot has assigned @llogiq.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Apr 18, 2025
Copy link
Contributor

@llogiq llogiq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good starting point. I'd like the message to be more succinct and relate to the current situation though.

match tree {
TokenTree::Token(token, _) => {
if let TokenKind::Ident(ident, _) = token.kind
&& (ident == sym::core || ident.as_str() == "kernel")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer need ident.as_str(). Look at clippy_utils::sym.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your feedback and suggestion to avoid ident.as_str() and refer to clippy_utils::sym. I've encountered a compilation error with the current implementation:
error[E0425]: cannot find value kernel in module sym
--> clippy_lints/src/relative_path_in_macro_definition.rs:57:61
|
57 | && (ident == sym::core || ident == sym::kernel)
| ^^^^^^ not found in sym

The issue arises because rustc_span::symbol::sym does not define a kernel symbol, unlike core. Upon reviewing clippy_utils::sym, I found it to be a macro that wraps Symbol::intern, used for creating symbols from strings, rather than providing predefined symbols like core.
To address this, I propose using Symbol::intern("kernel") to create the kernel symbol dynamically, allowing direct comparison with ident (of type rustc_span::Ident). The updated code snippet is:
if ident == sym::core || ident == Symbol::intern("kernel") {
// ... rest of the lint logic ...
}

This approach avoids ident.as_str() as you recommended, using direct symbol comparisons for efficiency. I've tested this change locally, and it resolves the compilation error while maintaining the lint's functionality to check for relative paths to core and kernel in macro definitions.
Could you please confirm if using Symbol::intern("kernel") is acceptable for this lint, or if there's a preferred method within Clippy's codebase (e.g., using clippy_utils::sym! macro or another approach)? Thank you for your guidance!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you can simply add "kernel" into that generate! macro call, then you can use clippy_utils::sym::kernel in your code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you can simply add "kernel" into that generate! macro call, then you can use clippy_utils::sym::kernel in your code.

It seems that the definition of "sym::core" is in
https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/symbol.rs.
But according to the discussion below, we no longer need to add the extra check. Anyway, thanks for the reply.

Comment on lines +69 to +73
if let TokenTree::Token(prev_token, _) = prev {
prev_token.kind == TokenKind::PathSep
} else {
false
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if let TokenTree::Token(prev_token, _) = prev {
prev_token.kind == TokenKind::PathSep
} else {
false
}
matches!(prev, TokenTree::Token(Token { kind: TokenKind::PathSep, .. }, _))

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx, I'll change it in v2.

cx,
RELATIVE_PATH_IN_MACRO_DEFINITION,
token.span,
"relative path to `core` or `kernel` used in macro definition",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we should reuse the first element of the path instead of writing both options.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx, I'll change it in v2.

@rustbot
Copy link
Collaborator

rustbot commented May 13, 2025

☔ The latest upstream changes (possibly 7bac114) made this pull request unmergeable. Please resolve the merge conflicts.

@smoelius
Copy link
Contributor

Sorry to intrude, but can I ask why core and kernel are the focus? Wouldn't it make sense to warn about any relative path in a macro definition?

@KunWuChan
Copy link
Author

KunWuChan commented May 17, 2025

Sorry to intrude, but can I ask why core and kernel are the focus? Wouldn't it make sense to warn about any relative path in a macro definition?

The source is here:
Rust-for-Linux/linux#1150

@smoelius
Copy link
Contributor

The source is here: Rust-for-Linux/linux#1150

Thank you, @KunWuChan. It would be nice if eventually the lint could be extended as @ojeda wrote in Rust-for-Linux/linux#1150 (comment):

Sounds like a good idea -- in general it would be nice to do that for all crates (or at least non-leaf ones) that we are aware, i.e. I don't think we will want modules named the same way as crates -- it can get confusing fast.

I think many besides kernel developers would benefit from a lint like that.

@llogiq
Copy link
Contributor

llogiq commented May 17, 2025

I agree that there is nothing in the issue about the lint that should restrict which paths must be relative. And kernel is not even part of the standard library, if we wanted to restrict the lint to that, we'd need core, std and alloc instead.

So let's simply remove that additional check and make the lint more general.

@ojeda
Copy link
Contributor

ojeda commented May 18, 2025

Yeah, we expected the lint to be general, rather than just core and kernel (i.e. those two crates were mentioned in the kernel-side issue since some cleanups were expected in macros that referred to those, but it applies to other paths, of course).

Thanks for this!

@KunWuChan
Copy link
Author

The source is here: Rust-for-Linux/linux#1150

Thank you, @KunWuChan. It would be nice if eventually the lint could be extended as @ojeda wrote in Rust-for-Linux/linux#1150 (comment):

Sounds like a good idea -- in general it would be nice to do that for all crates (or at least non-leaf ones) that we are aware, i.e. I don't think we will want modules named the same way as crates -- it can get confusing fast.

I think many besides kernel developers would benefit from a lint like that.

Sure, I'll try to do it as the suggestions.

I agree that there is nothing in the issue about the lint that should restrict which paths must be relative. And kernel is not even part of the standard library, if we wanted to restrict the lint to that, we'd need core, std and alloc instead.

So let's simply remove that additional check and make the lint more general.

thx, I'll remove the additional check and make the lint more general.

@KunWuChan
Copy link
Author

Yeah, we expected the lint to be general, rather than just core and kernel (i.e. those two crates were mentioned in the kernel-side issue since some cleanups were expected in macros that referred to those, but it applies to other paths, of course).

Thanks for this!

Okay, I'll remove the additional check and add some testcases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants