Skip to content
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

Disallow hidden references to mutable static #124895

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

Conversation

obeis
Copy link
Contributor

@obeis obeis commented May 8, 2024

@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 May 8, 2024
@RalfJung
Copy link
Member

RalfJung commented May 8, 2024

Sorry, I can only review interpreter and Miri PRs.

r? compiler

@rustbot rustbot assigned fee1-dead and unassigned RalfJung May 8, 2024
@obeis
Copy link
Contributor Author

obeis commented May 8, 2024

r? @davidtwco

@rustbot rustbot assigned davidtwco and unassigned fee1-dead May 8, 2024
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added A-testsuite Area: The testsuite used to check the correctness of rustc T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) labels May 8, 2024
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@obeis obeis marked this pull request as draft May 8, 2024 19:05
@davidtwco davidtwco 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 May 10, 2024
@davidtwco
Copy link
Member

Marking as waiting on author since you've made this a draft.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@obeis obeis marked this pull request as ready for review May 11, 2024 16:36
@rustbot
Copy link
Collaborator

rustbot commented May 11, 2024

The Miri subtree was changed

cc @rust-lang/miri

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@obeis
Copy link
Contributor Author

obeis commented May 11, 2024

@rustbot ready

@michaelwoerister
Copy link
Member

That error can be solved by pub re-exporting the Edition type here:

// `pub use` because the re-export is referred to by the declare_lint! macro
pub use rustc_span::edition::Edition;

Otherwise the code instantiated when declare_lint! is called from other crates won't have access to the rustc_lint_defs::Edition re-export.

@michaelwoerister
Copy link
Member

Thanks, @traviscross!

What would be an acceptable heuristic for determining from the method signature that the self reference might leak? If all other parameter types and the return type don't contain references -- or is that too simplistic?

@traviscross
Copy link
Contributor

What would be an acceptable heuristic for determining from the method signature that the self reference [doesn't] leak? If all other parameter types and the return type don't contain references -- or is that too simplistic?

Sounds like a start. For PartialEq::eq, though, both arguments are references.

cc @compiler-errors

@bors
Copy link
Contributor

bors commented Aug 27, 2024

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

@traviscross
Copy link
Contributor

In terms of the heuristic, I'm trying to think up the maximally-pessimistic example of how the reference could leak. Perhaps it's something like this:

use core::cell::Cell;

struct W<'w>(Cell<Option<&'w W<'w>>>);
impl<'w> W<'w> {
    fn leak<'a: 'w>(&'a self) {
        self.0.set(Some(self));
    }
}


fn main() {
    static mut X: W = W(Cell::new(None));
    unsafe { X.leak() };
    let leaked = unsafe { X.0.get().unwrap() };
    _ = [leaked];
}

Playground link

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

compiler/rustc_lint/src/static_mut_refs.rs Outdated Show resolved Hide resolved
compiler/rustc_lint/messages.ftl Outdated Show resolved Hide resolved
compiler/rustc_lint/messages.ftl Outdated Show resolved Hide resolved
compiler/rustc_lint/src/lints.rs Outdated Show resolved Hide resolved
compiler/rustc_lint/src/lints.rs Outdated Show resolved Hide resolved
compiler/rustc_lint/src/static_mut_refs.rs Outdated Show resolved Hide resolved
tests/ui/lint/static-mut-refs.rs Outdated Show resolved Hide resolved
tests/ui/lint/static-mut-refs.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@traviscross traviscross left a comment

Choose a reason for hiding this comment

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

The changes I asked for were addressed.

Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

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

Please change all of the FIXME(obeis) to not reference a specific username, since this is probably grouped under something better like FIXME(static_mut_refs).

Also, are all of the test changes still necessary? Do we really need to change STATIC += 1 to STATIC = STATIC + 1? If we're motivating users to make somewhat churn-y noop changes to their code, I really don't think this lint is complete yet. If not, then those should be reverted.

Same with x.is_some() to let Some(_) = X, and most of the other changes to tests.

Existing tests should not be changing static mut to static or to use atomics. In general, tests should be left alone, and have allow(static_mut_refs) added to the top. There's no reason to add FIXMEs to those -- some of these tests are explicitly using static muts to exercise their behavior in the compiler.

@compiler-errors
Copy link
Member

compiler-errors commented Sep 6, 2024

I was perhaps a bit too knee-jerky on the test changes, but they're really hard to separate out the changes from an initial glance.

I would prefe us to separately in a follow-up PR (or maybe even a PR that lands before this one) that we could tweak some of the test to use Atomics over static mut if they're run-pass tests. In the mean time, would prefer if we tag them FIXME(static_mut_refs): this could use an atomic rather than also trying to change them at the same time as implementing this lint.

Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

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

There are also some random stray files that need to be deleted:

  • compiler/rustc_lint_defs/src/lib.rs:11:5
  • compiler/rustc_lint_defs/src/lib.rs:887:48

}
hir::ExprKind::MethodCall(_, e, _, _)
if let Some(err_span) = path_is_static_mut(e, expr.span)
&& let typeck = cx.tcx.typeck(expr.hir_id.owner)
Copy link
Member

Choose a reason for hiding this comment

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

You should use cx.typeck_results here instead of calling the query: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LateContext.html#method.typeck_results

Comment on lines 86 to 92
&& let inputs =
cx.tcx.fn_sig(method_def_id).skip_binder().inputs().skip_binder()
&& !inputs.is_empty()
&& inputs[0].is_ref() =>
{
let m =
if let TyKind::Ref(_, _, m) = inputs[0].kind() { *m } else { Mutability::Not };
Copy link
Member

Choose a reason for hiding this comment

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

This can be simplified into something like let Some(receiver) = inputs.get(0) && let ty::Ref(_, _, m) = receiver.kind().

cx: &LateContext<'_>,
span: Span,
sugg_span: Span,
mutable: Option<Mutability>,
Copy link
Member

Choose a reason for hiding this comment

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

There's never a case where this isn't Some on the caller side, so this could be simplified to just Mutability.

@compiler-errors
Copy link
Member

compiler-errors commented Sep 6, 2024

I'd personally rather we try to make this lint a bit less trigger-prone if possible. I'd be fine even if we implement it only for totally unconstrained late-bound receiver lifetimes where the lifetime does not show up in the return type or something like that.

But that's my personal opinion; I guess if T-lang is fine with this amount of churn then whatever.

@michaelwoerister
Copy link
Member

r? @compiler-errors -- I'm not a good reviewer for this other than the basics.

@bors
Copy link
Contributor

bors commented Sep 13, 2024

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

@obeis
Copy link
Contributor Author

obeis commented Sep 13, 2024

@compiler-errors Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-edition-2024 Area: The 2024 edition A-testsuite Area: The testsuite used to check the correctness of rustc O-wasm Target: WASM (WebAssembly), http://webassembly.org/ S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

static_mut_refs: Should the lint cover hidden references?