rustc_codegen_ssa: only "spill" SSA-like values to the stack for debuginfo.
This is an implementation of the idea described in https://github.com/rust-lang/rust/issues/68817#issuecomment-583719182.
In short, instead of debuginfo forcing otherwise-SSA-like MIR locals into `alloca`s, and requiring a `load` for each use (or two, for scalar pairs), the `alloca` is now *only* used for attaching debuginfo with `llvm.dbg.declare`: the `OperandRef` is stored to the `alloca`, but *never loaded* from it.
Outside of `debug_introduce_local`, nothing cares about the debuginfo-only `alloca`, and instead works with `OperandRef` the same as MIR locals without debuginfo before this PR.
This should have some of the benefits of `llvm.dbg.value`, while working today.
cc @nagisa @nikomatsakis
change an instance of span_bug() to struct_span_err() to avoid ICE
After #67148, the `span_bug()` in `parse_ty_tuple_or_parens()` is reachable because `parse_paren_comma_seq()` can return an `Ok()` even in cases where it encounters an error.
This pull request prevents an ICE in such cases by replacing the `span_bug()` with `struct_span_error()`.
Fixes#68890.
Add long error code explanation message for E0637
Reference issue [#61137](https://github.com/rust-lang/rust/issues/61137)
To incorporate a long error description for E0637, I have made the necessary modification to error_codes.rs and added error_codes/E0637.md, and blessed the relevant .stderror files. ~~, however when I build rustc stage 1, I am unable to make `$ rustc --explain E0637` work even though rustc appears to be able to call up the long error explanations for other errors. I wanted to guarantee this would work before moving on the blessing the various ui tests that have been affected. @GuillaumeGomez Do you know the most likely reason(s) why this would be the case?~~
Update: `$ rustc --explain E0637` works now.
Remove problematic specialization from RangeInclusive
Fixes#67194 using the approach [outlined by Mark-Simulacrum](https://github.com/rust-lang/rust/issues/67194#issuecomment-581669549).
> I believe the property we want is that if `PartialEq(&self, &other) == true`, then `self.next() == other.next()`. It is true that this is satisfied by removing the specialization and always doing `is_empty.unwrap_or_default()`; the "wrong" behavior there arises from calling `next()` having an effect on initially empty ranges, as we should be in `is_empty = true` but are not (yet) there. It might be possible to detect that the current state is always empty (i.e., `start > end`) and then not fill in the empty slot. I think this might solve the problem without regressing tests; however, this could have performance implications.
> That approach essentially states that we only use the `is_empty` slot for cases where `start <= end`. That means that `Idx: !Step` and `start > end` would both behave the same, and correctly -- we do not need the boolean if we're not ever going to emit any values from the iterator.
This is implemented here by replacing the `is_empty: Option<bool>` slot with an `exhausted: bool` slot. This flag is
- `false` upon construction,
- `false` when iteration has not yielded an element -- importantly, this means it is always `false` for an iterator empty by construction,
- `false` when iteration has yielded an element and the iterator is not exhausted, and
- only `true` when iteration has been used to exhaust the iterator.
For completeness, this also adds a note to the `Debug` representation to note when the range is exhausted.
Rollup of 6 pull requests
Successful merges:
- #68694 (Reduce the number of `RefCell`s in `InferCtxt`.)
- #68966 (Improve performance of coherence checks)
- #68976 (Make `num::NonZeroX::new` an unstable `const fn`)
- #68992 (Correctly parse `mut a @ b`)
- #69005 (Small graphviz improvements for the new dataflow framework)
- #69006 (parser: Keep current and previous tokens precisely)
Failed merges:
r? @ghost
parser: Keep current and previous tokens precisely
...including their unnormalized forms.
Add more documentation for them.
Hopefully, this will help to eliminate footguns like https://github.com/rust-lang/rust/pull/68728#discussion_r373787486.
I'll try to address the FIXMEs in separate PRs during the next week.
r? @Centril
Make `num::NonZeroX::new` an unstable `const fn`
cc #53718
These require `#[feature(const_if_match)]`, meaning they must remain unstable for the time being.
Fixes#67844
Previously, opaque types would only get parent generics if they
a return-position-impl-trait (e.g. `fn foo<A>() -> impl MyTrait<A>`).
However, it's possible for opaque types to be nested inside one another:
```rust
trait WithAssoc { type AssocType; }
trait WithParam<A> {}
type Return<A> = impl WithAssoc<AssocType = impl WithParam<A>>;
```
When this occurs, we need to ensure that the nested opaque types
properly inherit generic parameters from their parent opaque type.
This commit fixes the `generics_of` query to take the parent item
into account when determining the generics for an opaque type.
This has negligible perf impact, but it does improve the code a bit.
* Only query the specialization graph of any trait once instead of once per
impl
* Loop over impls only once, precomputing impl DefId and TraitRef
Improve reporting errors and suggestions for trait bounds
Fix#66802
- When printing errors for unsized function parameter, properly point at the parameter instead of function's body.
- Improve `consider further restricting this bound` (and related) messages by separating human-oriented hints from the machine-oriented ones.
When suggesting associated fn with type parameters, include in the structured suggestion
Address #50734.
```
error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `baz`
--> file.rs:14:1
|
14 | impl TraitA<()> for S {
| ^^^^^^^^^^^^^^^^^^^^^ missing `foo`, `bar`, `baz` in implementation
|
= help: implement the missing item: `fn foo<T>(_: T) -> Self where T: TraitB, TraitB::Item = A { unimplemented!() }`
= help: implement the missing item: `fn bar<T>(_: T) -> Self { unimplemented!() }`
= help: implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: std::marker::Copy { unimplemented!() }`
```
It doesn't work well for associated types with `ty::Predicate::Projection`s as we need to resugar `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`.
Initial implementation of `#![feature(move_ref_pattern)]`
Following up on #45600, under the gate `#![feature(move_ref_pattern)]`, `(ref x, mut y)` is allowed subject to restrictions necessary for soundness. The match checking implementation and tests for `#![feature(bindings_after_at)]` is also adjusted as necessary.
Closes#45600.
Tracking issue: #68354.
r? @matthewjasper
rustc_codegen_ssa: don't treat inlined variables as debuginfo arguments.
Fixes#67586 by limiting `ArgumentVariable` special-casing to `VarDebugInfo` entries that are in `OUTERMOST_SOURCE_SCOPE`, i.e. the function's own argument scope.
That excludes `VarDebugInfo` from inlined callees, which can also point to the caller's argument locals.
This is a snippet from the optimized MIR (including inlining) of the testcase:
```rust
fn foo(_1: usize) -> usize {
debug bar => _1; // in scope 0 at ./example.rs:2:12: 2:15
let mut _0: usize; // return place in scope 0 at ./example.rs:2:27: 2:32
scope 1 {
debug x => _1; // in scope 1 at /rustc/9ed29b6ff6aa2e048b09c27af8f62ee3040bdb37/src/libcore/convert/mod.rs:106:26: 106:27
}
```
`scope 1` is from inlining the `identity` call, and `debug x => _1;` comes from the body of `core::convert::identity`, so they are now ignored for the purposes of determining the `ArgumentVariable` debuginfo associated to `_1`.
rustc_target: treat enum variants like union members, in call ABIs.
Fixes#68190, by handling non-C-like `enum`s as-if they were an `union` of `struct`s, in call ABIs.
Tests were provided by @sw17ch, from theirs and @bitwalker's original examples.
cc @nagisa @rkruppe