Skip to content

Unnecessary references lint#138230

Open
obeis wants to merge 2 commits into
rust-lang:mainfrom
obeis:lint-unnecessary-reference
Open

Unnecessary references lint#138230
obeis wants to merge 2 commits into
rust-lang:mainfrom
obeis:lint-unnecessary-reference

Conversation

@obeis

@obeis obeis commented Mar 8, 2025

Copy link
Copy Markdown
Contributor

@rustbot

rustbot commented Mar 8, 2025

Copy link
Copy Markdown
Collaborator

r? @Noratrieb

rustbot has assigned @Noratrieb.
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 S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 8, 2025
@rustbot

rustbot commented Mar 8, 2025

Copy link
Copy Markdown
Collaborator

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

@rust-log-analyzer

This comment has been minimized.

@compiler-errors compiler-errors left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This lint seems really specific to a single kind of expression, and there are plenty of other cases where unnecessary references are created when the user is trying to create a raw pointer. Unless this can be greatly generalized, it doesn't really seem worth adding this.

@compiler-errors

Copy link
Copy Markdown
Contributor

r? RalfJung

@rustbot rustbot assigned RalfJung and unassigned Noratrieb Mar 8, 2025
@obeis

obeis commented Mar 8, 2025

Copy link
Copy Markdown
Contributor Author

I agree, and my intention is to generalize this lint to cover all unnecessarily created references. Could you please list other cases that you think should be included? I can update this PR to cover them or create an issue to track these cases and mention that they should be added to the unnecessary_refs lint.

@RalfJung

RalfJung commented Mar 9, 2025 via email

Copy link
Copy Markdown
Member

@rustbot rustbot assigned SparrowLii and unassigned RalfJung Mar 9, 2025
@traviscross traviscross added T-lang Relevant to the language team needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Mar 9, 2025

@SparrowLii SparrowLii left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I know little about lints' impls so r? compiler

@rustbot rustbot assigned Nadrieril and unassigned SparrowLii Mar 10, 2025
@RalfJung

Copy link
Copy Markdown
Member

Do we have some people who are our "linting experts"?

@RalfJung

Copy link
Copy Markdown
Member

This lint seems really specific to a single kind of expression, and there are plenty of other cases where unnecessary references are created when the user is trying to create a raw pointer. Unless this can be greatly generalized, it doesn't really seem worth adding this.

Which examples did you have in mind?

A starting point might be to uplift https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr from cliippy to rustc, as you mention. It is not clear to me what the difference is between that lint and this one.

@traviscross

Copy link
Copy Markdown
Contributor

Do we have some people who are our "linting experts"?

cc @Urgau

@Urgau

Urgau commented Mar 10, 2025

Copy link
Copy Markdown
Member

Happy to take over the review. If @Nadrieril doesn't want to review it of course.

As for the lint it-self, I join @RalfJung that this is lint is currently clippy::borrow_as_ptr, which will need to be dropped from clippy. Look at 1fee1a4 for the changes needed.

As a drive-by, rustc_hir_pretty should not be necessary, a multi-part suggestion should be used instead, with some span manipulation to get the correct spans.

@Nadrieril

Copy link
Copy Markdown
Member

Much appreciated :) r? @Urgau

@rustbot rustbot assigned Urgau and unassigned Nadrieril Mar 11, 2025
@Urgau Urgau added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 12, 2025
Comment thread compiler/rustc_lint/src/unnecessary_refs.rs Outdated
Comment thread compiler/rustc_lint/src/lints.rs Outdated
Comment thread compiler/rustc_lint/src/unnecessary_refs.rs Outdated
Comment thread compiler/rustc_lint/src/unnecessary_refs.rs Outdated
Comment thread compiler/rustc_lint/messages.ftl Outdated
@obeis obeis force-pushed the lint-unnecessary-reference branch from 1e686f1 to e113827 Compare March 18, 2025 18:26
@obeis obeis force-pushed the lint-unnecessary-reference branch from 64132e5 to b0d836f Compare March 24, 2025 22:35
@rust-log-analyzer

This comment has been minimized.

@obeis obeis force-pushed the lint-unnecessary-reference branch 2 times, most recently from 4acb822 to d6d72c8 Compare March 26, 2025 14:04
@rust-log-analyzer

This comment has been minimized.

@bors

bors commented Mar 27, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #139012) made this pull request unmergeable. Please resolve the merge conflicts.

@obeis

obeis commented Apr 14, 2025

Copy link
Copy Markdown
Contributor Author

My PR is currently blocked because the stdarch bump is waiting on a bootstrap bump, see this.

