-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Order-dependence of dyn Trait: Supertrait
goals causes incompleteness (old solver)
#123303
Comments
cc @lcnr who may know if this issue already is tracked |
Actually this is just because |
So what happens here:
Specifically, winnowing does not take into account stack dependence: rust/compiler/rustc_trait_selection/src/traits/select/mod.rs Lines 495 to 497 in 8058136
And so therefore it may inadvertently "downgrade" a result that may be stack dependent to one that isn't stack dependent by removing it from the list of candidates, meaning we return Unfortunately, this is only hit when we actually do winnowing -- if there's only one candidate, then we won't winnow: rust/compiler/rustc_trait_selection/src/traits/select/mod.rs Lines 472 to 488 in 8058136
So that's why we don't see this more often. |
If #122791 weren't so close to landing, then I would probably instead fix this by changing winnowing: diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 1894fbba302..09d1df586c3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -492,10 +492,16 @@ fn candidate_from_obligation_no_cache<'o>(
let mut candidates = candidates
.into_iter()
.map(|c| match self.evaluate_candidate(stack, &c) {
- Ok(eval) if eval.may_apply() => {
+ // We CANNOT winnow `EvaluateToErrStackDependent`, since if we do,
+ // then we may end up with NO candidates in this list. If that's
+ // the case, then we will return `SelectionError::Unimplemented`,
+ // which results in `EvaluatedToErr` which is NOT stack dependent.
+ // This will cause us to incompletely cache a stack-dependent trait
+ // result as `EvaluatedToErr`.
+ Ok(EvaluatedToErr) => Ok(None),
+ Ok(eval) => {
Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
}
- Ok(_) => Ok(None),
Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)),
Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))),
}) |
This has probably failed since forever -- this example only fails since 1.49 which is when we started to enforce supertrait bounds hold (#73905) for object built-in candidates, but I wouldn't be surprised if you could construct an example which fails for even longer. |
To clarify this a bit and to make sure I understand it correctly, the underlying issue here is the following afaict:
when first evaluating |
I expect this to also affect
|
… r=estebank Make sure to insert `Sized` bound first into clauses list rust-lang#120323 made it so that we don't insert an implicit `Sized` bound whenever we see an *explicit* `Sized` bound. However, since the code that inserts implicit sized bounds puts the bound as the *first* in the list, that means that it had the **side-effect** of possibly meaning we check `Sized` *after* checking other trait bounds. If those trait bounds result in ambiguity or overflow or something, it may change how we winnow candidates. (**edit: SEE** rust-lang#123303) This is likely the cause for the regression in rust-lang#123279 (comment), since the impl... ```rust impl<T: Job + Sized> AsJob for T { // <----- changing this to `Sized + Job` or just `Job` (which turns into `Sized + Job`) will FIX the issue. } ``` ...looks incredibly suspicious. Fixes [after beta-backport] rust-lang#123279. Alternative is to revert rust-lang#120323. I don't have a strong opinion about this, but think it may be nice to keep the diagnostic changes around.
… r=estebank Make sure to insert `Sized` bound first into clauses list rust-lang#120323 made it so that we don't insert an implicit `Sized` bound whenever we see an *explicit* `Sized` bound. However, since the code that inserts implicit sized bounds puts the bound as the *first* in the list, that means that it had the **side-effect** of possibly meaning we check `Sized` *after* checking other trait bounds. If those trait bounds result in ambiguity or overflow or something, it may change how we winnow candidates. (**edit: SEE** rust-lang#123303) This is likely the cause for the regression in rust-lang#123279 (comment), since the impl... ```rust impl<T: Job + Sized> AsJob for T { // <----- changing this to `Sized + Job` or just `Job` (which turns into `Sized + Job`) will FIX the issue. } ``` ...looks incredibly suspicious. Fixes [after beta-backport] rust-lang#123279. Alternative is to revert rust-lang#120323. I don't have a strong opinion about this, but think it may be nice to keep the diagnostic changes around.
Rollup merge of rust-lang#123302 - compiler-errors:sized-bound-first, r=estebank Make sure to insert `Sized` bound first into clauses list rust-lang#120323 made it so that we don't insert an implicit `Sized` bound whenever we see an *explicit* `Sized` bound. However, since the code that inserts implicit sized bounds puts the bound as the *first* in the list, that means that it had the **side-effect** of possibly meaning we check `Sized` *after* checking other trait bounds. If those trait bounds result in ambiguity or overflow or something, it may change how we winnow candidates. (**edit: SEE** rust-lang#123303) This is likely the cause for the regression in rust-lang#123279 (comment), since the impl... ```rust impl<T: Job + Sized> AsJob for T { // <----- changing this to `Sized + Job` or just `Job` (which turns into `Sized + Job`) will FIX the issue. } ``` ...looks incredibly suspicious. Fixes [after beta-backport] rust-lang#123279. Alternative is to revert rust-lang#120323. I don't have a strong opinion about this, but think it may be nice to keep the diagnostic changes around.
Trying to prove
dyn Trait: Trait
only after we provedyn Trait: Supertrait
will cause the goal to fail. This seems bad.The text was updated successfully, but these errors were encountered: