Fix exponential projection complexity on nested types #48296
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
Here are some self-reminders. |
@@ -818,55 +822,74 @@ fn project_type<'cx, 'gcx, 'tcx>( | |||
&obligation_trait_ref, | |||
&mut candidates); | |||
|
|||
let decide_commit = |candidates: &mut ProjectionTyCandidateSet<'tcx>| { |
ishitatsuyuki
Feb 17, 2018
Author
Contributor
I have no way but to reorder this before the error handling. It looks non intuitive.
I have no way but to reorder this before the error handling. It looks non intuitive.
}); | ||
debug!("resulting candidate set: {:?}", candidates.vec); | ||
if candidates.vec.len() != 1 { | ||
candidates.ambiguous = true; |
ishitatsuyuki
Feb 17, 2018
Author
Contributor
This is nearly a hack.
This is nearly a hack.
} | ||
}; | ||
|
||
match vtable { | ||
match vtable.clone() { |
ishitatsuyuki
Feb 17, 2018
Author
Contributor
This copy can be avoided.
This copy can be avoided.
The other part of the blowup (typeck related) is yet to be solved, but I think the code is ready for a round of review. I have removed whitespace changes and clarified the description. |
@kennytm A reminder for you to change the review labels. |
@bors try Let’s do a perf check while we’re waiting for review :) |
[wip] Fix exponential projection complexity on nested types This implements solution 1 from #38528 (comment). The code quality is currently extremely poor, but we can improve them during review. Based on #48315. Needs changelog. Noticable improvement on compile time is expected. Fix #38528 (in progress, another exponential blowup exist) Close #39684 Close #43757
@ishitatsuyuki please remove the |
Well, I'm currently tackling another part of the exponential issue (so this is WIP), but I need comments on improving the code organization. |
|
By deduplicating the obligations the issue is completely resolved. I'm not sure if this approach is the best way though, and I copied the dumb deduplication becuase I didn't want to implement Ord everywhere. I will fix them later. |
@kennytm I need another try. |
@bors try |
Please change the label... |
Looks great =) |
} else { | ||
Err(()) | ||
} | ||
}); |
nikomatsakis
Feb 22, 2018
Contributor
I like the change to push errors into the candidate set. This is less confusing this way.
I like the change to push errors into the candidate set. This is less confusing this way.
ishitatsuyuki
Feb 22, 2018
Author
Contributor
I'm not sure if I understand. I already handle SelectionError above, and these Ok and Err is the return value to commit_if_ok
.
I'm not sure if I understand. I already handle SelectionError above, and these Ok and Err is the return value to commit_if_ok
.
// unknown. What we know is that the deduplication avoids exponential | ||
// amount of predicates being propogated when processing deeply nested | ||
// types. | ||
let mut seen = FxHashSet(); |
nikomatsakis
Feb 22, 2018
Contributor
Oh, it seems like duplicates could come from many sources -- in particular, normalization might introduce the same obligation a few times.
Oh, it seems like duplicates could come from many sources -- in particular, normalization might introduce the same obligation a few times.
@bors r+ @ishitatsuyuki -- it'd be great to add at least one of these exponential blow-up cases to the perf website so we can monitor for regressions. Perhaps @Mark-Simulacrum can walk you through it. |
|
…sakis Fix exponential projection complexity on nested types This implements solution 1 from rust-lang#38528 (comment). The code quality is currently extremely poor, but we can improve them during review. Blocking issues: - we probably don't want a quadratic deduplication for obligations. - is there an alternative to deduplication? Based on rust-lang#48315. Needs changelog. Noticable improvement on compile time is expected. Fix rust-lang#38528 Close rust-lang#39684 Close rust-lang#43757
This effectively reverts rust-lang#43546 as it seems that it does affect performance more than the PR has anticipated. This also removes the deduplication code from rust-lang#48296 as duplications were primarily coming from rust-lang#43546 and after removing that code it probably doesn't worth paying the cost of using a hash map.
This effectively reverts rust-lang#43546 as it seems that it does affect performance more than the PR has anticipated. This also removes the deduplication code from rust-lang#48296 as duplications were primarily coming from rust-lang#43546 and after removing that code it probably doesn't worth paying the cost of using a hash map.
Revert rust-lang#43546 This effectively reverts rust-lang#43546 as it seems that it does affect performance more than the PR has anticipated. This also removes the deduplication code from rust-lang#48296 as duplications were primarily coming from rust-lang#43546 and after removing that code it probably doesn't worth paying the cost of using a hash map. Interestingly, the regression tests introduced in rust-lang#43546 didn't fail after reverting, but some other tests had breakage. For now I just applied `--bless`, but I'd like to figure out if it could be a problem later on. Preliminary perf results confirms that we no longer need deduplication to avoid exponential behavior.  This PR will be draft until I figure out the potential breakage. r? `@ghost` Need a perf run. A crater run will help as well to identify potential breakage.
This effectively reverts rust-lang#43546 as it seems that it does affect performance more than the PR has anticipated. Follow-up changes from rust-lang#44269 are also reverted. This also removes the deduplication code from rust-lang#48296 as duplications were primarily coming from rust-lang#43546 and after removing that code it probably doesn't worth paying the cost of using a hash map.
This effectively reverts rust-lang#43546 as it seems that it does affect performance more than the PR has anticipated. Follow-up changes from rust-lang#44269 are also reverted. This also removes the deduplication code from rust-lang#48296 as duplications were primarily coming from rust-lang#43546 and after removing that code it probably doesn't worth paying the cost of using a hash map.
This effectively reverts rust-lang#43546 as it seems that it does affect performance more than the PR has anticipated. Follow-up changes from rust-lang#44269 are also reverted. This also removes the deduplication code from rust-lang#48296 as duplications were primarily coming from rust-lang#43546 and after removing that code it probably doesn't worth paying the cost of using a hash map.
This implements solution 1 from #38528 (comment).
The code quality was extremely poor, but it has improved during review.
Blocking issues:
Based on #48315.
Needs changelog. Noticable improvement on compile time is expected.
Fix #38528
Close #39684
Close #43757