@Dylan-DPC Dylan-DPC added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 30, 2025
@Urgau

Urgau commented Jun 20, 2026

Copy link
Copy Markdown
Member

@obeis What's the status of this PR? Was the stdarch bump issue resolved?

@obeis

obeis commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

@Urgau I think stdarch bump issue is resolved. I will update this PR in few next days.

@RalfJung

Copy link
Copy Markdown
Member

It looks like most of this PR is about fixing occurrences of the lint in library. That's mostly done by adding allow, which is not a great fix.

Maybe it'd make sense to land this lint as allow-by-default first, and then only slowly enable it throughout the library by actually removing the unnecessary references? Given the amount of times this triggers on the library, it seems likely to also trigger a lot in the wider ecosystem, so some sort of slow staging starting with allow-by-default might also make sense from that perspective. (We should definitely get t-lang input before landing this.)

@obeis obeis force-pushed the lint-unnecessary-reference branch from d6d72c8 to 10c6d3c Compare June 24, 2026 22:13
@rustbot

rustbot commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@obeis obeis requested a review from Urgau June 24, 2026 22:14
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 24, 2026
@obeis

obeis commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@RalfJung I agree, let's land this as allow-by-default for now.

@rust-log-analyzer

This comment has been minimized.

@obeis obeis force-pushed the lint-unnecessary-reference branch from 10c6d3c to 5f1cb56 Compare June 24, 2026 22:22
@traviscross traviscross added I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang I-lang-radar Items that are on lang's radar and will need eventual work or consideration. labels Jun 25, 2026
@traviscross

Copy link
Copy Markdown
Contributor

Makes sense to me. Thanks @obeis and @RalfJung.

Lint details

This is an allow-by-default lint:

unnecessary-refs

The unnecessary_refs lint checks for unnecessary references.

Example

#![warn(unnecessary_refs)]

fn via_ref(x: *const (i32, i32)) -> *const i32 {
    unsafe { &(*x).0 as *const i32 }
}

fn main() {
    let x = (0, 1);
    let _r = via_ref(&x);
}

This will produce:

warning: creating an intermediate reference implies aliasing requirements even when immediately casting to raw pointers
 --> lint_example.rs:4:14
  |
4 |     unsafe { &(*x).0 as *const i32 }
  |              ^^^^^^^^^^^^^^^^^^^^^
  |
note: the lint level is defined here
 --> lint_example.rs:1:9
  |
1 | #![warn(unnecessary_refs)]
  |         ^^^^^^^^^^^^^^^^
help: consider using `&raw const` for a safer and more explicit raw pointer
  |
4 -     unsafe { &(*x).0 as *const i32 }
4 +     unsafe { &raw const (*x).0 }
  |

Explanation

Creating unnecessary references is discouraged because it can reduce readability, introduce performance overhead, and lead to undefined behavior if the reference is unaligned or uninitialized. Avoiding them ensures safer and more efficient code.

This lint is proposed at allow-by-default so it can land while we adjust the standard library and gauge effects on the ecosystem.

@rfcbot fcp merge lang


In terms of the current implementation, I understand the following to be true.

fn redundant_block(x: u8) {
    let _x = { &x } as *const u8;
}

It doesn't fire for the above, but should.

fn vec_index_deref(x: *mut Vec<u8>) -> *mut u8 {
    unsafe { &mut (*x)[0] as *mut u8 }
}

It fires for this one, but should not, because the place isn't reachable through built-in projections and so a reference is materialized in MIR regardless. After applying the lint's suggestion, the MIR is the same, and the dangerous_implicit_autorefs lint still fires.

fn vec_index(v: &mut Vec<u8>) -> *mut u8 {
    &mut v[0] as *mut u8
}

Similar to the above, the lint fires and applying the suggestion results in code that produces the same MIR. (In this case, though, dangerous_implicit_autorefs doesn't fire.)

@rust-rfcbot

rust-rfcbot commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

@traviscross has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. and removed needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. labels Jun 25, 2026

#[derive(Diagnostic)]
#[diag(
"creating a intermediate reference implies aliasing requirements even when immediately casting to raw pointers"

@traviscross traviscross Jun 25, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"creating a intermediate reference implies aliasing requirements even when immediately casting to raw pointers"
"creating an intermediate reference implies aliasing requirements even when immediately casting to raw pointers"

View changes since the review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-query-system Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html) disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. O-windows Operating system: Windows P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-blocked Status: Blocked on something else such as an RFC or other implementation work. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lint against expressions that unnecessarily create references