Skip to content

Commit eee09ec

Browse files
committed
Remove 'speculative evaluation' of predicates
Performing 'speculative evaluation' introduces caching bugs that cannot be fixed without invasive changes to projection. Hopefully, we can win back most of the performance lost by re-adding 'cache completion' Fixes rust-lang#90662
1 parent 34dc0d0 commit eee09ec

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

Diff for: compiler/rustc_trait_selection/src/traits/project.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use super::PredicateObligation;
1010
use super::Selection;
1111
use super::SelectionContext;
1212
use super::SelectionError;
13-
use super::TraitQueryMode;
1413
use super::{
1514
ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
1615
ImplSourceGeneratorData, ImplSourcePointeeData, ImplSourceUserDefinedData,
@@ -946,27 +945,11 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
946945
};
947946

948947
let mut deduped: SsoHashSet<_> = Default::default();
949-
let mut canonical =
950-
SelectionContext::with_query_mode(selcx.infcx(), TraitQueryMode::Canonical);
951-
952948
result.obligations.drain_filter(|projected_obligation| {
953949
if !deduped.insert(projected_obligation.clone()) {
954950
return true;
955951
}
956-
// If any global obligations always apply, considering regions, then we don't
957-
// need to include them. The `is_global` check rules out inference variables,
958-
// so there's no need for the caller of `opt_normalize_projection_type`
959-
// to evaluate them.
960-
// Note that we do *not* discard obligations that evaluate to
961-
// `EvaluatedtoOkModuloRegions`. Evaluating these obligations
962-
// inside of a query (e.g. `evaluate_obligation`) can change
963-
// the result to `EvaluatedToOkModuloRegions`, while an
964-
// `EvaluatedToOk` obligation will never change the result.
965-
// See #85360 for more details
966-
projected_obligation.is_global(canonical.tcx())
967-
&& canonical
968-
.evaluate_root_obligation(projected_obligation)
969-
.map_or(false, |res| res.must_apply_considering_regions())
952+
false
970953
});
971954

972955
if use_cache {

Diff for: src/test/ui/traits/issue-90662-projection-caching.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// check-pass
2+
3+
// Regression test for issue #90662
4+
// Tests that projection caching does not cause a spurious error
5+
6+
trait HasProvider<T: ?Sized> {}
7+
trait Provider<M> {
8+
type Interface: ?Sized;
9+
}
10+
11+
trait Repository {}
12+
trait Service {}
13+
14+
struct DbConnection;
15+
impl<M> Provider<M> for DbConnection {
16+
type Interface = DbConnection;
17+
}
18+
19+
struct RepositoryImpl;
20+
impl<M: HasProvider<DbConnection>> Provider<M> for RepositoryImpl {
21+
type Interface = dyn Repository;
22+
}
23+
24+
struct ServiceImpl;
25+
impl<M: HasProvider<dyn Repository>> Provider<M> for ServiceImpl {
26+
type Interface = dyn Service;
27+
}
28+
29+
struct TestModule;
30+
impl HasProvider<<DbConnection as Provider<Self>>::Interface> for TestModule {}
31+
impl HasProvider<<RepositoryImpl as Provider<Self>>::Interface> for TestModule {}
32+
impl HasProvider<<ServiceImpl as Provider<Self>>::Interface> for TestModule {}
33+
34+
fn main() {}

0 commit comments

Comments
 (0)