constify const Fn*: Destruct
makes closures const destruct where their upvars are. i think this makes sense
and is how this should be implemented.
r? @oli-obk
Always check `ConstArgHasType` even when otherwise ignoring
fixes https://github.com/rust-lang/rust/issues/149774
helping @BoxyUwU finish up https://github.com/rust-lang/rust/pull/150322, this is a simple tweak/finishing-up of that PR.
this is a breaking change that crater detected has some issues with in Boxy's PR, and hence needs a t-types FCP. I can go and help fix those crates if/once the break is signed off on.
On E0277 tweak help when single type impls traits
When encountering an unmet predicate, when we point at the trait impls that do exist, if they are all for the same self type, tweak the wording to make it less verbose.
When encountering an unmet predicate, when we point at the trait impls that do exist, if they are all for the same self type, tweak the wording to make it less verbose.
don't suggest non-deriveable traits for unions
Fixesrust-lang/rust#137587
Before, the compiler suggested adding `#[derive(Debug)]` (other traits too) for unions,
which is misleading because some traits can't be automatically derived.
Only traits that are still suggested are Copy and Clone.
I noticed the error label changed after removing the suggestion. I hope this isn't a big deal, but let me know if that's an issue.
original example:
```rs
union Union {
member: usize,
}
impl PartialEq<u8> for Union {
fn eq(&self, rhs: &u8) -> bool {
unsafe { self.member == (*rhs).into() }
}
}
fn main() {
assert_eq!(Union { member: 0 }, 0);
}
```
before:
```
error[E0277]: `Union` doesn't implement `Debug`
--> src\main.rs:13:5
|
13 | assert_eq!(Union { member: 0 }, 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `Union`
|
= note: add `#[derive(Debug)]` to `Union` or manually `impl Debug for Union`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Union` with `#[derive(Debug)]`
|
2 + #[derive(Debug)]
3 | union Union {
|
```
after (the message doesn't suggest adding #[derive(Debug)] to unions)
```
error[E0277]: `Union` doesn't implement `Debug`
--> src\main.rs:13:5
|
13 | assert_eq!(Union { member: 0 }, 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `Debug` is not implemented for `Union`
--> src\main.rs:2:1
|
2 | union Union {
| ^^^^^^^^^^^
= note: manually `impl Debug for Union`
```
When encountering an inference error where a return type must be known, like when calling `Iterator::sum::<T>()` without specifying `T`, look for all `T` that would satisfy `Sum<S>`. If only one, suggest it.
```
error[E0283]: type annotations needed
--> $DIR/cannot-infer-iterator-sum-return-type.rs:4:9
|
LL | let sum = v
| ^^^
...
LL | .sum(); // `sum::<T>` needs `T` to be specified
| --- type must be known at this point
|
= note: cannot satisfy `_: Sum<i32>`
help: the trait `Sum` is implemented for `i32`
--> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL
|
= note: in this macro invocation
note: required by a bound in `std::iter::Iterator::sum`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
= note: this error originates in the macro `integer_sum_product` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider giving `sum` an explicit type, where the type for type parameter `S` is specified
|
LL | let sum: i32 = v
| +++++
```
Point turbofish inference errors at the uninferred generic arg
Follow-up to rust-lang/rust#153751.
When a method call has a turbofish with an uninferred generic argument, point the diagnostic span at the specific `_` that couldn't be inferred instead of the method name.
Before:
```rust
LL | S.f::<u32, _>(42);
| ^ cannot infer type of the type parameter `B`
```
After:
```rust
LL | S.f::<u32, _>(42);
| ^ cannot infer type of the type parameter `B`
```
Path expressions (`None::<_>`, `foo::<_>()`) are not handled yet, that's a separate code path.
cc @eggyal
Tweak wording of failed predicate in inference error
Special case message talking about `Predicate` that couldn't be satisfied when in inference errors so that we don't say "cannot satisfy `_: Trait`" and instead say "type must implement `Trait`".
Suppress self-referential associated type constraint suggestion
Fixesrust-lang/rust#112104
When comparing `Option<&I::Item>` against `Option<I::Item>`, the compiler decomposes the mismatch into `expected = &<I as Iterator>::Item` vs `found = <I as Iterator>::Item`. ARM 2 in `note_and_explain_type_err` matches because `found` is a projection, and would suggest `Item = &<I as Iterator>::Item` — constraining the associated type to something that contains itself.
ARM 1 (`expected_projection`) already guards against this with `found.contains(expected)`. ARM 2 was missing the symmetric check. This adds `expected.contains(found)` to the match guard.
Before:
```rust
help: consider constraining the associated type `<I as Iterator>::Item` to `&<I as Iterator>::Item`
|
1 | fn foo<I: Iterator<Item = &<I as Iterator>::Item>>(iter: &mut I) {
| +++++++++++++++++++++++++++++++
```
After: bogus suggestion is gone, and the existing `.as_ref()` suggestion from `hir_typeck` still fires correctly.
r? @estebank
Special case message talking about `Predicate` that couldn't be satisfied when in inference errors so that we don't say "cannot satisfy `_: Trait`" and instead say "type must implement `Trait`".
Provide better suggestions for inference errors on `.collect()?`
When encountering an inference error when calling `.collect()` followed by `?`, detect the return type of the enclosing function and suggest `.collect::<Result<_, _>>()?` instead of `.collect::<Vec<_>>()?`:
```
error[E0283]: type annotations needed
--> $DIR/question-mark-type-infer.rs:10:21
|
LL | l.iter().map(f).collect()?
| ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect`
|
= note: cannot satisfy `_: FromIterator<Result<i32, ()>>`
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider specifying the generic argument
|
LL | l.iter().map(f).collect::<Result<_, _>>()?
| ++++++++++++++++
```
On inference error in let binding, account for `?`:
```
error[E0282]: type annotations needed
--> $DIR/question-mark-type-inference-in-chain.rs:31:9
|
LL | let mut tags = lines.iter().map(|e| parse(e)).collect()?;
| ^^^^^^^^
...
LL | tags.sort();
| ---- type must be known at this point
|
help: consider giving `tags` an explicit type
|
LL | let mut tags: Vec<_> = lines.iter().map(|e| parse(e)).collect()?;
| ++++++++
```
Address rust-lang/rust#129269.
When encountering an inference error when calling `.collect()` followed by `?`, detect the return type of the enclosing function and suggest `.collect::<Result<_, _>>()?` instead of `.collect::<Vec<_>>()?`:
```
error[E0283]: type annotations needed
--> $DIR/question-mark-type-infer.rs:10:21
|
LL | l.iter().map(f).collect()?
| ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect`
|
= note: cannot satisfy `_: FromIterator<Result<i32, ()>>`
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider specifying the generic argument
|
LL | l.iter().map(f).collect::<Result<_, _>>()?
| ++++++++++++++++
```
On inference error in let binding, account for `?`:
```
error[E0282]: type annotations needed
--> $DIR/question-mark-type-inference-in-chain.rs:31:9
|
LL | let mut tags = lines.iter().map(|e| parse(e)).collect()?;
| ^^^^^^^^
...
LL | tags.sort();
| ---- type must be known at this point
|
help: consider giving `tags` an explicit type
|
LL | let mut tags: Vec<_> = lines.iter().map(|e| parse(e)).collect()?;
| ++++++++
```
Provide more context on type errors in const context
- On `const` and `static` point at the type (like we do for let bindings)
- On fn calls, point at const parameter in fn definition
- On type, point at const parameter in type definition
- On array type lengths, explain that array length is always `usize`
- On enum variant discriminant, mention `repr`
- On default field value using type parameter, provide more context (Fixrust-lang/rust#147748)
Reimplement const closures
Tracking issue: rust-lang/rust#106003
Best reviewed commit-by-commit
The old solver can't handle `for<'a> |x: &'a()| ()` closures in const contexts, but that feature is unstable itself, so we can just leave it to the next solver to handle.
We need a lot more tests, we're testing the bare minimum of success and failure paths right now.
r? @fee1-dead
Simplify `type_of_opaque`.
There is a bunch of complexity supporting the "cannot check whether the hidden type of opaque type satisfies auto traits" error that shows up in `tests/ui/impl-trait/auto-trait-leak.rs`. This is an obscure error that shows up in a single test. If we are willing to downgrade that error message to a cycle error, we can do the following.
- Simplify the `type_of_opaque` return value.
- Remove the `cycle_stash` query modifier.
- Remove the `CyclePlaceholder` type.
- Remove the `SelectionError::OpaqueTypeAutoTraitLeakageUnknown` variant.
- Remove a `FromCycleError` impl.
- Remove `report_opaque_type_auto_trait_leakage`.
- Remove the `StashKey::Cycle` variant.
- Remove the `CycleErrorHandling::Stash` variant.
That's a lot! I think this is a worthwhile trade-off.
r? @oli-obk
There is a bunch of complexity supporting the "cannot check whether the
hidden type of opaque type satisfies auto traits" error that shows up in
`tests/ui/impl-trait/auto-trait-leak.rs`. This is an obscure error that
shows up in a single test. If we are willing to downgrade that error
message to a cycle error, we can do the following.
- Simplify the `type_of_opaque` return value.
- Remove the `cycle_stash` query modifier.
- Remove the `CyclePlaceholder` type.
- Remove the `SelectionError::OpaqueTypeAutoTraitLeakageUnknown`
variant.
- Remove a `FromCycleError` impl.
- Remove `report_opaque_type_auto_trait_leakage`.
- Remove the `StashKey::Cycle` variant.
- Remove the `CycleErrorHandling::Stash` variant.
That's a lot! I think this is a worthwhile trade-off.
Detect inherent method behind deref being shadowed by trait method
```
error[E0277]: the trait bound `Rc<RefCell<S>>: Borrow<S>` is not satisfied
--> $DIR/shadowed-intrinsic-method-deref.rs:16:22
|
LL | let sb : &S = &s.borrow();
| ^^^^^^ the trait `Borrow<S>` is not implemented for `Rc<RefCell<S>>`
|
help: the trait `Borrow<S>` is not implemented for `Rc<RefCell<S>>`
but trait `Borrow<RefCell<S>>` is implemented for it
--> $SRC_DIR/alloc/src/rc.rs:LL:COL
= help: for that trait implementation, expected `RefCell<S>`, found `S`
= note: there's an inherent method on `RefCell<S>` of the same name, which can be auto-dereferenced from `&RefCell<T>`
help: to access the inherent method on `RefCell<S>`, use the fully-qualified path
|
LL - let sb : &S = &s.borrow();
LL + let sb : &S = &RefCell::borrow(&s);
|
```
In the example above, method `borrow` is available both on `<RefCell<S> as Borrow<S>>` *and* on `RefCell<S>`. Adding the import `use std::borrow::Borrow;` causes `s.borrow()` to find the former instead of the latter. We now point out that the other exists, and provide a suggestion on how to call it.
Fixrust-lang/rust#41906. CC rust-lang/rust#153662.
```
error[E0277]: the trait bound `Rc<RefCell<S>>: Borrow<S>` is not satisfied
--> $DIR/shadowed-intrinsic-method-deref.rs:16:22
|
LL | let sb : &S = &s.borrow();
| ^^^^^^ the trait `Borrow<S>` is not implemented for `Rc<RefCell<S>>`
|
help: the trait `Borrow<S>` is not implemented for `Rc<RefCell<S>>`
but trait `Borrow<RefCell<S>>` is implemented for it
--> $SRC_DIR/alloc/src/rc.rs:LL:COL
= help: for that trait implementation, expected `RefCell<S>`, found `S`
= note: there's an inherent method on `RefCell<S>` of the same name, which can be auto-dereferenced from `&RefCell<T>`
help: to access the inherent method on `RefCell<S>`, use the fully-qualified path
|
LL - let sb : &S = &s.borrow();
LL + let sb : &S = &RefCell::borrow(&s);
|
```
In the example above, method `borrow` is available both on `<RefCell<S> as Borrow<S>>` *and* on `RefCell<S>`. Adding the import `use std::borrow::Borrow;` causes `s.borrow()` to find the former instead of the latter. We now point out that the other exists, and provide a suggestion on how to call it.
Avoid projection-only suggestions for inherent assoc types
Fixesrust-lang/rust#153539.
Type mismatch diagnostics in `note_and_explain_type_err` currently route both `ty::Projectio`n and `ty::Inherent`
through the same associated-type suggestion path. For inherent associated types, that path can reach helpers that
are only valid for trait projections.
Overhaul `ensure_ok`
The interaction of `ensure_ok` and the `return_result_from_ensure_ok` query modifier is weird and hacky. This PR cleans it up. Details in the individual commits.
r? @Zalathar
`ensure_ok` provides a special, more efficient way of calling a query
when its return value isn't needed. But there is a complication: if the
query is marked with the `return_result_from_ensure_ok` modifier, then
it will return `Result<(), ErrorGuaranteed`. This is clunky and feels
tacked on. It's annoying to have to add a modifier to a query to declare
information present in its return type, and it's confusing that queries
called via `ensure_ok` have different return types depending on the
modifier.
This commit:
- Eliminates the `return_result_from_ensure_ok` modifier. The proc macro
now looks at the return type and detects if it matches `Result<_,
ErrorGuarantee>`. If so, it adds the modifier
`returns_error_guaranteed`. (Aside: We need better terminology to
distinguish modifiers written by the user in a `query` declaration
(e.g. `cycle_delayed_bug`) from modifiers added by the proc macro
(e.g. `cycle_error_handling`.))
- Introduces `ensure_result`, which replaces the use of `ensure_ok` for
queries that return `Result<_, ErrorGuarantee>`. As a result,
`ensure_ok` can now only be used for the "ignore the return value"
case.
Clean up the eager formatting API
For https://github.com/rust-lang/rust/issues/151366#event-22181360642
Previously eager formatting worked by throwing the arguments into a diag, formatting, then removing the args again. This is ugly so instead we now just do the formatting completely separately.
This PR has nice commits, so I recommend reviewing commit by commit.
r? @GuillaumeGomez