Skip to content

Fix cast-lossless should not suggest when casting type is from macro input #15358

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 1 commit into from
Jul 28, 2025

Conversation

profetia
Copy link
Contributor

@profetia profetia commented Jul 27, 2025

Closes #15348

The span of the as expr is also incorrect, but I believe it is not a bug from Clippy.

changelog: [cast-lossless] fix wrong suggestions when casting type is from macro input

@rustbot
Copy link
Collaborator

rustbot commented Jul 27, 2025

r? @samueltardieu

rustbot has assigned @samueltardieu.
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 Jul 27, 2025
Copy link

github-actions bot commented Jul 27, 2025

Lintcheck changes for 938e79f

Lint Added Removed Changed
clippy::cast_lossless 0 202 3

This comment will be updated if you push new changes

Copy link
Member

@samueltardieu samueltardieu left a comment

Choose a reason for hiding this comment

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

I am a bit puzzled by the proposed fix. For example, what should happen in the following case?

    macro_rules! zero {
        ($int:ty) => {{
            let data: [u16; 3] = [0, 0, 0];
            data[0] as $int
        }};
    }

    let _ = zero!(u8);
    let _ = zero!(u16);
    let _ = zero!(u32);
    let _ = zero!(u64);
    let _ = zero!(u128);

If Clippy gives a suggestion (as it does because of the u32, u64, and u128 cases) and the user applies it, then the code with u8 won't compile anymore. Isn't that dangerous to presume that the from() type relative function can be used just because one instance (or three in this case) appears to allow it?

@profetia
Copy link
Contributor Author

In the proposed fix, no lint will be given for u8. When the casting type is from macro input, whether the cast is loseless become undermined. In this fix, a help is given instead of a suggestion. Maybe we should silence it all together?

@samueltardieu
Copy link
Member

In the proposed fix, no lint will be given for u8. When the casting type is from macro input, whether the cast is loseless become undermined. In this fix, a help is given instead of a suggestion. Maybe we should silence it all together?

I think it should be silenced, because you cannot "fix" the macro if that could make some other uses of it not compile because of this fix.

@samueltardieu
Copy link
Member

The span of the as expr is also incorrect

What do you mean?

@profetia
Copy link
Contributor Author

@samueltardieu Updated. Now they are silenced.

@profetia
Copy link
Contributor Author

The span of the as expr is also incorrect

What do you mean?

In the reproducer given in #15348,

The as span is showing as:

12 |           impl BitSplit for $int {
   |  ___________________________^
13 | |             type Half = $half;
14 | |             #[inline]
15 | |             fn merge(halves: [Self::Half; 2]) -> Self {
16 | |                 const HALF_SIZE: usize = std::mem::size_of::<$half>() * 8;
17 | |                 (halves[0] << HALF_SIZE) as $int | halves[1] as $int
   | |____________________________________________________________^

But it should be:

17 |                  (halves[0] << HALF_SIZE) as $int | halves[1] as $int
                                                         ^^^^^^^^^^^^^^^^^

This might be a bug in rustc

@samueltardieu samueltardieu added this pull request to the merge queue Jul 28, 2025
Merged via the queue into rust-lang:master with commit a55517f Jul 28, 2025
11 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jul 28, 2025
@samueltardieu
Copy link
Member

The span of the as expr is also incorrect

What do you mean?

In the reproducer given in #15348,

The as span is showing as:

12 |           impl BitSplit for $int {
   |  ___________________________^
13 | |             type Half = $half;
14 | |             #[inline]
15 | |             fn merge(halves: [Self::Half; 2]) -> Self {
16 | |                 const HALF_SIZE: usize = std::mem::size_of::<$half>() * 8;
17 | |                 (halves[0] << HALF_SIZE) as $int | halves[1] as $int
   | |____________________________________________________________^

But it should be:

17 |                  (halves[0] << HALF_SIZE) as $int | halves[1] as $int
                                                         ^^^^^^^^^^^^^^^^^

This might be a bug in rustc

This might be fixed by rust-lang/rust#144711.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

cast-lossless breaks macro
3 participants