improve `_` constants in item signature handling
removing the "type" from the error messages does slightly worsen the error messages for types, but figuring out whether the placeholder is for a type or a constant and correctly dealing with that seemed fairly difficult to me so I took the easy way out ✨ Imo the error message is still clear enough.
r? `@BoxyUwU` cc `@estebank`
Point at correct argument when async fn output type lifetime disagrees with signature
Fixes most of #74256.
## Problems fixed
This PR fixes a couple of related problems in the error reporting code.
### Highlighting the wrong argument
First, the error reporting code was looking at the desugared return type of an `async fn` to decide which parameter to highlight. For example, a function like
```rust
async fn async_fn(self: &Struct, f: &u32) -> &u32
{ f }
```
desugars to
```rust
async fn async_fn<'a, 'b>(self: &'a Struct, f: &'b u32)
-> impl Future<Output = &'a u32> + 'a + 'b
{ f }
```
Since `f: &'b u32` is returned but the output type is `&'a u32`, the error would occur when checking that `'a: 'b`.
The reporting code would look to see if the "offending" lifetime `'b` was included in the return type, and because the code was looking at the desugared future type, it was included. So it defaulted to reporting that the source of the other lifetime `'a` (the `self` type) was the problem, when it was really the type of `f`. (Note that if it had chosen instead to look at `'a` first, it too would have been included in the output type, and it would have arbitrarily reported the error (correctly this time) on the type of `f`.)
Looking at the actual future type isn't useful for this reason; it captures all input lifetimes. Using the written return type for `async fn` solves this problem and results in less confusing error messages for the user.
This isn't a perfect fix, unfortunately; writing the "manually desugared" form of the above function still results in the wrong parameter being highlighted. Looking at the output type of every `impl Future` return type doesn't feel like a very principled approach, though it might work. The problem would remain for function signatures that look like the desugared one above but use different traits. There may be deeper changes required to pinpoint which part of each type is conflicting.
### Lying about await point capture causing lifetime conflicts
The second issue fixed by this PR is the unnecessary complexity in `try_report_anon_anon_conflict`. It turns out that the root cause I suggested in https://github.com/rust-lang/rust/issues/76547#issuecomment-692863608 wasn't really the root cause. Adding special handling to report that a variable was captured over an await point only made the error messages less correct and pointed to a problem other than the one that actually occurred.
Given the above discussion, it's easy to see why: `async fn`s capture all input lifetimes in their return type, so holding an argument across an await point should never cause a lifetime conflict! Removing the special handling simplified the code and improved the error messages (though they still aren't very good!)
## Future work
* Fix error reporting on the "desugared" form of this code
* Get the `suggest_adding_lifetime_params` suggestion firing on these examples
* cc #42703, I think
r? `@estebank`
Improve SIMD casts
* Allows `simd_cast` intrinsic to take `usize` and `isize`
* Adds `simd_as` intrinsic, which is the same as `simd_cast` except for saturating float-to-int conversions (matching the behavior of `as`).
cc `@workingjubilee`
Fix ICEs related to `Deref<Target=[T; N]>` on newtypes
1. Stash a const infer's type into the canonical var during canonicalization, so we can recreate the fresh const infer with that same type.
For example, given `[T; _]` we know `_` is a `usize`. If we go from infer => canonical => infer, we shouldn't forget that variable is a usize.
Fixes#92626Fixes#83704
2. Don't stash the autoderef'd slice type that we get from method lookup, but instead recreate it during method confirmation. We need to do this because the type we receive back after picking the method references a type variable that does not exist after probing is done.
Fixes#92637
... A better solution for the second issue would be to actually _properly_ implement `Deref` for `[T; N]` instead of fixing this autoderef hack to stop leaking inference variables. But I actually looked into this, and there are many complications with const impls.
Replace use of `ty()` on term and use it in more places. This will allow more flexibility in the
future, but slightly worried it allows items which are consts which only accept types.
Implement `#[rustc_must_implement_one_of]` attribute
This PR adds a new attribute — `#[rustc_must_implement_one_of]` that allows changing the "minimal complete definition" of a trait. It's similar to GHC's minimal `{-# MINIMAL #-}` pragma, though `#[rustc_must_implement_one_of]` is weaker atm.
Such attribute was long wanted. It can be, for example, used in `Read` trait to make transitions to recently added `read_buf` easier:
```rust
#[rustc_must_implement_one_of(read, read_buf)]
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let mut buf = ReadBuf::new(buf);
self.read_buf(&mut buf)?;
Ok(buf.filled_len())
}
fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> {
default_read_buf(|b| self.read(b), buf)
}
}
impl Read for Ty0 {}
//^ This will fail to compile even though all `Read` methods have default implementations
// Both of these will compile just fine
impl Read for Ty1 {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> { /* ... */ }
}
impl Read for Ty2 {
fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> Result<()> { /* ... */ }
}
```
For now, this is implemented as an internal attribute to start experimenting on the design of this feature. In the future we may want to extend it:
- Allow arbitrary requirements like `a | (b & c)`
- Allow multiple requirements like
- ```rust
#[rustc_must_implement_one_of(a, b)]
#[rustc_must_implement_one_of(c, d)]
```
- Make it appear in rustdoc documentation
- Change the syntax?
- Etc
Eventually, we should make an RFC and make this (or rather similar) attribute public.
---
I'm fairly new to compiler development and not at all sure if the implementation makes sense, but at least it passes tests :)
ProjectionPredicate should be able to handle both associated types and consts so this adds the
first step of that. It mainly just pipes types all the way down, not entirely sure how to handle
consts, but hopefully that'll come with time.
Replace `NestedVisitorMap` with generic `NestedFilter`
This is an attempt to make the `intravisit::Visitor` API simpler and "more const" with regard to nested visiting.
With this change, `intravisit::Visitor` does not visit nested things by default, unless you specify `type NestedFilter = nested_filter::OnlyBodies` (or `All`). `nested_visit_map` returns `Self::Map` instead of `NestedVisitorMap<Self::Map>`. It panics by default (unreachable if `type NestedFilter` is omitted).
One somewhat trixty thing here is that `nested_filter::{OnlyBodies, All}` live in `rustc_middle` so that they may have `type Map = map::Map` and so that `impl Visitor`s never need to specify `type Map` - it has a default of `Self::NestedFilter::Map`.
Remove deprecated LLVM-style inline assembly
The `llvm_asm!` was deprecated back in #87590 1.56.0, with intention to remove
it once `asm!` was stabilized, which already happened in #91728 1.59.0. Now it
is time to remove `llvm_asm!` to avoid continued maintenance cost.
Closes#70173.
Closes#92794.
Closes#87612.
Closes#82065.
cc `@rust-lang/wg-inline-asm`
r? `@Amanieu`
Fix `try wrapping expression in variant` suggestion with struct field shorthand
Fixes a broken suggestion: [playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=83fe2dbfe1485f8cfca1aef2a6582e77)
before:
```
error[E0308]: mismatched types
--> src/main.rs:7:19
|
7 | let x = Foo { bar };
| ^^^ expected enum `Option`, found integer
|
= note: expected enum `Option<i32>`
found type `{integer}`
help: try wrapping the expression in `Some`
|
7 | let x = Foo { Some(bar) };
| +++++ +
```
after:
```
error[E0308]: mismatched types
--> src/main.rs:7:19
|
7 | let x = Foo { bar };
| ^^^ expected enum `Option`, found integer
|
= note: expected enum `Option<i32>`
found type `{integer}`
help: try wrapping the expression in `Some`
|
7 | let x = Foo { bar: Some(bar) };
| ~~~~~~~~~~~~~~
```
r? ``@m-ou-se``
since you touched the code last in #91080
Link impl items to corresponding trait items in late resolver.
Hygienically linking trait impl items to declarations in the trait can be done directly by the late resolver. In fact, it is already done to diagnose unknown items.
This PR uses this resolution work and stores the `DefId` of the trait item in the HIR. This avoids having to do this resolution manually later.
r? `@matthewjasper`
Related to #90639. The added `trait_item_id` field can be moved to `ImplItemRef` to be used directly by your PR.
Do not fail evaluation in const blocks
Evaluate const blocks with a const param-env, so we properly check `~const` trait bounds.
Fixes#92713
(I will fix the poor diagnostics in #92713 and #92712 in a separate PR)
cc `@nbdd0121` who wrote the code this PR touches in #89561
Prefer projection candidates instead of param_env candidates for Sized predicates
Fixes#89352
Also includes some drive by logging and verbose printing changes that I found useful when debugging this, but I can remove this if needed.
This is a little hacky - but imo no more than the rest of `candidate_should_be_dropped_in_favor_of`. Importantly, in a Chalk-like world, both candidates should be completely compatible.
r? ```@nikomatsakis```
Deduplicate box deref and regular deref suggestions
Remove the suggestion code special-cased for Box deref.
r? ```@camelid```
since you introduced the code in #90627
Suggest `return`ing tail expressions in async functions
This PR fixes#92308.
Previously, the suggestion to `return` tail expressions (introduced in #81769) did not apply to `async` functions, as the suggestion checked whether the types were equal disregarding `impl Future<Output = T>` syntax sugar for `async` functions. This PR changes that in order to fix a potential papercut.
I'm not sure if this is the "right" way to do this, so if there is a better way then please let me know.
I amended an existing test introduced in #81769 to add a regression test for this, if you think I should make a separate test I will.
Closure capture cleanup & refactor
Follow up of #89648
Each commit is self-contained and the rationale/changes are documented in the commit message, so it's advisable to review commit by commit.
The code is significantly cleaner (at least IMO), but that could have some perf implication, so I'd suggest a perf run.
r? `@wesleywiser`
cc `@arora-aman`