Don't create references to uninitialized data in `List::from_arena`
Previously `result` and `arena_slice` were references pointing to uninitialized data, which is technically UB. They may have been fine because the pointed data is `Copy` and and they were only written to, but the semantics of this aren't clearly defined yet, and since we have a sound way to do the same thing I don't think we should keep the possibly-unsound way.
Make expansions stable for incr. comp.
This PR aims to make expansions stable for incr. comp. by using the same architecture as definitions:
- the interned identifier `ExpnId` contains a `CrateNum` and a crate-local id;
- bidirectional maps `ExpnHash <-> ExpnId` are setup;
- incr. comp. on-disk cache saves and reconstructs expansions using their `ExpnHash`.
I tried to use as many `LocalExpnId` as I could in the resolver code, but I may have missed a few opportunities.
All this will allow to use an `ExpnId` as a query key, and to force this query without recomputing caller queries. For instance, this will be used to implement #85999.
r? `@petrochenkov`
CTFE/Miri engine Pointer type overhaul
This fixes the long-standing problem that we are using `Scalar` as a type to represent pointers that might be integer values (since they point to a ZST). The main problem is that with int-to-ptr casts, there are multiple ways to represent the same pointer as a `Scalar` and it is unclear if "normalization" (i.e., the cast) already happened or not. This leads to ugly methods like `force_mplace_ptr` and `force_op_ptr`.
Another problem this solves is that in Miri, it would make a lot more sense to have the `Pointer::offset` field represent the full absolute address (instead of being relative to the `AllocId`). This means we can do ptr-to-int casts without access to any machine state, and it means that the overflow checks on pointer arithmetic are (finally!) accurate.
To solve this, the `Pointer` type is made entirely parametric over the provenance, so that we can use `Pointer<AllocId>` inside `Scalar` but use `Pointer<Option<AllocId>>` when accessing memory (where `None` represents the case that we could not figure out an `AllocId`; in that case the `offset` is an absolute address). Moreover, the `Provenance` trait determines if a pointer with a given provenance can be cast to an integer by simply dropping the provenance.
I hope this can be read commit-by-commit, but the first commit does the bulk of the work. It introduces some FIXMEs that are resolved later.
Fixes https://github.com/rust-lang/miri/issues/841
Miri PR: https://github.com/rust-lang/miri/pull/1851
r? `@oli-obk`
TAIT: Infer all inference variables in opaque type substitutions via InferCx
The previous algorithm was correct for the example given in its
documentation, but when the TAIT was declared as a free item
instead of an associated item, the generic parameters were the
wrong ones.
cc `@spastorino`
r? `@nikomatsakis`
The previous algorithm was correct for the example given in its
documentation, but when the TAIT was declared as a free item
instead of an associated item, the generic parameters were the
wrong ones.
Replace associated item bound vars with placeholders when projecting
Fixes#76407Fixes#76826
Similar, but more limited, to #85499. This allows us to handle things like `for<'a> <T as Trait>::Assoc<'a>` but not `for<'a> <T as Trait<'a>>::Assoc`, unblocking GATs.
r? `@nikomatsakis`
This resolves all the problems we had around "normalizing" the representation of a Scalar in case it carries a Pointer value: we can just use Pointer if we want to have a value taht we are sure is already normalized.
Support forwarding caller location through trait object method call
Since PR #69251, the `#[track_caller]` attribute has been supported on
traits. However, it only has an effect on direct (monomorphized) method
calls. Calling a `#[track_caller]` method on a trait object will *not*
propagate caller location information - instead, `Location::caller()` will
return the location of the method definition.
This PR forwards caller location information when `#[track_caller]` is
present on the method definition in the trait. This is possible because
`#[track_caller]` in this position is 'inherited' by any impls of that
trait, so all implementations will have the same ABI.
This PR does *not* change the behavior in the case where
`#[track_caller]` is present only on the impl of a trait.
While all implementations of the method might have an explicit
`#[track_caller]`, we cannot know this at codegen time, since other
crates may have impls of the trait. Therefore, we keep the current
behavior of not forwarding the caller location, ensuring that all
implementations of the trait will have the correct ABI.
See the modified test for examples of how this works
- Closures in external crates may get compiled in because of
monomorphization. We should store names of captured variables
in `optimized_mir`, so that they are written into the metadata
file and we can use them to generate debuginfo.
- If there are breakpoints inside closures, the names of captured
variables stored in `optimized_mir` can be used to print them.
Now the name is more precise when disjoint fields are captured.
Previously, debuggers print closures as something like
```
y::main::closure-0 (0x7fffffffdd34)
```
The pointer actually references to an upvar. It is not
very obvious, especially for beginners.
It's because upvars don't have names before, as they
are packed into a tuple. This commit names the upvars,
so we can expect to see something like
```
y::main::closure-0 {_captured_ref__b: 0x[...]}
```
Query-ify global limit attribute handling
Currently, we read various 'global limits' from inner attributes the crate root (`recursion_limit`, `move_size_limit`, `type_length_limit`, `const_eval_limit`). These limits are then stored in `Sessions`, allowing them to be access from a `TyCtxt` without registering a dependency on the crate root attributes.
This PR moves the calculation of these global limits behind queries, so that we properly track dependencies on crate root attributes. During the setup of macro expansion (before we've created a `TyCtxt`), we need to access the recursion limit, which is now done by directly calling into the code shared by the normal query implementations.
Hack: Ignore inference variables in certain queries
Fixes#84841Fixes#86753
Some queries are not built to accept types with inference variables, which can lead to ICEs. These queries probably ought to be converted to canonical form, but as a quick workaround, we can return conservative results in the case that inference variables are found.
We should file a follow-up issue (and update the FIXMEs...) to do the proper refactoring.
cc `@arora-aman`
r? `@oli-obk`
Support allocation failures when interpreting MIR
This closes#79601 by handling the case where memory allocation fails during MIR interpretation, and translates that failure into an `InterpError`. The error message is "tried to allocate more memory than available to compiler" to make it clear that the memory shortage is happening at compile-time by the compiler itself, and that it is not a runtime issue.
Now that memory allocation can fail, it would be neat if Miri could simulate low-memory devices to make it easy to see how much memory a Rust program needs.
Note that this breaks Miri because it assumes that allocation can never fail.