allow mutable references in const values when they point to no memory
Fixes https://github.com/rust-lang/rust/issues/120450
The second commit is just some drive-by test suite cleanup.
r? `@oli-obk`
Implement intrinsics with fallback bodies
fixes#93145 (though we can port many more intrinsics)
cc #63585
The way this works is that the backend logic for generating custom code for intrinsics has been made fallible. The only failure path is "this intrinsic is unknown". The `Instance` (that was `InstanceDef::Intrinsic`) then gets converted to `InstanceDef::Item`, which represents the fallback body. A regular function call to that body is then codegenned. This is currently implemented for
* codegen_ssa (so llvm and gcc)
* codegen_cranelift
other backends will need to adjust, but they can just keep doing what they were doing if they prefer (though adding new intrinsics to the compiler will then require them to implement them, instead of getting the fallback body).
cc `@scottmcm` `@WaffleLapkin`
### todo
* [ ] miri support
* [x] default intrinsic name to name of function instead of requiring it to be specified in attribute
* [x] make sure that the bodies are always available (must be collected for metadata)
Instead we re-use the static's alloc id within the interpreter for its initializer to refer to the `Allocation` that only exists within the interpreter.
Continue compilation after check_mod_type_wf errors
The ICEs fixed here were probably reachable through const eval gymnastics before, but now they are easily reachable without that, too.
The new errors are often bugfixes, where useful errors were missing, because they were reported after the early abort. In other cases sometimes they are just duplication of already emitted errors, which won't be user-visible due to deduplication.
fixes https://github.com/rust-lang/rust/issues/120860
add another test for promoteds-in-static
https://github.com/rust-lang/rust/pull/119614 led to validation of promoteds recursing into statics. These statics can point to `static mut` and interior mutable `static` and do other things we don't allow in `const`, but promoteds are validated as `const`, so we get strange errors (saying "in `const`" when there is no const) and surprising validation failures.
https://github.com/rust-lang/rust/pull/120960 fixes that; this here adds another test.
r? ``@oli-obk``
Fixes https://github.com/rust-lang/rust/issues/120968
check_consts: fix duplicate errors, make importance consistent
This is stuff I noticed while working on https://github.com/rust-lang/rust/pull/120932, but it's orthogonal to that PR.
r? ``@oli-obk``
This also now allows promoteds everywhere to point to 'extern static', because why not?
We still check that constants cannot transitively reach 'extern static' through references.
(We allow it through raw pointers.)
static mut: allow mutable reference to arbitrary types, not just slices and arrays
For historical reasons, we allow this:
```rust
static mut ARRAY: &'static mut [isize] = &mut [1];
```
However, we do not allow this:
```rust
static mut INT: &'static mut isize = &mut 1;
```
I think that's terribly inconsistent. I don't care much for `static mut`, but we have to keep it around for backwards compatibility and so we have to keep supporting it properly in the compiler. In recent refactors of how we deal with mutability of data in `static` and `const`, I almost made a fatal mistake since I tested `static mut INT: &'static mut isize = &mut 1` and concluded that we don't allow such `'static` mutable references even inside `static mut`. After all, nobody would expect this to be allowed only for arrays and slices, right?!?? So for the sake of our own sanity, and of whoever else reverse engineers these rules in the future to understand what the Rust compiler accepts or does not accept, I propose that we accept this for all types, not just arrays and slices.
Rollup of 9 pull requests
Successful merges:
- #119939 (Improve 'generic param from outer item' error for `Self` and inside `static`/`const` items)
- #120331 (pattern_analysis: use a plain `Vec` in `DeconstructedPat`)
- #120396 (Account for unbounded type param receiver in suggestions)
- #120423 (update indirect structural match lints to match RFC and to show up for dependencies)
- #120435 (Suggest name value cfg when only value is used for check-cfg)
- #120502 (Remove `ffi_returns_twice` feature)
- #120507 (Account for non-overlapping unmet trait bounds in suggestion)
- #120513 (Normalize type outlives obligations in NLL for new solver)
- #120707 (Don't expect early-bound region to be local when reporting errors in RPITIT well-formedness)
r? `@ghost`
`@rustbot` modify labels: rollup
Rollup of 8 pull requests
Successful merges:
- #119759 (Add FileCheck annotations to dataflow-const-prop tests)
- #120323 (On E0277 be clearer about implicit `Sized` bounds on type params and assoc types)
- #120473 (Only suggest removal of `as_*` and `to_` conversion methods on E0308)
- #120540 (add test for try-block-in-match-arm)
- #120547 (`#![feature(inline_const_pat)]` is no longer incomplete)
- #120552 (Correctly check `never_type` feature gating)
- #120555 (put pnkfelix (me) back on the review queue.)
- #120556 (Improve the diagnostics for unused generic parameters)
r? `@ghost`
`@rustbot` modify labels: rollup
Rollup of 8 pull requests
Successful merges:
- #120484 (Avoid ICE when is_val_statically_known is not of a supported type)
- #120516 (pattern_analysis: cleanup manual impls)
- #120517 (never patterns: It is correct to lower `!` to `_`.)
- #120523 (Improve `io::Read::read_buf_exact` error case)
- #120528 (Store SHOULD_CAPTURE as AtomicU8)
- #120529 (Update data layouts in custom target tests for LLVM 18)
- #120531 (Remove a bunch of `has_errors` checks that have no meaningful or the wrong effect)
- #120533 (Correct paths for hexagon-unknown-none-elf platform doc)
r? `@ghost`
`@rustbot` modify labels: rollup
Don't hash lints differently to non-lints.
`Diagnostic::keys`, which is used for hashing and equating diagnostics, has a surprising behaviour: it ignores children, but only for lints. This was added in #88493 to fix some duplicated diagnostics, but it doesn't seem necessary any more.
This commit removes the special case and only four tests have changed output, with additional errors. And those additional errors aren't exact duplicates, they're just similar. For example, in src/tools/clippy/tests/ui/same_name_method.rs we currently have this error:
```
error: method's name is the same as an existing method in a trait
--> $DIR/same_name_method.rs:75:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
|
note: existing `foo` defined here
--> $DIR/same_name_method.rs:79:9
|
LL | impl T1 for S {}
| ^^^^^^^^^^^^^^^^
```
and with this change we also get this error:
```
error: method's name is the same as an existing method in a trait
--> $DIR/same_name_method.rs:75:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
|
note: existing `foo` defined here
--> $DIR/same_name_method.rs:81:9
|
LL | impl T2 for S {}
|
```
I think printing this second argument is reasonable, possibly even preferable to hiding it. And the other cases are similar.
r? `@estebank`
Expand the primary span of E0277 when the immediate unmet bound is not what the user wrote:
```
error[E0277]: the trait bound `i32: Bar` is not satisfied
--> f100.rs:6:6
|
6 | <i32 as Foo>::foo();
| ^^^ the trait `Bar` is not implemented for `i32`, which is required by `i32: Foo`
|
help: this trait has no implementations, consider adding one
--> f100.rs:2:1
|
2 | trait Bar {}
| ^^^^^^^^^
note: required for `i32` to implement `Foo`
--> f100.rs:3:14
|
3 | impl<T: Bar> Foo for T {}
| --- ^^^ ^
| |
| unsatisfied trait bound introduced here
```
Fix#40120.
`Diagnostic::keys`, which is used for hashing and equating diagnostics,
has a surprising behaviour: it ignores children, but only for lints.
This was added in #88493 to fix some duplicated diagnostics, but it
doesn't seem necessary any more.
This commit removes the special case and only four tests have changed
output, with additional errors. And those additional errors aren't
exact duplicates, they're just similar. For example, in
src/tools/clippy/tests/ui/same_name_method.rs we currently have this
error:
```
error: method's name is the same as an existing method in a trait
--> $DIR/same_name_method.rs:75:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
|
note: existing `foo` defined here
--> $DIR/same_name_method.rs:79:9
|
LL | impl T1 for S {}
| ^^^^^^^^^^^^^^^^
```
and with this change we also get this error:
```
error: method's name is the same as an existing method in a trait
--> $DIR/same_name_method.rs:75:13
|
LL | fn foo() {}
| ^^^^^^^^^^^
|
note: existing `foo` defined here
--> $DIR/same_name_method.rs:81:9
|
LL | impl T2 for S {}
| ^^^^^^^^^^^^^^^^
```
I think printing this second argument is reasonable, possibly even
preferable to hiding it. And the other cases are similar.