Represent MIR composite debuginfo as projections instead of aggregates
Composite debuginfo for MIR is currently represented as
```
debug name => Type { projection1 => place1, projection2 => place2 };
```
ie. a single `VarDebugInfo` object with that name, and its value a `VarDebugInfoContents::Composite`.
This PR proposes to reverse the representation to be
```
debug name.projection1 => place1;
debug name.projection2 => place2;
```
ie. multiple `VarDebugInfo` objects with each their projection.
This simplifies the handling of composite debuginfo by the compiler by avoiding weird nesting.
Based on https://github.com/rust-lang/rust/pull/115139
Add `FreezeLock` type and use it to store `Definitions`
This adds a `FreezeLock` type which allows mutation using a lock until the value is frozen where it can be accessed lock-free. It's used to store `Definitions` in `Untracked` instead of a `RwLock`. Unlike the current scheme of leaking read guards this doesn't deadlock if definitions is written to after no mutation are expected.
Use relative positions inside a SourceFile.
This allows to remove the normalization of start positions for hashing, and simplify allocation of global address space.
cc `@Zoxc`
Encode DepKind as u16
The derived Encodable/Decodable impls serialize/deserialize as a varint, which results in a lot of code size around the encoding/decoding of these types which isn't justified: The full range of values here is rather small but doesn't quite fit in to a `u8`. Growing _all_ serialized `DepKind` to 2 bytes costs us on average 1% size in the incr comp dep graph, which I plan to recoup in https://github.com/rust-lang/rust/pull/110050 by taking advantage of the unused bits in all the serialized `DepKind`.
r? `@nnethercote`
Make `get_return_block()` return `Some` only for HIR nodes in body
Fixes#114918
The issue occurred while compiling the following input:
```rust
fn uwu() -> [(); { () }] {
loop {}
}
```
It was caused by the code below trying to suggest a missing return type which resulted in a const eval cycle: 1bd043098e/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs (L68-L75)
The root cause was `get_return_block()` returning an `Fn` node for a node in the return type (i.e. the second `()` in the return type `[(); { () }]` of the input) although it is supposed to do so only for nodes that lie in the body of the function and return `None` otherwise (at least as per my understanding).
The PR fixes the issue by fixing this behaviour of `get_return_block()`.
Remove conditional use of `Sharded` from query state
`Sharded` is already a zero cost abstraction, so it shouldn't affect the performance of the single thread compiler if LLVM does its job.
r? `@cjgillot`
Allow explicit `#[repr(Rust)]`
This is identical to no `repr()` at all. For `Rust, packed` and `Rust, align(x)`, it should be the same as no `Rust` at all (as, afaik, `#[repr(align(16))]` uses the Rust ABI.)
The main use case for this is being able to explicitly say "I want to use the Rust ABI" in very very rare circumstances where the first obvious choice would be the C ABI yet is undesirable, which is already possible with functions as `extern "Rust"`. This would be useful for silencing https://github.com/rust-lang/rust-clippy/pull/11253. It's also more consistent with `extern`.
The lack of this also tripped me up a bit when I was new to Rust, as I expected this to be possible.
Point at return type when it influences non-first `match` arm
When encountering code like
```rust
fn foo() -> i32 {
match 0 {
1 => return 0,
2 => "",
_ => 1,
}
}
```
Point at the return type and not at the prior arm, as that arm has type `!` which isn't influencing the arm corresponding to arm `2`.
Fix#78124.
Couple of global state and driver refactors
* Remove some unused global mutable state
* Remove a couple of unnecessary queries (both driver and `TyCtxt` queries)
* Remove an unnecessary use of `FxIndexMap`
When encountering code like
```rust
fn foo() -> i32 {
match 0 {
1 => return 0,
2 => "",
_ => 1,
}
}
```
Point at the return type and not at the prior arm, as that arm has type
`!` which isn't influencing the arm corresponding to arm `2`.
Fix#78124.
feat: `riscv-interrupt-{m,s}` calling conventions
Similar to prior support added for the mips430, avr, and x86 targets this change implements the rough equivalent of clang's [`__attribute__((interrupt))`][clang-attr] for riscv targets, enabling e.g.
```rust
static mut CNT: usize = 0;
pub extern "riscv-interrupt-m" fn isr_m() {
unsafe {
CNT += 1;
}
}
```
to produce highly effective assembly like:
```asm
pub extern "riscv-interrupt-m" fn isr_m() {
420003a0: 1141 addi sp,sp,-16
unsafe {
CNT += 1;
420003a2: c62a sw a0,12(sp)
420003a4: c42e sw a1,8(sp)
420003a6: 3fc80537 lui a0,0x3fc80
420003aa: 63c52583 lw a1,1596(a0) # 3fc8063c <_ZN12esp_riscv_rt3CNT17hcec3e3a214887d53E.0>
420003ae: 0585 addi a1,a1,1
420003b0: 62b52e23 sw a1,1596(a0)
}
}
420003b4: 4532 lw a0,12(sp)
420003b6: 45a2 lw a1,8(sp)
420003b8: 0141 addi sp,sp,16
420003ba: 30200073 mret
```
(disassembly via `riscv64-unknown-elf-objdump -C -S --disassemble ./esp32c3-hal/target/riscv32imc-unknown-none-elf/release/examples/gpio_interrupt`)
This outcome is superior to hand-coded interrupt routines which, lacking visibility into any non-assembly body of the interrupt handler, have to be very conservative and save the [entire CPU state to the stack frame][full-frame-save]. By instead asking LLVM to only save the registers that it uses, we defer the decision to the tool with the best context: it can more accurately account for the cost of spills if it knows that every additional register used is already at the cost of an implicit spill.
At the LLVM level, this is apparently [implemented by] marking every register as "[callee-save]," matching the semantics of an interrupt handler nicely (it has to leave the CPU state just as it found it after its `{m|s}ret`).
This approach is not suitable for every interrupt handler, as it makes no attempt to e.g. save the state in a user-accessible stack frame. For a full discussion of those challenges and tradeoffs, please refer to [the interrupt calling conventions RFC][rfc].
Inside rustc, this implementation differs from prior art because LLVM does not expose the "all-saved" function flavor as a calling convention directly, instead preferring to use an attribute that allows for differentiating between "machine-mode" and "superivsor-mode" interrupts.
Finally, some effort has been made to guide those who may not yet be aware of the differences between machine-mode and supervisor-mode interrupts as to why no `riscv-interrupt` calling convention is exposed through rustc, and similarly for why `riscv-interrupt-u` makes no appearance (as it would complicate future LLVM upgrades).
[clang-attr]: https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v
[full-frame-save]: 9281af2ecf/src/lib.rs (L440-L469)
[implemented by]: b7fb2a3fec/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp (L61-L67)
[callee-save]: 973f1fe7a8/llvm/lib/Target/RISCV/RISCVCallingConv.td (L30-L37)
[rfc]: https://github.com/rust-lang/rfcs/pull/3246
Similar to prior support added for the mips430, avr, and x86 targets
this change implements the rough equivalent of clang's
[`__attribute__((interrupt))`][clang-attr] for riscv targets, enabling
e.g.
```rust
static mut CNT: usize = 0;
pub extern "riscv-interrupt-m" fn isr_m() {
unsafe {
CNT += 1;
}
}
```
to produce highly effective assembly like:
```asm
pub extern "riscv-interrupt-m" fn isr_m() {
420003a0: 1141 addi sp,sp,-16
unsafe {
CNT += 1;
420003a2: c62a sw a0,12(sp)
420003a4: c42e sw a1,8(sp)
420003a6: 3fc80537 lui a0,0x3fc80
420003aa: 63c52583 lw a1,1596(a0) # 3fc8063c <_ZN12esp_riscv_rt3CNT17hcec3e3a214887d53E.0>
420003ae: 0585 addi a1,a1,1
420003b0: 62b52e23 sw a1,1596(a0)
}
}
420003b4: 4532 lw a0,12(sp)
420003b6: 45a2 lw a1,8(sp)
420003b8: 0141 addi sp,sp,16
420003ba: 30200073 mret
```
(disassembly via `riscv64-unknown-elf-objdump -C -S --disassemble ./esp32c3-hal/target/riscv32imc-unknown-none-elf/release/examples/gpio_interrupt`)
This outcome is superior to hand-coded interrupt routines which, lacking
visibility into any non-assembly body of the interrupt handler, have to
be very conservative and save the [entire CPU state to the stack
frame][full-frame-save]. By instead asking LLVM to only save the
registers that it uses, we defer the decision to the tool with the best
context: it can more accurately account for the cost of spills if it
knows that every additional register used is already at the cost of an
implicit spill.
At the LLVM level, this is apparently [implemented by] marking every
register as "[callee-save]," matching the semantics of an interrupt
handler nicely (it has to leave the CPU state just as it found it after
its `{m|s}ret`).
This approach is not suitable for every interrupt handler, as it makes
no attempt to e.g. save the state in a user-accessible stack frame. For
a full discussion of those challenges and tradeoffs, please refer to
[the interrupt calling conventions RFC][rfc].
Inside rustc, this implementation differs from prior art because LLVM
does not expose the "all-saved" function flavor as a calling convention
directly, instead preferring to use an attribute that allows for
differentiating between "machine-mode" and "superivsor-mode" interrupts.
Finally, some effort has been made to guide those who may not yet be
aware of the differences between machine-mode and supervisor-mode
interrupts as to why no `riscv-interrupt` calling convention is exposed
through rustc, and similarly for why `riscv-interrupt-u` makes no
appearance (as it would complicate future LLVM upgrades).
[clang-attr]: https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v
[full-frame-save]: 9281af2ecf/src/lib.rs (L440-L469)
[implemented by]: b7fb2a3fec/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp (L61-L67)
[callee-save]: 973f1fe7a8/llvm/lib/Target/RISCV/RISCVCallingConv.td (L30-L37)
[rfc]: https://github.com/rust-lang/rfcs/pull/3246
Map RPIT duplicated lifetimes back to fn captured lifetimes
Use the [`lifetime_mapping`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.OpaqueTy.html#structfield.lifetime_mapping) to map an RPIT's captured lifetimes back to the early- or late-bound lifetimes from its parent function. We may be going thru several layers of mapping, since opaques can be nested, so we introduce `TyCtxt::map_rpit_lifetime_to_fn_lifetime` to loop through several opaques worth of mapping, and handle turning it into a `ty::Region` as well.
We can then use this instead of the identity substs for RPITs in `check_opaque_meets_bounds` to address #114285.
We can then also use `map_rpit_lifetime_to_fn_lifetime` to properly install bidirectional-outlives predicates for both RPITs and RPITITs. This addresses #114601.
I based this on #114574, but I don't actually know how much of that PR we still need, so some code may be redundant now... 🤷
---
Fixes#114597Fixes#114579Fixes#114285
Also fixes#114601, since it turns out we had other bugs with RPITITs and their duplicated lifetime params 😅.
Supersedes #114574
r? `@oli-obk`
Store the laziness of type aliases in their `DefKind`
Previously, we would treat paths referring to type aliases as *lazy* type aliases if the current crate had lazy type aliases enabled independently of whether the crate which the alias was defined in had the feature enabled or not.
With this PR, the laziness of a type alias depends on the crate it is defined in. This generally makes more sense to me especially if / once lazy type aliases become the default in a new edition and we need to think about *edition interoperability*:
Consider the hypothetical case where the dependency crate has an older edition (and thus eager type aliases), it exports a type alias with bounds & a where-clause (which are void but technically valid), the dependent crate has the latest edition (and thus lazy type aliases) and it uses that type alias. Arguably, the bounds should *not* be checked since at any time, the dependency crate should be allowed to change the bounds at will with a *non*-major version bump & without negatively affecting downstream crates.
As for the reverse case (dependency: lazy type aliases, dependent: eager type aliases), I guess it rules out anything from slight confusion to mild annoyance from upstream crate authors that would be caused by the compiler ignoring the bounds of their type aliases in downstream crates with older editions.
---
This fixes#114468 since before, my assumption that the type alias associated with a given weak projection was lazy (and therefore had its variances computed) did not necessarily hold in cross-crate scenarios (which [I kinda had a hunch about](https://github.com/rust-lang/rust/pull/114253#discussion_r1278608099)) as outlined above. Now it does hold.
`@rustbot` label F-lazy_type_alias
r? `@oli-obk`
Add documentation to has_deref
Documentation of `has_deref` needed some polish to be more clear about where it should be used and what's it's purpose.
cc https://github.com/rust-lang/rust/issues/114401
r? `@RalfJung`
Convert builtin "global" late lints to run per module
The compiler currently has 4 non-incremental lints:
1. `clashing_extern_declarations`;
2. `missing_debug_implementations`;
3. ~`unnameable_test_items`;~ changed by https://github.com/rust-lang/rust/pull/114414
4. `missing_docs`.
Non-incremental lints get reexecuted for each compilation, which is slow. Moreover, those lints are allow-by-default, so run for nothing most of the time. This PR attempts to make them more incremental-friendly.
`clashing_extern_declarations` is moved to a standalone query.
`missing_debug_implementation` can use `non_blanket_impls_for_ty` instead of recomputing it.
`missing_docs` is harder as it needs to track if there is a `doc(hidden)` module surrounding. I hack around this using the lint level engine. That's easy to implement and allows to re-enable the lint for a re-exported module, while a more proper solution would reuse the same device as `unnameable_test_items`.
update overflow handling in the new trait solver
implements https://hackmd.io/QY0dfEOgSNWwU4oiGnVRLw?view. I want to clean up this doc and add it to the rustc-dev-guide, but I think this PR is ready for merge as is, even without the dev-guide entry.
r? `@compiler-errors`
Rework upcasting confirmation to support upcasting to fewer projections in target bounds
This PR implements a modified trait upcasting algorithm that is resilient to changes in the number of associated types in the bounds of the source and target trait objects.
It does this by equating each bound of the target trait ref individually against the bounds of the source trait ref, rather than doing them all together by constructing a new trait object.
#### The new way we do trait upcasting confirmation
1. Equate the target trait object's principal trait ref with one of the supertraits of the source trait object's principal.
fdcab310b2/compiler/rustc_trait_selection/src/traits/select/mod.rs (L2509-L2525)
2. Make sure that every auto trait in the *target* trait object is present in the source trait ref's bounds.
fdcab310b2/compiler/rustc_trait_selection/src/traits/select/mod.rs (L2559-L2562)
3. For each projection in the *target* trait object, make sure there is exactly one projection that equates with it in the source trait ref's bound. If there is more than one, bail with ambiguity.
fdcab310b2/compiler/rustc_trait_selection/src/traits/select/mod.rs (L2526-L2557)
* Since there may be more than one that applies, we probe first to check that there is exactly one, then we equate it outside of a probe once we know that it's unique.
4. Make sure the lifetime of the source trait object outlives the lifetime of the target.
<details>
<summary>Meanwhile, this is how we used to do upcasting:</summary>
1. For each supertrait of the source trait object, take that supertrait, append the source object's projection bounds, and the *target* trait object's auto trait bounds, and make this into a new object type:
d12c6e947c/compiler/rustc_trait_selection/src/traits/select/confirmation.rs (L915-L929)
2. Then equate it with the target trait object:
d12c6e947c/compiler/rustc_trait_selection/src/traits/select/confirmation.rs (L936)
This will be a type mismatch if the target trait object has fewer projection bounds, since we compare the bounds structurally in relate:
d12c6e947c/compiler/rustc_middle/src/ty/relate.rs (L696-L698)
</details>
Fixes#114035
Also fixes#114113, because I added a normalize call in the old solver.
r? types
resolve before canonicalization in new solver, ICE if unresolved
Fold the values with a resolver before canonicalization instead of making it happen within canonicalization.
This allows us to filter trivial region constraints from the external constraints.
r? ``@lcnr``
Perform OpaqueCast field projection on HIR, too.
fixes#105819
This is necessary for closure captures in 2021 edition, as they capture individual fields, not the full mentioned variables. So it may try to capture a field of an opaque (because the hidden type is known to be something with a field).
See https://github.com/rust-lang/rust/pull/99806 for when and why we added OpaqueCast to MIR.
Add `internal_features` lint
Implements https://github.com/rust-lang/compiler-team/issues/596
Also requires some more test blessing for codegen tests etc
`@jyn514` had the idea of just `allow`ing the lint by default in the test suite. I'm not sure whether this is a good idea, but it's definitely one worth considering. Additional input encouraged.
const validation: point at where we found a pointer but expected an integer
Instead of validation just printing "unable to turn pointer into bytes", make this a regular validation error that says where in the value the bad pointer was found. Also distinguish "expected integer, got pointer" from "expected pointer, got partial pointer or mix of pointers".
To avoid duplicating things too much I refactored the diagnostics for validity a bit, so that "got uninit, expected X" and "got pointer, expected X" can share the "X" part. Also all the errors emitted for validation are now grouped under `const_eval_validation` so that they are in a single group in the ftl file.
r? `@oli-obk`
It lints against features that are inteded to be internal to the
compiler and standard library. Implements MCP #596.
We allow `internal_features` in the standard library and compiler as those
use many features and this _is_ the standard library from the "internal to the compiler and
standard library" after all.
Marking some features as internal wasn't exactly the most scientific approach, I just marked some
mostly obvious features. While there is a categorization in the macro,
it's not very well upheld (should probably be fixed in another PR).
We always pass `-Ainternal_features` in the testsuite
About 400 UI tests and several other tests use internal features.
Instead of throwing the attribute on each one, just always allow them.
There's nothing wrong with testing internal features^^
Miri: fix error on dangling pointer inbounds offset
We used to claim that the pointer was "dereferenced", but that is just not true.
Can be reviewed commit-by-commit. The first commit is an unrelated rename that didn't seem worth splitting into its own PR.
r? `@oli-obk`
Don't check unnecessarily that impl trait is RPIT
We have this random `return_type_impl_trait` function to detect if a function returns an RPIT which is used in outlives suggestions, but removing it doesn't actually change any diagnostics. Let's just remove it.
Also, suppress a spurious outlives error from a ReError.
Fixes#114274
Operand types are now tracked explicitly, so there is no need to reserve ID 0
for the special always-zero counter.
As part of the renumbering, this change fixes an off-by-one error in the way
counters were counted by the `coverageinfo` query. As a result, functions
should now have exactly the number of counters they actually need, instead of
always having an extra counter that is never used.
Operand types are now tracked explicitly, so there is no need for expression
IDs to avoid counter IDs by descending from `u32::MAX`. Instead they can just
count up from 0, and can be used directly as indices when necessary.
Because the three kinds of operand are now distinguished explicitly, we no
longer need fiddly code to disambiguate counter IDs and expression IDs based on
the total number of counters/expressions in a function.
This does increase the size of operands from 4 bytes to 8 bytes, but that
shouldn't be a big deal since they are mostly stored inside boxed structures,
and the current coverage code is not particularly size-optimized anyway.
The actual motivation here is to prevent `rustfmt` from suddenly reformatting
these enum variants onto a single line, when they become slightly shorter in
the future.
But there's no harm in adding some helpful documentation at the same time.
Map RPITIT's opaque type bounds back from projections to opaques
An RPITIT in a program's AST is eventually translated into both a projection GAT and an opaque. The opaque is used for default trait methods, like:
```
trait Foo {
fn bar() -> impl Sized { 0i32 }
}
```
The item bounds for both the projection and opaque are identical, and both have a *projection* self ty. This is mostly okay, since we can normalize this projection within the default trait method body to the opaque, but it does two things:
1. it leads to bugs in places where we don't normalize item bounds, like `deduce_future_output_from_obligations`
2. it leads to extra match arms that are both suspicious looking and also easy to miss
This PR maps the opaque type bounds of the RPITIT's *opaque* back to the opaque's self type to avoid this quirk. Then we can fix the UI test for #108304 (1.) and also remove a bunch of match arms (2.).
Fixes#108304
r? `@spastorino`
Rollup of 7 pull requests
Successful merges:
- #114099 (privacy: no nominal visibility for assoc fns )
- #114128 (When flushing delayed span bugs, write to the ICE dump file even if it doesn't exist)
- #114138 (Adjust spans correctly for fn -> method suggestion)
- #114146 (Skip reporting item name when checking RPITIT GAT's associated type bounds hold)
- #114147 (Insert RPITITs that were shadowed by missing ADTs that resolve to [type error])
- #114155 (Replace a lazy `RefCell<Option<T>>` with `OnceCell<T>`)
- #114164 (Add regression test for `--cap-lints allow` and trait bounds warning)
r? `@ghost`
`@rustbot` modify labels: rollup
When `staged_api` is enabled, effective visibilities are computed earlier
and this can trigger an ICE in some cases.
In particular, if a impl of a trait method has a visibility then an error
will be reported for that, but when privacy invariants are being checked,
the effective visibility will still be greater than the nominal visbility
and that will trigger a `span_bug!`.
However, this invariant - that effective visibilites are limited to
nominal visibility - doesn't make sense for associated functions.
Signed-off-by: David Wood <david@davidtw.co>
new unstable option: -Zwrite-long-types-to-disk
This option guards the logic of writing long type names in files and instead using short forms in error messages in rustc_middle/ty/error behind a flag. The main motivation for this change is to disable this behaviour when running ui tests.
This logic can be triggered by running tests in a directory that has a long enough path, e.g. /my/very-long-path/where/rust-codebase/exists/
This means ui tests can fail depending on how long the path to their file is.
Some ui tests actually rely on this behaviour for their assertions, so for those we enable the flag manually.
Normalize the RHS of an `Unsize` goal in the new solver
`Unsize` goals are... tricky. Not only do they structurally match on their self type, but they're also structural on their other type parameter. I'm pretty certain that it is both incomplete and also just plain undesirable to not consider normalizing the RHS of an unsize goal. More practically, I'd like for this code to work:
```rust
trait A {}
trait B: A {}
impl A for usize {}
impl B for usize {}
trait Mirror {
type Assoc: ?Sized;
}
impl<T: ?Sized> Mirror for T {
type Assoc = T;
}
fn main() {
// usize: Unsize<dyn B>
let x = Box::new(1usize) as Box<<dyn B as Mirror>::Assoc>;
// dyn A: Unsize<dyn B>
let y = x as Box<<dyn A as Mirror>::Assoc>;
}
```
---
In order to achieve this, we add `EvalCtxt::normalize_non_self_ty` (naming modulo bikeshedding), which *must* be used for all non-self type arguments that are structurally matched in candidate assembly. Currently this is only necessary for `Unsize`'s argument, but I could see future traits requiring this (hopefully rarely) in the future. It uses `repeat_while_none` to limit infinite looping, and normalizes the self type until it is no longer an alias.
Also, we need to fix feature gate detection for `trait_upcasting` and `unsized_tuple_coercion` when HIR typeck has unnormalized types. We can do that by checking the `ImplSource` returned by selection, which necessitates adding a new impl source for tuple upcasting.
interpret: Unify projections for MPlaceTy, PlaceTy, OpTy
For ~forever, we didn't really have proper shared code for handling projections into those three types. This is mostly because `PlaceTy` projections require `&mut self`: they might have to `force_allocate` to be able to represent a project part-way into a local.
This PR finally fixes that, by enhancing `Place::Local` with an `offset` so that such an optimized place can point into a part of a place without having requiring an in-memory representation. If we later write to that place, we will still do `force_allocate` -- for now we don't have an optimized path in `write_immediate` that would avoid allocation for partial overwrites of immediately stored locals. But in `write_immediate` we have `&mut self` so at least this no longer pollutes all our type signatures.
(Ironically, I seem to distantly remember that many years ago, `Place::Local` *did* have an `offset`, and I removed it to simplify things. I guess I didn't realize why it was so useful... I am also not sure if this was actually used to achieve place projection on `&self` back then.)
The `offset` had type `Option<Size>`, where `None` represent "no projection was applied". This is needed because locals *can* be unsized (when they are arguments) but `Place::Local` cannot store metadata: if the offset is `None`, this refers to the entire local, so we can use the metadata of the local itself (which must be indirect); if a projection gets applied, since the local is indirect, it will turn into a `Place::Ptr`. (Note that even for indirect locals we can have `Place::Local`: when the local appears in MIR, we always start with `Place::Local`, and only check `frame.locals` later. We could eagerly normalize to `Place::Ptr` but I don't think that would actually simplify things much.)
Having done all that, we can finally properly abstract projections: we have a new `Projectable` trait that has the basic methods required for projecting, and then all projection methods are implemented for anything that implements that trait. We can even implement it for `ImmTy`! (Not that we need that, but it seems neat.) The visitor can be greatly simplified; it doesn't need its own trait any more but it can use the `Projectable` trait. We also don't need the separate `Mut` visitor any more; that was required only to reflect that projections on `PlaceTy` needed `&mut self`.
It is possible that there are some more `&mut self` that can now become `&self`... I guess we'll notice that over time.
r? `@oli-obk`
This is necessary for closure captures in 2021 edition, as they capture individual fields, not the full mentioned variables. So it may try to capture a field of an opaque (because the hidden type is known to be something with a field).
rustdoc: handle cross-crate RPITITs correctly
Filter out the internal associated types synthesized during the desugaring of RPITITs, they really shouldn't show up in the docs.
This also fixes#113929 since we're no longer invoking `is_impossible_associated_item` (renamed from `is_impossible_method`) which cannot handle them (leading to an ICE). I don't think it makes sense to try to make `is_impossible_associated_item` handle this exotic kind of associated type (CC original author `@compiler-errors).`
@ T-rustdoc reviewers, currently I'm throwing out ITIT assoc tys before cleaning assoc tys at each usage-site. I'm thinking about making `clean_middle_assoc_item` return an `Option<_>` instead and doing the check inside of it to prevent any call sites from forgetting the check for ITITs. Since I wasn't sure if you would like that approach, I didn't go through with it. Let me know what you think.
<details><summary>Explanation on why <code>is_impossible_associated_item(itit_assoc_ty)</code> leads to an ICE</summary>
Given the following code:
```rs
pub trait Trait { fn def<T>() -> impl Default {} }
impl Trait for () {}
```
The generated associated type looks something like (simplified):
```rs
type {opaque#0}<T>: Default = impl Default; // the name is actually `kw::Empty` but this is the `def_path_str` repr
```
The query `is_impossible_associated_item` goes through all predicates of the associated item – in this case `<T as Sized>` – to check if they contain any generic parameters from the (generic) associated type itself. For predicates that don't contain any *own* generics, it does further processing, part of which is instantiating the predicate with the generic arguments of the impl block (which is only correct if they truly don't contain any own generics since they wouldn't get instantiated this way leading to an ICE).
It checks if `parent_def_id(T) == assoc_ty_def_id` to get to know if `T` is owned by the assoc ty. Unfortunately this doesn't work for ITIT assoc tys. In this case, the parent of `T` is `Trait::def` (!) which is the associated function (I'm pretty sure this is very intentional) which is of course not equal to the assoc ty `Trait::{opaque#0}`.
</details>
`@rustbot` label A-cross-crate-reexports
This option guards the logic of writing long type names in files and
instead using short forms in error messages in rustc_middle/ty/error
behind a flag. The main motivation for this change is to disable this
behaviour when running ui tests.
This logic can be triggered by running tests in a directory that has a
long enough path, e.g. /my/very-long-path/where/rust-codebase/exists/
This means ui tests can fail depending on how long the path to their
file is.
Some ui tests actually rely on this behaviour for their assertions,
so for those we enable the flag manually.
Rollup of 4 pull requests
Successful merges:
- #113887 (new solver: add a separate cache for coherence)
- #113910 (Add FnPtr ty to SMIR)
- #113913 (error/E0691: include alignment in error message)
- #113914 (rustc_target: drop duplicate code)
r? `@ghost`
`@rustbot` modify labels: rollup
Still more complexity, but this allows computing exact `NaiveLayout`s
for null-optimized enums, and thus allows calls like
`transmute::<Option<&T>, &U>()` to work in generic contexts.
THis significantly complicates `NaiveLayout` logic, but is necessary to
ensure that bounds like `NonNull<T>: PointerLike` hold in generic
contexts.
Also implement exact layout computation for structs.
Querify unused trait check.
This code transitively loads information for all bodies, and from resolutions. As it does not return a value, it should be beneficial to have it as a query.
Don't translate compiler-internal bug messages
These are not very useful to be translated, as
* translators would get really weird and bad english versions to start out from,
* compiler devs have to do some work for what is supposed to be dead code and just a sanity check,
* the target audience is other compiler devs.
r? `@davidtwco`
Make it clearer that edition functions are `>=`, not `==`
r? `@Nilstrieb`
We could also perhaps derive `Ord` on `Edition` and use comparison operators.
Add the `no-builtins` attribute to functions when `no_builtins` is applied at the crate level.
**When `no_builtins` is applied at the crate level, we should add the `no-builtins` attribute to each function to ensure it takes effect in LTO.**
This is also the reason why no_builtins does not take effect in LTO as mentioned in #35540.
Now, `#![no_builtins]` should be similar to `-fno-builtin` in clang/gcc, see https://clang.godbolt.org/z/z4j6Wsod5.
Next, we should make `#![no_builtins]` participate in LTO again. That makes sense, as LTO also takes into consideration function-level instruction optimizations, such as the MachineOutliner. More importantly, when a user writes a large `#![no_builtins]` crate, they would like this crate to participate in LTO as well.
We should also add a function-level no_builtins attribute to allow users to have more control over it. This is similar to Clang's `__attribute__((no_builtin))` feature, see https://clang.godbolt.org/z/Wod6KK6eq. Before implementing this feature, maybe we should discuss whether to support more fine-grained control, such as `__attribute__((no_builtin("memcpy")))`.
Related discussions:
- #109821
- #35540
Next (a separate pull request?):
- [ ] Revert #35637
- [ ] Add a function-level `no_builtin` attribute?
Safe Transmute: Fix ICE (due to UnevaluatedConst)
This patch updates the code that looks at the `Assume` type when evaluating if transmutation is possible. An ICE was being triggered in the case that the `Assume` parameter contained an unevaluated const (in this test case, due to a function with missing parameter names).
Fixes#110892
This patch updates the code that looks at the `Assume` type when evaluating if
transmutation is possible. An ICE was being triggered in the case that the
`Assume` parameter contained an unevaluated const (in this test case, due to a
function with missing parameter names).
Fixes#110892
Use u64 for incr comp allocation offsets
Fixes https://github.com/rust-lang/rust/issues/76037
Fixes https://github.com/rust-lang/rust/issues/95780
Fixes https://github.com/rust-lang/rust/issues/111613
These issues are all reporting ICEs caused by using `u32` to store offsets to allocations in the incremental compilation cache. This PR aims to lift that limitation by changing the offset type in question to `u64`.
There are two perf runs in this PR. The first reports a regression, and the second does not. The changes are the same in both. I rebased the PR then did the second perf run because I noticed that the primary regression in it was very commonly seen in spurious regression reports.
I do not know what the perf run will report when this is merged. I would not be surprised to see regression or neutral, but the cachegrind diffs for the regression point at `try_mark_previous_green` which is a common source of inexplicable regressions and I don't think should be perturbed by this PR.
I'm not opposed to adding a regression test such as
```rust
fn main() {
println!("{}", [37; 1 << 30].len());
}
```
But that program takes 1 minute to compile and consumes 4.6 GB of memory then writes that much to disk. Is that a concerning amount of resource use for a test?
r? `@nnethercote`
Streamline size estimates (take 2)
This was merged in #113684 but then [something happened](https://github.com/rust-lang/rust/pull/113684#issuecomment-1636811985):
> There has been a bors issue that lead to the merge commit of this PR getting purged from master.
> You'll have to make a new PR to reapply it.
So this is exactly the same changes.
`@bors` r=wesleywiser
Add support for inherent projections in new solver
Not hard to support these, and it cuts out a really big chunk of failing UI tests with `--compare-mode=next-solver`
r? `@lcnr` (feel free to reassign, anyone can review this)
This means we call `MonoItem::size_estimate` (which involves a query)
less often: just once per mono item, and then once more per inline item
placement. After that we can reuse the stored value as necessary. This
means `CodegenUnit::compute_size_estimate` is cheaper.