| Age | Commit message (Collapse) | Author | Lines |
|
|
|
|
|
|
|
|
|
|
|
const-eval interning: accept interior mutable pointers in final value
…but keep rejecting mutable references
This fixes https://github.com/rust-lang/rust/issues/121610 by no longer firing the lint when there is a pointer with interior mutability in the final value of the constant. On stable, such pointers can be created with code like:
```rust
pub enum JsValue {
Undefined,
Object(Cell<bool>),
}
impl Drop for JsValue {
fn drop(&mut self) {}
}
// This does *not* get promoted since `JsValue` has a destructor.
// However, the outer scope rule applies, still giving this 'static lifetime.
const UNDEFINED: &JsValue = &JsValue::Undefined;
```
It's not great to accept such values since people *might* think that it is legal to mutate them with unsafe code. (This is related to how "infectious" `UnsafeCell` is, which is a [wide open question](https://github.com/rust-lang/unsafe-code-guidelines/issues/236).) However, we [explicitly document](https://doc.rust-lang.org/reference/behavior-considered-undefined.html) that things created by `const` are immutable. Furthermore, we also accept the following even more questionable code without any lint today:
```rust
let x: &'static Option<Cell<i32>> = &None;
```
This is even more questionable since it does *not* involve a `const`, and yet still puts the data into immutable memory. We could view this as promotion [potentially introducing UB](https://github.com/rust-lang/unsafe-code-guidelines/issues/493). However, we've accepted this since ~forever and it's [too late to reject this now](https://github.com/rust-lang/rust/pull/122789); the pattern is just too useful.
So basically, if you think that `UnsafeCell` should be tracked fully precisely, then you should want the lint we currently emit to be removed, which this PR does. If you think `UnsafeCell` should "infect" surrounding `enum`s, the big problem is really https://github.com/rust-lang/unsafe-code-guidelines/issues/493 which does not trigger the lint -- the cases the lint triggers on are actually the "harmless" ones as there is an explicit surrounding `const` explaining why things end up being immutable.
What all this goes to show is that the hard error added in https://github.com/rust-lang/rust/pull/118324 (later turned into the future-compat lint that I am now suggesting we remove) was based on some wrong assumptions, at least insofar as it concerns shared references. Furthermore, that lint does not help at all for the most problematic case here where the potential UB is completely implicit. (In fact, the lint is actively in the way of [my preferred long-term strategy](https://github.com/rust-lang/unsafe-code-guidelines/issues/493#issuecomment-2028674105) for dealing with this UB.) So I think we should go back to square one and remove that error/lint for shared references. For mutable references, it does seem to work as intended, so we can keep it. Here it serves as a safety net in case the static checks that try to contain mutable references to the inside of a const initializer are not working as intended; I therefore made the check ICE to encourage users to tell us if that safety net is triggered.
Closes https://github.com/rust-lang/rust/issues/122153 by removing the lint.
Cc `@rust-lang/opsem` `@rust-lang/lang`
|
|
Simplify some nested `if` statements
Applies some but not all instances of `clippy::collapsible_if`. Some ended up looking worse afterwards, though, so I left those out. Also applies instances of `clippy::collapsible_else_if`
Review with whitespace disabled please.
|
|
Remove needless returns detected by clippy in the compiler
|
|
|
|
keep rejecting mutable references)
|
|
|
|
|
|
|
|
Enable Miri to pass pointers through FFI
Following https://github.com/rust-lang/rust/pull/126787, the purpose of this PR is to now enable Miri to execute native calls that make use of pointers.
> <details>
>
> <summary> Simple example </summary>
>
> ```rust
> extern "C" {
> fn ptr_printer(ptr: *mut i32);
> }
>
> fn main() {
> let ptr = &mut 42 as *mut i32;
> unsafe {
> ptr_printer(ptr);
> }
> }
> ```
> ```c
> void ptr_printer(int *ptr) {
> printf("printing pointer dereference from C: %d\n", *ptr);
> }
> ```
> should now show `printing pointer dereference from C: 42`.
>
> </details>
Note that this PR does not yet implement any logic involved in updating Miri's "analysis" state (byte initialization, provenance) upon such a native call.
r? ``@RalfJung``
|
|
Co-authored-by: Ralf Jung <post@ralfj.de>
|
|
I am surprised the diff is so small for this enormous crate.
|
|
|
|
|
|
|
|
|
|
miri: fix offset_from behavior on wildcard pointers
offset_from wouldn't behave correctly when the "end" pointer was a wildcard pointer (result of an int2ptr cast) just at the end of the allocation. Fix that by expressing the "same allocation" check in terms of two `check_ptr_access_signed` instead of something specific to offset_from, which is both more canonical and works better with wildcard pointers.
The second commit just improves diagnostics: I wanted the "pointer is dangling (has no provenance)" message to say how many bytes of memory it expected to see (since if it were 0 bytes, this would actually be legal, so it's good to tell the user that it's not 0 bytes). And then I was annoying that the error looks so different for when you deref a dangling pointer vs an out-of-bounds pointer so I made them more similar.
Fixes https://github.com/rust-lang/miri/issues/3767
|
|
The previous commit updated `rustfmt.toml` appropriately. This commit is
the outcome of running `x fmt --all` with the new formatting options.
|
|
|
|
Try to fix ICE from re-interning an AllocId with different allocation contents
As far as I can tell, based on my investigation in https://github.com/rust-lang/rust/issues/126741, the racy decoding scheme implemented here was never fully correct, but the arrangement of Allocations that's required to ICE the compiler requires some very specific MIR optimizations to create. As far as I can tell, GVN likes to create the problematic pattern, which is why we're noticing this problem now.
So the solution here is to not do racy decoding. If two threads race to decoding an AllocId, one of them is going to sit on a lock until the other is done.
|
|
|
|
|
|
|
|
|
|
Miri function identity hack: account for possible inlining
Having a non-lifetime generic is not the only reason a function can be duplicated. Another possibility is that the function may be eligible for cross-crate inlining. So also take into account the inlining attribute in this Miri hack for function pointer identity.
That said, `cross_crate_inlinable` will still sometimes return true even for `inline(never)` functions:
- when they are `DefKind::Ctor(..) | DefKind::Closure` -- I assume those cannot be `InlineAttr::Never` anyway?
- when `cross_crate_inline_threshold == InliningThreshold::Always`
so maybe this is still not quite the right criterion to use for function pointer identity.
|
|
|
|
|
|
|
|
get_bytes_unchecked_raw in allocation.rs; add pub fn get_alloc_bytes_unchecked_raw[_mut] in memory.rs
|
|
interpret: better error when we ran out of memory
|
|
|
|
|
|
This excludes casting, which needs more tests.
|
|
|
|
|
|
|
|
|
|
[perf] Delay the construction of early lint diag structs
Attacks some of the perf regressions from https://github.com/rust-lang/rust/pull/124417#issuecomment-2123700666.
See individual commits for details. The first three commits are not strictly necessary.
However, the 2nd one (06bc4fc67145e3a7be9b5a2cf2b5968cef36e587, *Remove `LintDiagnostic::msg`*) makes the main change way nicer to implement.
It's also pretty sweet on its own if I may say so myself.
|
|
Remove more `#[macro_use] extern crate tracing`
Because explicit importing of macros via use items is nicer (more standard and readable) than implicit importing via `#[macro_use]`. Continuing the work from #124511 and #124914.
r? `@jackh726`
|
|
|
|
|
|
* instead simply set the primary message inside the lint decorator functions
* it used to be this way before [#]101986 which introduced `msg` to prevent
good path delayed bugs (which no longer exist) from firing under certain
circumstances when lints were suppressed / silenced
* this is no longer necessary for various reasons I presume
* it shaves off complexity and makes further changes easier to implement
|
|
|
|
|
|
This requires exporting the interpreter macros so they can be used with
`use crate::interpret::*`.
|
|
It is optimized for lists with a single element, avoiding the need for
an allocation in that case. But `SmallVec<[T; 1]>` also avoids the
allocation, and is better in general: more standard, log2 number of
allocations if the list exceeds one item, and a much more capable API.
This commit removes `TinyList` and converts the two uses to
`SmallVec<[T; 1]>`. It also reorders the `use` items in the relevant
file so they are in just two sections (`pub` and non-`pub`), ordered
alphabetically, instead of many sections. (This is a relevant part of
the change because I had to decide where to add a `use` item for
`SmallVec`.)
|