Consider unfulfilled obligations in binop errors
When encountering a binop where the types would have been accepted, if
all the predicates had been fulfilled, include information about the
predicates and suggest appropriate `#[derive]`s if possible.
Fix#84515.
When encountering a binop where the types would have been accepted, if
all the predicates had been fulfilled, include information about the
predicates and suggest appropriate `#[derive]`s if possible.
Point at trait(s) that needs to be `impl`emented.
Fix bug with query modifier parsing
The previous macro_rules! parsers failed when an additional modifier was added
with ambiguity errors. The error is pretty unclear as to what exactly the cause
here is, but this change simplifies the argument parsing code such that the
error is avoided.
Extracted from other work, and somewhat duplicates 0358edeb5 from #85830, but
this approach seems a little simpler to me. Not technically currently necessary but seems
like a good cleanup.
Consistently use 'supertrait'.
A subset of places referred to 'super-trait', so this changes them
to all use 'supertrait'. This matches 'supertype' and some other
usages. An exception is 'auto-trait' which is consistently used
in that manner.
Remove some feature gates
The first commit removes various feature gates that are unused. The second commit replaces some `Fn` implementations with `Iterator` implementations, which is much cleaner IMO. The third commit replaces an unboxed_closures feature gate with min_specialization. For some reason the unboxed_closures feature gate suppresses the min_specialization feature gate from triggering on an `TrustedStep` impl. The last comment just turns a regular comment into a doc comment as drive by cleanup. I can move it to a separate PR if preferred.
The previous macro_rules! parsers failed when an additional modifier was added
with ambiguity errors. The error is pretty unclear as to what exactly the cause
here is, but this change simplifies the argument parsing code such that the
error is avoided.
Avoid nondeterminism in trimmed_def_paths
Previously this query depended on the global interning order of Symbols, which
meant that irrelevant changes could influence the query and cause
recompilations. This commit ensures that the return set is stable and will not
be affected by the global order by deterministically (in lexicographic order)
choosing a name to use if there are multiple names for a single DefId.
This should fix the cause of the [regressions] in #83343.
[regressions]: https://perf.rust-lang.org/compare.html?start=9620f3a84b079decfdc2e557be007580b097fe43&end=addb4da686a97da46159f0123cb6cdc2ce3d7fdb
A subset of places referred to 'super-trait', so this changes them
to all use 'supertrait'. This matches 'supertype' and some other
usages. An exception is 'auto-trait' which is consistently used
in that manner.
Rollup of 7 pull requests
Successful merges:
- #85223 (rustdoc: Clarified the attribute which prompts the warning)
- #88847 (platform-support.md: correct ARMv7+MUSL platform triple notes)
- #88963 (Coerce const FnDefs to implement const Fn traits )
- #89376 (Fix use after drop in self-profile with llvm events)
- #89422 (Replace whitespaces in doctests' name with dashes)
- #89440 (Clarify a sentence in the documentation of Vec (#84488))
- #89441 (Normalize after substituting via `field.ty()`)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Normalize after substituting via `field.ty()`
Back in https://github.com/rust-lang/rust/issues/72476 I hadn't understood where the problem was coming from, and only worked around the issue. What happens is that calling `field.ty()` on a field of a generic struct substitutes the appropriate generics but doesn't normalize the resulting type.
As a consumer of types I'm surprised that one would substitute without normalizing, feels like a footgun, so I added a comment.
Fixes https://github.com/rust-lang/rust/issues/89393.
Coerce const FnDefs to implement const Fn traits
You can now pass a FnDef to a function expecting `F` where `F: ~const FnTrait`.
r? ``@oli-obk``
``@rustbot`` label T-compiler F-const_trait_impl
Rework HIR API to make invocations of the hir_crate query harder.
`hir_crate` forces the recomputation of queries that depend on it.
This PR aims at avoiding useless invocations of `hir_crate` by making dependent code go through `tcx.hir()`.
Added -Z randomize-layout flag
An implementation of #77316, it currently randomly shuffles the fields of `repr(rust)` types based on their `DefPathHash`
r? ``@eddyb``
Previously this query depended on the global interning order of Symbols, which
meant that irrelevant changes could influence the query and cause
recompilations. This commit ensures that the return set is stable and will not
be affected by the global order by deterministically (in lexicographic order)
choosing a name to use if there are multiple names for a single DefId.
This PR has several interconnected pieces:
1. In some of the NLL region error code, we now pass
around an `ObligationCause`, instead of just a plain `Span`.
This gets forwarded into `fulfill_cx.register_predicate_obligation`
during error reporting.
2. The general InferCtxt error reporting code is extended to
handle `ObligationCauseCode::BindingObligation`
3. A new enum variant `ConstraintCategory::Predicate` is added.
We try to avoid using this as the 'best blame constraint' - instead,
we use it to enhance the `ObligationCause` of the `BlameConstraint`
that we do end up choosing.
As a result, several NLL error messages now contain the same
"the lifetime requirement is introduced here" message as non-NLL
errors.
Having an `ObligationCause` available will likely prove useful
for future improvements to NLL error messages.
Introduce `Rvalue::ShallowInitBox`
Polished version of #88700.
Implements MCP rust-lang/compiler-team#460, and should allow #43596 to go forward.
In short, creating an empty box is split from a nullary-op `NullOp::Box` into two steps, first a call to `exchange_malloc`, then a `Rvalue::ShallowInitBox` which transmutes `*mut u8` to a shallow-initialized `Box<T>`. This allows the `exchange_malloc` call to unwind. Details can be found in the MCP.
`NullOp::Box` is not yet removed, purely to make reverting easier in case anything goes wrong as the result of this PR. If revert is needed a reversion of "Use Rvalue::ShallowInitBox for box expression" commit followed by a test bless should be sufficient.
Experiments in #88700 showed a very slight compile-time perf regression due to (supposedly) slightly more time spent in LLVM. We could omit unwind edge generation (in non-`oom=panic` case) in box expression MIR construction to restore perf; but I don't think it's necessary since runtime perf isn't affected and perf difference is rather small.
Be explicit about using Binder::dummy
This is somewhat of a late followup to the binder refactor PR. It removes `ToPredicate` and `ToPolyTraitImpls` that hide the use of `Binder::dummy`. While this does make code a bit more verbose, it allows us be more careful about where we create binders.
Another alternative here might be to add a new trait `ToBinder` or something with a `dummy()` fn. Which could still allow grepping but allows doing something like `trait_ref.dummy()` (but I also wonder if longer-term, it would be better to be even more explicit with a `bind_with_vars(ty::List::empty())` *but* that's not clear yet.
r? ``@nikomatsakis``
Revise never type fallback algorithm
This is a rebase of https://github.com/rust-lang/rust/pull/84573, but dropping the stabilization of never type (and the accompanying large test diff).
Each commit builds & has tests updated alongside it, and could be reviewed in a more or less standalone fashion. But it may make more sense to review the PR as a whole, I'm not sure. It should be noted that tests being updated isn't really a good indicator of final behavior -- never_type_fallback is not enabled by default in this PR, so we can't really see the full effects of the commits here.
This combines the work by Niko, which is [documented in this gist](https://gist.github.com/nikomatsakis/7a07b265dc12f5c3b3bd0422018fa660), with some additional rules largely derived to target specific known patterns that regress with the algorithm solely derived by Niko. We build these from an intuition that:
* In general, fallback to `()` is *sound* in all cases
* But, in general, we *prefer* fallback to `!` as it accepts more code, particularly that written to intentionally use `!` (e.g., Result's with a Infallible/! variant).
When evaluating Niko's proposed algorithm, we find that there are certain cases where fallback to `!` leads to compilation failures in real-world code, and fallback to `()` fixes those errors. In order to allow for stabilization, we need to fix a good portion of these patterns.
The final rule set this PR proposes is that, by default, we fallback from `?T` to `!`, with the following exceptions:
1. `?T: Foo` and `Bar::Baz = ?T` and `(): Foo`, then fallback to `()`
2. Per [Niko's algorithm](https://gist.github.com/nikomatsakis/7a07b265dc12f5c3b3bd0422018fa660#proposal-fallback-chooses-between--and--based-on-the-coercion-graph), the "live" `?T` also fallback to `()`.
The first rule is necessary to address a fairly common pattern which boils down to something like the snippet below. Without rule 1, we do not see the closure's return type as needing a () fallback, which leads to compilation failure.
```rust
#![feature(never_type_fallback)]
trait Bar { }
impl Bar for () { }
impl Bar for u32 { }
fn foo<R: Bar>(_: impl Fn() -> R) {}
fn main() {
foo(|| panic!());
}
```
r? `@jackh726`
fix non_blanket_impls iteration order
We sometimes iterate over all `non_blanket_impls`, not sure if this is observable outside
of error messages (i.e. as incremental bugs). This should fix the underlying issue of #86986.
second attempt of #88718
r? `@nikomatsakis`