-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Add lint against (some) interior mutable consts #132146
base: master
Are you sure you want to change the base?
Conversation
This lint seems to be the same as (or limited version of) AFAIK |
This comment has been minimized.
This comment has been minimized.
Forgot to mentioned it (fixed), but yes it's a very-limited form of the clippy lint.
I disagree that it is useless. It detects suspicious constants item, suspicious enough that they are probably a mistake and IMO warrants a warning. In other words I think this lint detects potential issues at the root cause and not at the usage site. I would find it weird if we warned when using a const-item from an external crate, where the user can't do anything about it (except maybe creating an issue upstream) but I also think I could be convinced otherwise.
I did not actually see this lint before, it's interesting and tackles the issue at another level; but IMO declaring a interior mutable const is a foot-gun whenever used or not, in particular if exposed and used from an external crate.
This should use inline const, which is suggested by this lint. |
f812ff2
to
f1634d8
Compare
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
This comment has been minimized.
This comment has been minimized.
Ah, we each seem to have a different case in mind. I was thinking of a case where const is correct and the usage referring to it is incorrect, and you seem to be thinking of a case where defining it as const is wrong and the usage referring to it is supposedly correct. I agree that this lint is indeed not necessarily useless in such a case.
It seems unfortunate that lint, for which the only two ways to deal with warnings are to ignore the warning or increase the MSRV, will be added as warn-by-default. After reading your comment, I think it would be better to apply this lint only to public constants, and uplift
|
Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 |
This comment has been minimized.
This comment has been minimized.
c059fe1
to
3e46a9a
Compare
This comment has been minimized.
This comment has been minimized.
3e46a9a
to
fe98149
Compare
This comment was marked as resolved.
This comment was marked as resolved.
fe98149
to
d29f661
Compare
Yes, there seems to be some of cases in the wildly were it's the case. (both of the linked issues are example of that) Example of a soundness issue caused by using a const-item instead of a static-itemuse std::sync::Once;
// SAFETY: should only be call once
unsafe extern "C" fn ffi_init() { /* ... */ }
const INIT_ONCE: Once = Once::new(); // using `B` will always creates temporaries and
// never modify it-self on use, should be a
// static-item instead
fn init() {
INIT_ONCE.call_once(|| unsafe {
ffi_init(); // unsound, as the `call_once` is on a temporary
// and not on a shared variable
})
} Updated the lint example with this one, to better describe the usefulness of the lint
Interesting idea. I'm not sure I like having the lint be dependant of the visibility of the const-item since it has nothing to do with the issue it-self, see my example above or #132028, where the issue is not the usage but the declaration, with your proposal we IMO would be linting at the wrong place. (We could lint at the declaration only if we found a usage, but that seems hacky and I rather avoid that) |
This comment has been minimized.
This comment has been minimized.
d29f661
to
e46943e
Compare
@@ -1,5 +1,5 @@ | |||
#![warn(clippy::declare_interior_mutable_const)] | |||
|
|||
#![allow(interior_mutable_consts)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do those Clippy lints interact with the new rustc lint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This proposed lint is similar to clippy::declare_interior_mutable_const
, except that contrary to the Clippy lint which recurse into the type and can lint on arbitrary type that have interior mutability, this lint only checks if the type is marked with #[rustc_significant_interior_mutable_type]
(which only concerns a few core/std types).
So for these types (and only these types) we would report a similar warning. (Preventing this duplicated warning should be a matter of checking if the type as the attribute).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer adding this check to the Clippy lints, over just allowing the rustc lint in the tests.
The tests could then be adapted to remove all test cases that get linted by rustc
, except for maybe 1 to check that the Clippy lint doesn't actually trigger on those core/std types.
e46943e
to
84243a7
Compare
84243a7
to
8aaf94d
Compare
This comment has been minimized.
This comment has been minimized.
8aaf94d
to
1d6f0e9
Compare
☔ The latest upstream changes (presumably #135726) made this pull request unmergeable. Please resolve the merge conflicts. |
1d6f0e9
to
9e7f71c
Compare
Some changes occurred in compiler/rustc_passes/src/check_attr.rs |
/// unsafe extern "C" fn ffi_init() { /* ... */ } | ||
/// | ||
/// const A: Once = Once::new(); // using `B` will always creates temporaries and | ||
/// // never modify it-self on use, should be a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// // never modify it-self on use, should be a | |
/// // never modify itself on use, should be a |
@@ -426,6 +426,14 @@ lint_incomplete_include = | |||
lint_inner_macro_attribute_unstable = inner macro attributes are unstable | |||
lint_interior_mutable_consts = interior mutability in `const` item have no effect to the `const` item itself |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lint_interior_mutable_consts = interior mutability in `const` item have no effect to the `const` item itself | |
lint_interior_mutable_consts = interior mutability in `const` items have no effect on the `const` item itself |
I'm trying to decide whether I like this or not. What I like about it is where it might help catch errors, of course. What I don't like about it is that probably I actually think it's fine to use a const item as a kind of "const alias" (or like a thunk const function), and so I'm hesitant to discourage that as much as this lint probably would. That is, it seems maybe fine to use a const item to set up some interior mutable type how you want it, and then to use that in initializers, e.g. Regarding this bit:
This could be troublesome for us. Each time we'd want to extend this, it could be a significant lint expansion in terms of the amount of code affected, but the fix is not machine-applicable. |
In terms of "experience report", an almost identical repro of #132028 occurred on reddit today. |
In the case of array initializer we should maybe recommend inline const
If we only recommend the |
The point is that we could have: const INIT: .. = {
..
..
..
..
};
let (x, y, z) = ([INIT; 128], [INIT; 128], [INIT; 128]); Clearly we wouldn't just want to inline the body of the const initializer into each array initializer in const fn make_init() -> .. {
..
..
..
..
}
let (x, y, z) = ([const { make_init() }; 128], [const { make_init() }; 128], [const { make_init() }; 128]); That's what I'm not really sure it'd be great for us to impose. Then, going a step further, it seems like anywhere we have const INIT: .. = make_init();
let (x, y, z) = ([INIT; 128], [INIT; 128], [INIT; 128]); And I could see it being surprising if we warned against this kind of natural refactoring in this one case. |
Hum, I see, thanks for the bigger example. We could maybe have exception for local (not pub) interior mutable const used only as initializer (only array initializer?) and nothing else. |
This comment was marked as resolved.
This comment was marked as resolved.
9e7f71c
to
f504b26
Compare
This comment has been minimized.
This comment has been minimized.
f504b26
to
0c8f814
Compare
interior_mutable_consts
warn-by-default
The
interior_mutable_consts
lint detects instance where const-items have a interior mutable type, which silently does nothing.Example
Explanation
Using a const-item with an interior mutable type has no effect as const-item are essentially inlined wherever they are used, meaning that they are copied directly into the relevant context when used rendering modification through interior mutability ineffective across usage of that const-item.
The current implementation of this lint only warns on significant
std
andcore
interior mutable types, likeOnce
,AtomicI32
, ... this is done out of prudence and may be extended in the future.It should be noted that the lint in not immunized against false-positives in particular when those immutable const-items are used as "init" const for const arrays (i.e.
[INIT; 10]
), which is why the lint recommends inline-const instead.It should also be noted that this is NOT an uplift of the more general
clippy::declare_interior_mutable_const
lint, which works for all interior mutable types, but has even more false-positives than the currently proposed lint.A simple Github Search reveals many instance where the user probably wanted to use a
static
-item instead.@rustbot labels +I-lang-nominated +T-lang -S-waiting-on-review
cc @AngelicosPhosphoros @kupiakos
r? compiler
Fixes IRLO - Forbidding creation of constant mutexes, etc
Fixes #132028
Fixes #40543