about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs19
-rw-r--r--src/test/ui/traits/issue-90662-projection-caching.rs34
2 files changed, 35 insertions, 18 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 490e35d34f2..23f615a9618 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -10,7 +10,6 @@ use super::PredicateObligation;
 use super::Selection;
 use super::SelectionContext;
 use super::SelectionError;
-use super::TraitQueryMode;
 use super::{
     ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
     ImplSourceGeneratorData, ImplSourcePointeeData, ImplSourceUserDefinedData,
@@ -946,27 +945,11 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
             };
 
             let mut deduped: SsoHashSet<_> = Default::default();
-            let mut canonical =
-                SelectionContext::with_query_mode(selcx.infcx(), TraitQueryMode::Canonical);
-
             result.obligations.drain_filter(|projected_obligation| {
                 if !deduped.insert(projected_obligation.clone()) {
                     return true;
                 }
-                // If any global obligations always apply, considering regions, then we don't
-                // need to include them. The `is_global` check rules out inference variables,
-                // so there's no need for the caller of `opt_normalize_projection_type`
-                // to evaluate them.
-                // Note that we do *not* discard obligations that evaluate to
-                // `EvaluatedtoOkModuloRegions`. Evaluating these obligations
-                // inside of a query (e.g. `evaluate_obligation`) can change
-                // the result to `EvaluatedToOkModuloRegions`, while an
-                // `EvaluatedToOk` obligation will never change the result.
-                // See #85360 for more details
-                projected_obligation.is_global(canonical.tcx())
-                    && canonical
-                        .evaluate_root_obligation(projected_obligation)
-                        .map_or(false, |res| res.must_apply_considering_regions())
+                false
             });
 
             if use_cache {
diff --git a/src/test/ui/traits/issue-90662-projection-caching.rs b/src/test/ui/traits/issue-90662-projection-caching.rs
new file mode 100644
index 00000000000..879f30071bf
--- /dev/null
+++ b/src/test/ui/traits/issue-90662-projection-caching.rs
@@ -0,0 +1,34 @@
+// check-pass
+
+// Regression test for issue #90662
+// Tests that projection caching does not cause a spurious error
+
+trait HasProvider<T: ?Sized> {}
+trait Provider<M> {
+    type Interface: ?Sized;
+}
+
+trait Repository {}
+trait Service {}
+
+struct DbConnection;
+impl<M> Provider<M> for DbConnection {
+    type Interface = DbConnection;
+}
+
+struct RepositoryImpl;
+impl<M: HasProvider<DbConnection>> Provider<M> for RepositoryImpl {
+    type Interface = dyn Repository;
+}
+
+struct ServiceImpl;
+impl<M: HasProvider<dyn Repository>> Provider<M> for ServiceImpl {
+    type Interface = dyn Service;
+}
+
+struct TestModule;
+impl HasProvider<<DbConnection as Provider<Self>>::Interface> for TestModule {}
+impl HasProvider<<RepositoryImpl as Provider<Self>>::Interface> for TestModule {}
+impl HasProvider<<ServiceImpl as Provider<Self>>::Interface> for TestModule {}
+
+fn main() {}