Delegation: fix ICE on wrong `Self` instantiation
fixes https://github.com/rust-lang/rust/issues/119921
fixes https://github.com/rust-lang/rust/issues/119919
There is no way to instantiate `Self` param for caller in delegation item if
1. callee is a trait method && callee contains `Self` param
2. delegation item isn't an associative item
In general, we can consider `Self` param as independent type param in these cases:
```rust
trait Trait {
fn foo(_: Option<&Self>) {...}
}
reuse Trait::foo;
// will be desugared to:
fn foo<T: Trait>(x: Option<&T>) { Trait::foo(x) }
```
But this requires early bound parameters support. For now, I suggest banning such cases to avoid ICE's.
r? ``@petrochenkov``
CFI: Fix drop and drop_in_place
Fix drop and drop_in_place by transforming self of drop and drop_in_place methods into a Drop trait objects.
This was split off from https://github.com/rust-lang/rust/pull/116404.
cc `@compiler-errors` `@workingjubilee`
CFI: Enable KCFI testing of run-pass tests
This enables KCFI-based testing for all the CFI run-pass tests in the suite today. We can add the test header on top of in-flight CFI tests once they land. This is becoming more important as we get closer to leveraging CFI's multiple type attachment feature, as that is where the implementations will have a divergence.
It also enables KCFI as a sanitizer for x86_64 and aarch64 Linux to make this possible. The sanitizer should likely be available for all aarch64, x86_64, and riscv targets, but that isn't critical for initial testing.
Soft-destabilize `RustcEncodable` & `RustcDecodable`, remove from prelude in next edition
cc rust-lang/libs-team#272
Any use of `RustcEncodable` and `RustcDecodable` now triggers a deny-by-default lint. The derives have been removed from the 2024 prelude. I specifically chose **not** to document this in the module-level documentation, as the presence in existing preludes is not documented (which I presume is intentional).
This does not implement the proposed change for `rustfix`, which I will be looking into shortly.
With regard to the items in the preludes being stable, this should not be an issue because #15702 has been resolved.
r? libs-api
Rollup of 9 pull requests
Successful merges:
- #108675 (Document `adt_const_params` feature in Unstable Book)
- #122120 (Suggest associated type bounds on problematic associated equality bounds)
- #122589 (Fix diagnostics for async block cloning)
- #122835 (Require `DerefMut` and `DerefPure` on `deref!()` patterns when appropriate)
- #123049 (In `ConstructCoroutineInClosureShim`, pass receiver by mut ref, not mut pointer)
- #123055 (enable cargo miri test doctests)
- #123057 (unix fs: Make hurd using explicit new rather than From)
- #123087 (Change `f16` and `f128` clippy stubs to be nonpanicking)
- #123103 (Rename `Inherited` -> `TypeckRootCtxt`)
r? `@ghost`
`@rustbot` modify labels: rollup
Suggest associated type bounds on problematic associated equality bounds
Fixes#105056. TL;DR: Suggest `Trait<Ty: Bound>` on `Trait<Ty = Bound>` in Rust >=2021.
~~Blocked on #122055 (stabilization of `associated_type_bounds`), I'd say.~~ (merged)
Delegation: fix ICE on wrong `self` resolution
fixes https://github.com/rust-lang/rust/issues/122874
Delegation item should be wrapped in a `rib` to behave like a regular function during name resolution.
r? `@petrochenkov`
CFI: (actually) check that methods are object-safe before projecting their receivers to `dyn Trait` in CFI
`trait_object_ty` assumed that associated types would be fully determined by the trait. This is *almost* true - const parameters and type parameters are no longer allowed, but lifetime parameters are. Since we erase all lifetime parameters anyways, instantiate it with as many erased regions as it needs.
Fixes: #123053
r? `@compiler-errors`
Avoid some unnecessary query invocations.
Specifically this inlines `const_eval_poly` and avoids computing the generic params, the param env, normalizing the param env and erasing lifetimes on everything.
should fix the perf regression from https://github.com/rust-lang/rust/pull/121087
This enables KCFI-based testing for all the CFI run-pass tests in the
suite today. We can add the test header on top of in-flight CFI tests
once they land.
It also enables KCFI as a sanitizer for x86_64 and aarch64 Linux to make
this possible. The sanitizer should likely be available for all aarch64,
x86_64, and riscv targets, but that isn't critical for initial testing.
`trait_object_ty` assumed that associated types would be fully
determined by the trait. This is *almost* true - const parameters and
type parameters are no longer allowed, but lifetime parameters are.
Since we erase all lifetime parameters anyways, instantiate it with as
many erased regions as it needs.
Fixes: #123053
In `pretty_print_type()`, print `async fn` futures' paths instead of spans.
This makes `-Zprint-type-sizes`'s output easier to read, because the name of an `async fn` is more immediately recognizable than its span. This change will also synergize with my other `-Zprint-type-sizes` PR #122922 which prints the type of child futures being awaited.
I also deleted the comment "FIXME(eddyb) should use `def_span`." because it appears to have already been fixed by commit 67727aa7c3.
Validate that we're only matching on unit struct for path pattern
Resolution doesn't validate that we only really take `CtorKind::Unit` in path patterns, since all it sees is `Res::SelfCtor(def_id)`. Check this instead during pattern typeck.
r? petrochenkov
Fixes#122809
Delegation: fix ICE on `bound_vars` divergence
Fixes https://github.com/rust-lang/rust/issues/122550.
Bug was caused by divergence between lowered type and corresponding `bound_vars` in `late_bound_vars_map`. In this patch `bound_vars` calculation for delegation item is moved from `lower_fn_ty` to `resolve_bound_vars` query.
r? `@petrochenkov`
Don't emit an error about failing to produce a file with a specific name if user never gave an explicit name
Fixes#122509
You can ask `rustc` to produce some intermediate results with `--emit foo`, this operation comes in two flavors: `--emit asm` and `--emit asm=foo.s`. First one produces one or more `.s` files without any name guarantees, second one renames it into `foo.s`. Second version only works when compiler produces a single file - for asm files this means using a single compilation unit for example.
In case compilation produced more than a single file `rustc` runs following check to emit some warnings:
```rust
if crate_output.outputs.contains_key(&output_type) {
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
// no good solution for this case, so warn the user.
sess.dcx().emit_warn(errors::IgnoringEmitPath { extension });
} else if crate_output.single_output_file.is_some() {
// 3) Multiple codegen units, with `-o some_name`. We have
// no good solution for this case, so warn the user.
sess.dcx().emit_warn(errors::IgnoringOutput { extension });
} else {
// 4) Multiple codegen units, but no explicit name. We
// just leave the `foo.0.x` files in place.
// (We don't have to do any work in this case.)
}
```
Comment in the final `else` branch implies that if user didn't ask for a specific name - there's no need to emit warnings. However because of the internal representation of `crate_output.outputs` - this doesn't work as expected: if user asked to produce an asm file without giving it an implicit name it will contain `Some(None)`.
To fix the problem new code actually checks if user gave an explicit name. I think this was an original intentional behavior, at least comments imply that.
This makes `-Zprint-type-sizes`'s output easier to read, because the
name of an `async fn` is more immediately recognizable than its span.
I also deleted the comment "FIXME(eddyb) should use `def_span`." because
it appears to have already been fixed by commit 67727aa7c3.
CFI: Support complex receivers
Right now, we only support rewriting `&self` and `&mut self` into `&dyn MyTrait` and `&mut dyn MyTrait`. This expands it to handle the full gamut of receivers by calculating the receiver based on *substitution* rather than based on a rewrite. This means that, for example, `Arc<Self>` will become `Arc<dyn MyTrait>` appropriately with this change.
This approach also allows us to support associated type constraints as well, so we will correctly rewrite `&self` into `&dyn MyTrait<T=i32>`, for example.
r? ```@workingjubilee```
CFI: Handle dyn with no principal
In user-facing Rust, `dyn` always has at least one predicate following it. Unfortunately, because we filter out marker traits from receivers at callsites and `dyn Sync` is, for example, legal, this results in us having `dyn` types with no predicates on occasion in our alias set encoding. This patch handles cases where there are no predicates in a `dyn` type which are relevant to its alias set.
Fixes#122998
r? workingjubilee
Replace `mir_built` query with a hook and use mir_const everywhere instead
A small perf improvement due to less dep graph handling.
Mostly just a cleanup to get rid of one of our many mir queries
Previously, we only rewrote `&self` and `&mut self` receivers. By
instantiating the method from the trait definition, we can make this
work work with arbitrary legal receivers instead.
In user-facing Rust, `dyn` always has at least one predicate following
it. Unfortunately, because we filter out marker traits from receivers at
callsites and `dyn Sync` is, for example, legal, this results in us
having `dyn` types with no predicates on occasion in our alias set
encoding. This patch handles cases where there are no predicates in a
`dyn` type which are relevant to its alias set.
Fixes#122998
panic-in-panic-hook: formatting a message that's just a string is risk-free
This slightly improves the output in the 'panic while processing panic' case if the panic message does not involve any formatting. Follow-up to https://github.com/rust-lang/rust/pull/122930.
r? ``@Amanieu``
Add a regression test for #117310Closes#117310
It seems to have been fixed in `rustc 1.79.0-nightly (1388d7a06 2024-03-20)` or before, so just adding a regression test for it.
Fixed the `private-dependency` bug
Fixed the private-dependency bug: If the directly dependent crate is loaded last and is not configured with `--extern`, it may be incorrectly set to `private-dependency`
Fixes#122756
Encode implied predicates for traits
In #112629, we decided to make associated type bounds in the "supertrait" AST position *implied* even though they're not supertraits themselves.
This means that the `super_predicates` and `implied_predicates` queries now differ for regular traits. The assumption that they didn't differ was hard-coded in #107614, so in cross-crate positions this means that we forget the implied predicates from associated type bounds.
This isn't unsound, just kind of annoying. This should be backported since associated type bounds are slated to stabilize for 1.78 -- either that, or associated type bounds can be reverted on beta and re-shipped in 1.79 with this patch.
Fixes#122859
CFI: Strip auto traits off Virtual calls
We already use `Instance` at declaration sites when available to glean additional information about possible abstractions of the type in use. This does the same when possible at callsites as well.
The primary purpose of this change is to allow CFI to alter how it generates type information for indirect calls through `Virtual` instances.
This is needed for the "separate machinery" version of my approach to the vtable issues (#122573), because we need to respond differently to a `Virtual` call to the same type as a non-virtual call, specifically [stripping auto traits off the receiver's `Self`](54b15b0c36) because there isn't a separate vtable for `Foo` vs `Foo + Send`.
This would also make a more general underlying mechanism that could be used by rcvalle's [proposed drop detection / encoding](edcd1e20a1) if we end up using his approach, as we could condition out on the `def_id` in the CFI code rather than requiring the generating code to explicitly note whether it was calling drop.
CFI: Support self_cell-like recursion
Current `transform_ty` attempts to avoid cycles when normalizing `#[repr(transparent)]` types to their interior, but runs afoul of this pattern used in `self_cell`:
```
struct X<T> {
x: u8,
p: PhantomData<T>,
}
#[repr(transparent)]
struct Y(X<Y>);
```
When attempting to normalize Y, it will still cycle indefinitely. By using a types-visited list, this will instead get expanded exactly one layer deep to X<Y>, and then stop, not attempting to normalize `Y` any further.
This PR was split off from #121962 as part of fixing the larger vtable compatibility issues.
r? ``````@workingjubilee``````
Mention Register Size in `#[warn(asm_sub_register)]`
Fixes#121593
Displays the register size information obtained from `suggest_modifier()` and `default_modifier()`.
Add test in higher ranked subtype
I'm a beginner in this repository, and there are some things I'm not sure about:
- Is it okay that there is a warning:
```
rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit) }
```
- Is it okay that there are two duplicate errors in the same line?
- Did I put the test in the right place?
Any suggestions would be appreciated.
Fixes#121649
Handle str literals written with `'` lexed as lifetime
Given `'hello world'` and `'1 str', provide a structured suggestion for a valid string literal:
```
error[E0762]: unterminated character literal
--> $DIR/lex-bad-str-literal-as-char-3.rs:2:26
|
LL | println!('hello world');
| ^^^^
|
help: if you meant to write a `str` literal, use double quotes
|
LL | println!("hello world");
| ~ ~
```
```
error[E0762]: unterminated character literal
--> $DIR/lex-bad-str-literal-as-char-1.rs:2:20
|
LL | println!('1 + 1');
| ^^^^
|
help: if you meant to write a `str` literal, use double quotes
|
LL | println!("1 + 1");
| ~ ~
```
Fix#119685.
Additional trait bounds beyond the principal trait and its implications
are not possible in the vtable. This means that if a receiver is
`&dyn Foo + Send`, the function will only be expecting `&dyn Foo`.
This strips those auto traits off before CFI encoding.
Rollup of 11 pull requests
Successful merges:
- #120577 (Stabilize slice_split_at_unchecked)
- #122698 (Cancel `cargo update` job if there's no updates)
- #122780 (Rename `hir::Local` into `hir::LetStmt`)
- #122915 (Delay a bug if no RPITITs were found)
- #122916 (docs(sync): normalize dot in fn summaries)
- #122921 (Enable more mir-opt tests in debug builds)
- #122922 (-Zprint-type-sizes: print the types of awaitees and unnamed coroutine locals.)
- #122927 (Change an ICE regression test to use the original reproducer)
- #122930 (add panic location to 'panicked while processing panic')
- #122931 (Fix some typos in the pin.rs)
- #122933 (tag_for_variant follow-ups)
r? `@ghost`
`@rustbot` modify labels: rollup
Change an ICE regression test to use the original reproducer
The ICE was fixed in PR https://github.com/rust-lang/rust/pull/122370, but the test used a different reproducer than the one originally reported. This PR changes it to the original one, giving us more confidence that the fix works.
Fixes#122199
-Zprint-type-sizes: print the types of awaitees and unnamed coroutine locals.
This should assist comprehending the size of coroutines. In particular, whenever a future is suspended while awaiting another future, the latter is given the special name `__awaitee`, and now the type of the awaited future will be printed, allowing identifying caller/callee — er, I mean, poller/pollee — relationships.
It would be possible to include the type name in more cases, but I thought that that might be overly verbose (`print-type-sizes` is already a lot of text) and ordinary named fields or variables are easier for readers to discover the types of.
This change will also synergize with my other PR #122923 which changes type printing to print the path of the `async fn` instead of the span.
Implementation note: I'm not sure if `Symbol::intern` is appropriate for this application, but it was the obvious way to not have to remove the `Copy` implementation from `FieldInfo`, or add a `'tcx` lifetime, while avoiding keeping a lot of possibly redundant strings in memory. I don't know what the proper tradeoff to make here is (though presumably it is not too important for a `-Z` debugging option).
Let codegen decide when to `mem::swap` with immediates
Making `libcore` decide this is silly; the backend has so much better information about when it's a good idea.
Thus this PR introduces a new `typed_swap` intrinsic with a fallback body, and replaces that fallback implementation when swapping immediates or scalar pairs.
r? oli-obk
Replaces #111744, and means we'll never need more libs PRs like #111803 or #107140
This should assist comprehending the size of coroutines.
In particular, whenever a future is suspended while awaiting another
future, the latter is given the special name `__awaitee`, and now the
type of the awaited future will be printed, allowing identifying
caller/callee — er, I mean, poller/pollee — relationships.
It would be possible to include the type name in more cases, but I
thought that that might be overly verbose (`print-type-sizes` is already
a lot of text) and ordinary named fields or variables are easier for
readers to discover the types of.
Current `transform_ty` attempts to avoid cycles when normalizing
`#[repr(transparent)]` types to their interior, but runs afoul of this
pattern used in `self_cell`:
```
struct X<T> {
x: u8,
p: PhantomData<T>,
}
#[repr(transparent)]
struct Y(X<Y>);
```
When attempting to normalize Y, it will still cycle indefinitely. By
using a types-visited list, this will instead get expanded exactly
one layer deep to X<Y>, and then stop, not attempting to normalize `Y`
any further.
Suggest `_` for missing generic arguments in turbofish
The compiler may suggest unusable generic type names for missing generic arguments in an expression context:
```rust
fn main() {
(0..1).collect::<Vec>()
}
```
> help: add missing generic argument
>
> (0..1).collect::<Vec<T>>()
but `T` is not a valid name in this context, and this suggestion won't compile.
I've changed it to use `_` inside method calls (turbofish), so it will suggest `(0..1).collect::<Vec<_>>()` which _may_ compile.
It's possible that the suggested `_` will be ambiguous, but there is very extensive E0283 that will help resolve that, which is more helpful than a basic "cannot find type `T` in this scope" users would get otherwise.
Out of caution to limit scope of the change I've limited it to just turbofish, but I suspect `_` could be the better choice in more cases. Perhaps in all expressions?
Note that the caller chooses a type for type param
```
error[E0308]: mismatched types
--> $DIR/return-impl-trait.rs:23:5
|
LL | fn other_bounds<T>() -> T
| - -
| | |
| | expected `T` because of return type
| | help: consider using an impl return type: `impl Trait`
| expected this type parameter
...
LL | ()
| ^^ expected type parameter `T`, found `()`
|
= note: expected type parameter `T`
found unit type `()`
= note: the caller chooses the type of T which can be different from ()
```
Tried to see if "expected this type parameter" can be replaced, but that goes all the way to `rustc_infer` so seems not worth the effort and can affect other diagnostics.
Revives #112088 and #104755.
compiler: allow transmute of ZST arrays with generics
Extend the `SizeSkeleton` evaluator to shortcut zero-sized arrays, thus considering `[T; 0]` to have a compile-time fixed-size of 0.
The existing evaluator already deals with generic arrays under the feature-guard `transmute_const_generics`. However, it merely allows comparing fixed-size types with fixed-size types, and generic types with generic types. For generic types, it merely compares whether their arguments match (ordering them first). Even if their exact sizes are not known at compile time, it can ensure that they will eventually be the same.
This patch extends this by shortcutting the size-evaluation of zero sized arrays and thus allowing size comparisons of `()` with `[T; 0]`, where one contains generics and the other does not.
This code is guarded by `transmute_const_generics` (#109929), even though it is unclear whether it should be. However, this assumes that a separate stabilization PR is required to move this out of the feature guard.
Initially reported in #98104.
With associated type bounds enabled, the implied_predicates and super_predicates
queries may differ for traits, since associated type bounds are also
implied but are not counted as super predicates.
Gracefully handle `AnonConst` in `diagnostic_hir_wf_check()`
Instead of running the WF check on the `AnonConst` itself we run it on the `ty` of the generic param of which the `AnonConst` is the default value.
Fixes#122199
Experimental feature postfix match
This has a basic experimental implementation for the RFC postfix match (rust-lang/rfcs#3295, #121618). [Liaison is](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Postfix.20Match.20Liaison/near/423301844) ```@scottmcm``` with the lang team's [experimental feature gate process](https://github.com/rust-lang/lang-team/blob/master/src/how_to/experiment.md).
This feature has had an RFC for a while, and there has been discussion on it for a while. It would probably be valuable to see it out in the field rather than continue discussing it. This feature also allows to see how popular postfix expressions like this are for the postfix macros RFC, as those will take more time to implement.
It is entirely implemented in the parser, so it should be relatively easy to remove if needed.
This PR is split in to 5 commits to ease review.
1. The implementation of the feature & gating.
2. Add a MatchKind field, fix uses, fix pretty.
3. Basic rustfmt impl, as rustfmt crashes upon seeing this syntax without a fix.
4. Add new MatchSource to HIR for Clippy & other HIR consumers
CFI: Skip non-passed arguments
Rust will occasionally rely on fn((), X) -> Y being compatible with fn(X) -> Y, since () is a non-passed argument. Relax CFI by choosing not to encode non-passed arguments.
This PR was split off from #121962 as part of fixing the larger vtable compatibility issues.
r? `@workingjubilee`
Several (doc) comments were super outdated or didn't provide enough context.
Some doc comments shoved everything in a single paragraph without respecting
the fact that the first paragraph should be a single sentence because rustdoc
treats these as item descriptions / synopses on module pages.
Add tests for shortcomings of associated type bounds
Adds the test in https://github.com/rust-lang/rust/pull/122791#issuecomment-2011433015
Turns out that #121123 is what breaks `tests/ui/associated-type-bounds/cant-see-copy-bound-from-child-rigid.rs` (passes on nightly), but given that associated type bounds haven't landed anywhere yet, I'm happy with breaking it.
This is unrelated to #122791, which just needed that original commit e6b64c6194 stacked on top of it so that it wouldn't have tests failing.
r? lcnr
Rust will occasionally rely on fn((), X) -> Y being compatible with
fn(X) -> Y, since () is a non-passed argument. Relax CFI by choosing not
to encode non-passed arguments.
Implement macro-based deref!() syntax for deref patterns
Stop using `box PAT` syntax for deref patterns, and instead use a perma-unstable macro.
Blocked on #122222
r? `@Nadrieril`
Interpolated cleanups
Various cleanups I made while working on attempts to remove `Interpolated`, that are worth merging now. Best reviewed one commit at a time.
r? `@petrochenkov`
Strip placeholders from hidden types before remapping generic parameter
When remapping generic parameters in the hidden type to the generic parameters of the definition of the opaque, we assume that placeholders cannot exist. Instead of just patching that site, I decided to handle it earlier, directly in `infer_opaque_types`, where we are already doing all the careful lifetime handling.
fixes#122694
the reason that ICE now occurred was that we stopped treating `operation` as being in the defining scope, so the TAIT became part of the hidden type of the `async fn`'s opaque type instead of just bailing out as ambiguos
I think
```rust
use std::future::Future;
mod foo {
type FutNothing<'a> = impl 'a + Future<Output = ()>;
//~^ ERROR: unconstrained opaque type
}
async fn operation(_: &mut ()) -> () {
//~^ ERROR: concrete type differs from previous
call(operation).await
//~^ ERROR: concrete type differs from previous
}
async fn call<F>(_f: F)
where
for<'any> F: FnMut(&'any mut ()) -> foo::FutNothing<'any>,
{
//~^ ERROR: expected generic lifetime parameter, found `'any`
}
```
would have already had the same ICE before https://github.com/rust-lang/rust/pull/121796
Make `#[diagnostic::on_unimplemented]` format string parsing more robust
This commit fixes several issues with the format string parsing of the `#[diagnostic::on_unimplemented]` attribute that were pointed out by `@ehuss.`
In detail it fixes:
* Appearing format specifiers (display, etc). For these we generate a warning that the specifier is unsupported. Otherwise we ignore them
* Positional arguments. For these we generate a warning that positional arguments are unsupported in that location and replace them with the format string equivalent (so `{}` or `{n}` where n is the index of the positional argument)
* Broken format strings with enclosed }. For these we generate a warning about the broken format string and set the emitted message literally to the provided unformatted string
* Unknown format specifiers. For these we generate an additional warning about the unknown specifier. Otherwise we emit the literal string as message.
This essentially makes those strings behave like `format!` with the minor difference that we do not generate hard errors but only warnings. After that we continue trying to do something unsuprising (mostly either ignoring the broken parts or falling back to just giving back the literal string as provided).
Fix#122391
r? `@compiler-errors`
Make `type_ascribe!` not a built-in
The only weird thing is the macro expansion note. I wonder if we should suppress these 🤔
r? ````@fmease```` since you told me about builtin# lol
Fix misc printing issues in emit=stable_mir
Trying to continue the work that ````@ouz-a```` started here: https://github.com/rust-lang/rust/pull/118364
Few modifications beyond fixes:
1. I made the `pretty_*` functions private.
2. I added a function to print the instance body
3. Changed a bunch of signatures to write to the writer directly.
4. Added a function to translate the place to its internal representation, so we could use the internal debug implementation.
5. Also removed `pretty_ty`, replaced by Display implementation of Ty which uses the internal display.
Don't ICE when encountering bound regions in generator interior type
I'm pretty sure this meant to say "`has_free_regions`", probably just a typo in 4a4fc3bb5b. We can have bound regions (because we only convert non-bound regions into existential regions in generator interiors), but we can't have (non-ReErased) free regions.
r? lcnr
deref patterns: bare-bones feature gate and typechecking
I am restarting the deref patterns experimentation. This introduces a feature gate under the lang-team [experimental feature](https://github.com/rust-lang/lang-team/blob/master/src/how_to/experiment.md) process, with [````@cramertj```` as lang-team liaison](https://github.com/rust-lang/lang-team/issues/88) (it's been a while though, you still ok with this ````@cramertj?).```` Tracking issue: https://github.com/rust-lang/rust/issues/87121.
This is the barest-bones implementation I could think of:
- explicit syntax, reusing `box <pat>` because that saves me a ton of work;
- use `Deref` as a marker trait (instead of a yet-to-design `DerefPure`);
- no support for mutable patterns with `DerefMut` for now;
- MIR lowering will come in the next PR. It's the trickiest part.
My goal is to let us figure out the MIR lowering part, which might take some work. And hopefully get something working for std types soon.
This is in large part salvaged from ````@fee1-dead's```` https://github.com/rust-lang/rust/pull/119467.
r? ````@compiler-errors````
recursively evaluate the constants in everything that is 'mentioned'
This is another attempt at fixing https://github.com/rust-lang/rust/issues/107503. The previous attempt at https://github.com/rust-lang/rust/pull/112879 seems stuck in figuring out where the [perf regression](https://perf.rust-lang.org/compare.html?start=c55d1ee8d4e3162187214692229a63c2cc5e0f31&end=ec8de1ebe0d698b109beeaaac83e60f4ef8bb7d1&stat=instructions:u) comes from. In https://github.com/rust-lang/rust/pull/122258 I learned some things, which informed the approach this PR is taking.
Quoting from the new collector docs, which explain the high-level idea:
```rust
//! One important role of collection is to evaluate all constants that are used by all the items
//! which are being collected. Codegen can then rely on only encountering constants that evaluate
//! successfully, and if a constant fails to evaluate, the collector has much better context to be
//! able to show where this constant comes up.
//!
//! However, the exact set of "used" items (collected as described above), and therefore the exact
//! set of used constants, can depend on optimizations. Optimizing away dead code may optimize away
//! a function call that uses a failing constant, so an unoptimized build may fail where an
//! optimized build succeeds. This is undesirable.
//!
//! To fix this, the collector has the concept of "mentioned" items. Some time during the MIR
//! pipeline, before any optimization-level-dependent optimizations, we compute a list of all items
//! that syntactically appear in the code. These are considered "mentioned", and even if they are in
//! dead code and get optimized away (which makes them no longer "used"), they are still
//! "mentioned". For every used item, the collector ensures that all mentioned items, recursively,
//! do not use a failing constant. This is reflected via the [`CollectionMode`], which determines
//! whether we are visiting a used item or merely a mentioned item.
//!
//! The collector and "mentioned items" gathering (which lives in `rustc_mir_transform::mentioned_items`)
//! need to stay in sync in the following sense:
//!
//! - For every item that the collector gather that could eventually lead to build failure (most
//! likely due to containing a constant that fails to evaluate), a corresponding mentioned item
//! must be added. This should use the exact same strategy as the ecollector to make sure they are
//! in sync. However, while the collector works on monomorphized types, mentioned items are
//! collected on generic MIR -- so any time the collector checks for a particular type (such as
//! `ty::FnDef`), we have to just onconditionally add this as a mentioned item.
//! - In `visit_mentioned_item`, we then do with that mentioned item exactly what the collector
//! would have done during regular MIR visiting. Basically you can think of the collector having
//! two stages, a pre-monomorphization stage and a post-monomorphization stage (usually quite
//! literally separated by a call to `self.monomorphize`); the pre-monomorphizationn stage is
//! duplicated in mentioned items gathering and the post-monomorphization stage is duplicated in
//! `visit_mentioned_item`.
//! - Finally, as a performance optimization, the collector should fill `used_mentioned_item` during
//! its MIR traversal with exactly what mentioned item gathering would have added in the same
//! situation. This detects mentioned items that have *not* been optimized away and hence don't
//! need a dedicated traversal.
enum CollectionMode {
/// Collect items that are used, i.e., actually needed for codegen.
///
/// Which items are used can depend on optimization levels, as MIR optimizations can remove
/// uses.
UsedItems,
/// Collect items that are mentioned. The goal of this mode is that it is independent of
/// optimizations: the set of "mentioned" items is computed before optimizations are run.
///
/// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
/// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
/// might decide to run them before computing mentioned items.) The key property of this set is
/// that it is optimization-independent.
MentionedItems,
}
```
And the `mentioned_items` MIR body field docs:
```rust
/// Further items that were mentioned in this function and hence *may* become monomorphized,
/// depending on optimizations. We use this to avoid optimization-dependent compile errors: the
/// collector recursively traverses all "mentioned" items and evaluates all their
/// `required_consts`.
///
/// This is *not* soundness-critical and the contents of this list are *not* a stable guarantee.
/// All that's relevant is that this set is optimization-level-independent, and that it includes
/// everything that the collector would consider "used". (For example, we currently compute this
/// set after drop elaboration, so some drop calls that can never be reached are not considered
/// "mentioned".) See the documentation of `CollectionMode` in
/// `compiler/rustc_monomorphize/src/collector.rs` for more context.
pub mentioned_items: Vec<Spanned<MentionedItem<'tcx>>>,
```
Fixes#107503
This commit fixes several issues with the format string parsing of the
`#[diagnostic::on_unimplemented]` attribute that were pointed out by
@ehuss.
In detail it fixes:
* Appearing format specifiers (display, etc). For these we generate a
warning that the specifier is unsupported. Otherwise we ignore them
* Positional arguments. For these we generate a warning that positional
arguments are unsupported in that location and replace them with the
format string equivalent (so `{}` or `{n}` where n is the index of the
positional argument)
* Broken format strings with enclosed }. For these we generate a warning
about the broken format string and set the emitted message literally to
the provided unformatted string
* Unknown format specifiers. For these we generate an additional warning
about the unknown specifier. Otherwise we emit the literal string as
message.
This essentially makes those strings behave like `format!` with the
minor difference that we do not generate hard errors but only warnings.
After that we continue trying to do something unsuprising (mostly either
ignoring the broken parts or falling back to just giving back the
literal string as provided).
Fix#122391
Split an item bounds and an item's super predicates
This is the moral equivalent of #107614, but instead for predicates this applies to **item bounds**. This PR splits out the item bounds (i.e. *all* predicates that are assumed to hold for the alias) from the item *super predicates*, which are the subset of item bounds which share the same self type as the alias.
## Why?
Much like #107614, there are places in the compiler where we *only* care about super-predicates, and considering predicates that possibly don't have anything to do with the alias is problematic. This includes things like closure signature inference (which is at its core searching for `Self: Fn(..)` style bounds), but also lints like `#[must_use]`, error reporting for aliases, computing type outlives predicates.
Even in cases where considering all of the `item_bounds` doesn't lead to bugs, unnecessarily considering irrelevant bounds does lead to a regression (#121121) due to doing extra work in the solver.
## Example 1 - Trait Aliases
This is best explored via an example:
```
type TAIT<T> = impl TraitAlias<T>;
trait TraitAlias<T> = A + B where T: C;
```
The item bounds list for `Tait<T>` will include:
* `Tait<T>: A`
* `Tait<T>: B`
* `T: C`
While `item_super_predicates` query will include just the first two predicates.
Side-note: You may wonder why `T: C` is included in the item bounds for `TAIT`? This is because when we elaborate `TraitAlias<T>`, we will also elaborate all the predicates on the trait.
## Example 2 - Associated Type Bounds
```
type TAIT<T> = impl Iterator<Item: A>;
```
The `item_bounds` list for `TAIT<T>` will include:
* `Tait<T>: Iterator`
* `<Tait<T> as Iterator>::Item: A`
But the `item_super_predicates` will just include the first bound, since that's the only bound that is relevant to the *alias* itself.
## So what
This leads to some diagnostics duplication just like #107614, but none of it will be user-facing. We only see it in the UI test suite because we explicitly disable diagnostic deduplication.
Regarding naming, I went with `super_predicates` kind of arbitrarily; this can easily be changed, but I'd consider better names as long as we don't block this PR in perpetuity.
Fix bad span for explicit lifetime suggestions
Fixes#121267
Current explicit lifetime suggestions are not showing correct spans for some lifetimes - e.g. elided lifetime generic parameters;
This should be done correctly regarding elided lifetime kind like the following code
43fdd4916d/compiler/rustc_resolve/src/late/diagnostics.rs (L3015-L3044)