This manifistated in #90195 with compiler being unable to keep
one candidate for a trait impl, if where is a global impl and more
than one trait bound in the where clause.
Before #87280 `candidate_should_be_dropped_in_favor_of` was using
`TypeFoldable::is_global()` that was enough to discard the two
`ParamCandidate`s. But #87280 changed it to use
`TypeFoldable::is_known_global()` instead, which is pessimistic, so
now the compiler drops the global impl instead (because
`is_known_global` is not sure) and then can't decide between the
two `ParamCandidate`s.
Switching it to use `is_global` again solves the issue.
Fixes#90195.
Use the "nice E0277 errors"[1] for `!Send` `impl Future` from foreign crate
Partly address #78543 by making the error quieter.
We don't have access to the `typeck` tables from foreign crates, so we
used to completely skip the new code when checking foreign crates. Now,
we carry on and don't provide as nice output (we don't clarify *what* is
making the `Future: !Send`), but at least we no longer emit a sea of
derived obligations in the output.
[1]: https://blog.rust-lang.org/inside-rust/2019/10/11/AsyncAwait-Not-Send-Error-Improvements.html
r? `@tmandry`
Partly address #78543 by making the error quieter.
We don't have access to the `typeck` tables from foreign crates, so we
used to completely skip the new code when checking foreign crates. Now,
we carry on and don't provide as nice output (we don't clarify *what* is
making the `Future: !Send`), but at least we no longer emit a sea of
derived obligations in the output.
[1]: https://blog.rust-lang.org/inside-rust/2019/10/11/AsyncAwait-Not-Send-Error-Improvements.html
Implement coherence checks for negative trait impls
The main purpose of this PR is to be able to [move Error trait to core](https://github.com/rust-lang/project-error-handling/issues/3).
This feature is necessary to handle the following from impl on box.
```rust
impl From<&str> for Box<dyn Error> { ... }
```
Without having negative traits affect coherence moving the error trait into `core` and moving that `From` impl to `alloc` will cause the from impl to no longer compiler because of a potential future incompatibility. The compiler indicates that `&str` _could_ introduce an `Error` impl in the future, and thus prevents the `From` impl in `alloc` that would cause overlap with `From<E: Error> for Box<dyn Error>`. Adding `impl !Error for &str {}` with the negative trait coherence feature will disable this error by encoding a stability guarantee that `&str` will never implement `Error`, making the `From` impl compile.
We would have this in `alloc`:
```rust
impl From<&str> for Box<dyn Error> {} // A
impl<E> From<E> for Box<dyn Error> where E: Error {} // B
```
and this in `core`:
```rust
trait Error {}
impl !Error for &str {}
```
r? `@nikomatsakis`
This PR was built on top of `@yaahc` PR #85764.
Language team proposal: to https://github.com/rust-lang/lang-team/issues/96
This doesn't work properly yet, we would probably need to implement an
`assembly_neg_candidates` and consider things like `T: !AB` as `T: !A`
|| `T: !B`
Adopt let_else across the compiler
This performs a substitution of code following the pattern:
```
let <id> = if let <pat> = ... { identity } else { ... : ! };
```
To simplify it to:
```
let <pat> = ... { identity } else { ... : ! };
```
By adopting the `let_else` feature (cc #87335).
The PR also updates the syn crate because the currently used version of the crate doesn't support `let_else` syntax yet.
Note: Generally I'm the person who *removes* usages of unstable features from the compiler, not adds more usages of them, but in this instance I think it hopefully helps the feature get stabilized sooner and in a better state. I have written a [comment](https://github.com/rust-lang/rust/issues/87335#issuecomment-944846205) on the tracking issue about my experience and what I feel could be improved before stabilization of `let_else`.
This performs a substitution of code following the pattern:
let <id> = if let <pat> = ... { identity } else { ... : ! };
To simplify it to:
let <pat> = ... { identity } else { ... : ! };
By adopting the let_else feature.
Add `const_eval_select` intrinsic
Adds an intrinsic that calls a given function when evaluated at compiler time, but generates a call to another function when called at runtime.
See https://github.com/rust-lang/const-eval/issues/7 for previous discussion.
r? `@oli-obk.`
Prevent error reporting from outputting a recursion error if it finds an ambiguous trait impl during suggestions
Closes#89275
This fixes the compiler reporting a recursion error during another already in progress error by trying to make a conversion method suggestion and encounters ambiguous trait implementations that can convert a the original type into a type that can then be recursively converted into itself via another method in the trait.
Updated OverflowError struct to be an enum so I could differentiate between passes - it's no longer a ZST but I don't think that should be a problem as they only generate when there's an error in compiling code anyway
Rollup of 7 pull requests
Successful merges:
- #89298 (Issue 89193 - Fix ICE when using `usize` and `isize` with SIMD gathers )
- #89461 (Add `deref_into_dyn_supertrait` lint.)
- #89477 (Move items related to computing diffs to a separate file)
- #89559 (RustWrapper: adapt for LLVM API change)
- #89585 (Emit item no type error even if type inference fails)
- #89596 (Make cfg imply doc(cfg))
- #89615 (Add InferCtxt::with_opaque_type_inference to get_body_with_borrowck_facts)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Add `deref_into_dyn_supertrait` lint.
Initial implementation of #89460. Resolves#89190.
Maybe also worth a beta backport if necessary.
r? `@nikomatsakis`
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.