-Znext-solver use the trait object's own bounds instead of goal when considering builtin object bounds#152859
-Znext-solver use the trait object's own bounds instead of goal when considering builtin object bounds#152859ShoyuVanilla wants to merge 2 commits intorust-lang:mainfrom
-Znext-solver use the trait object's own bounds instead of goal when considering builtin object bounds#152859Conversation
4a25656 to
0f257f0
Compare
|
hmm, thinking about this, given pub trait Trait<T> {
type Assoc;
}
pub trait Foo {
type FooAssoc;
}
pub struct Wrap<U: Foo>(<dyn Trait<i32, Assoc = i64> as Trait<U::FooAssoc>>::Assoc)
where
dyn Trait<i32, Assoc = i64>: Trait<U::FooAssoc>;we're checking This builtin impl should be impl Trait<i32> for dyn Trait<i32, Assoc = i64>
where
i32: Sized,
// we eagerly replace `<Self as Trait<i32>>::Assoc` with `i64` when
// emitting the impl to avoid non-productive cycles.
<Self as Trait<i32>>::Assoc: Sized,
{
type Assoc = i64;
}The builtin impl only applies here if I think the bug is here We should compute the where-clauses of the builtin impl using only the object type, not the goal we actually have to prove. This builtin impl won't be applicable for |
…iltin object bounds
0f257f0 to
4d3a012
Compare
-Znext-solver Remove a problematic assertion from probing object bound candidates-Znext-solver se the trait object's own bounds instead of goal when considering builtin object bounds
|
That looks correct. I was being too narrow in my reasoning about the cause 😅 |
This comment has been minimized.
This comment has been minimized.
| @@ -83,14 +83,21 @@ where | |||
| assumption: I::Clause, | |||
| ) -> Result<Candidate<I>, NoSolution> { | |||
| Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { | |||
| ecx.try_evaluate_added_goals()?; | |||
There was a problem hiding this comment.
rust/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
Lines 192 to 194 in 1eb36c6
We equate the goal with the assumption before entering this closure in the above lines.
However, that eq relationship does not actually hold in the problematic cases from the linked issues.
Because this additional goal is introduced through that equality, the ICE still occurs even if we use the trait ref from the trait object (instead of the goal's trait ref) when calling predicates_for_object_candidate.
Those predicates are evaluated here, in projection_may_match:
I think short-circuiting candidates for which the equality cannot hold, before entering the remaining probing, would be harmless and prevent the ICE.
In fact, adding just that early check is enough to fix the ICE in the linked issues.
But I think using trait object's own bounds instead of goal's is correct, so changed the follwing lines as well.
| @@ -425,7 +425,7 @@ where | |||
| } | |||
| } | |||
| ty::Dynamic(tt, ..) => { | |||
| let principal = tt.principal().map(|p| p.def_id()); | |||
| let principal = tt.principal_def_id(); | |||
There was a problem hiding this comment.
This change is irrelevant of the issue but seems trivial 😅
-Znext-solver se the trait object's own bounds instead of goal when considering builtin object bounds-Znext-solver use the trait object's own bounds instead of goal when considering builtin object bounds
|
Hmm, the CI failure looks sus. Am I doing somewhat very incorrect thingy? |
Fixes #152789 and fixes #151329
r? lcnr