about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs22
-rw-r--r--tests/ui/associated-inherent-types/variance-computation-requires-equality.rs20
-rw-r--r--tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr11
3 files changed, 52 insertions, 1 deletions
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index 18822351f4f..86a24eef7f5 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -5,7 +5,9 @@ use crate::infer::{
 };
 use crate::traits::{Obligation, PredicateObligations};
 
-use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::relate::{
+    relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation,
+};
 use rustc_middle::ty::TyVar;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
@@ -36,6 +38,24 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
         self.fields.infcx.tcx
     }
 
+    fn relate_item_args(
+        &mut self,
+        item_def_id: rustc_hir::def_id::DefId,
+        a_arg: ty::GenericArgsRef<'tcx>,
+        b_arg: ty::GenericArgsRef<'tcx>,
+    ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
+        if self.ambient_variance == ty::Variance::Invariant {
+            // Avoid fetching the variance if we are in an invariant
+            // context; no need, and it can induce dependency cycles
+            // (e.g., #41849).
+            relate_args_invariantly(self, a_arg, b_arg)
+        } else {
+            let tcx = self.tcx();
+            let opt_variances = tcx.variances_of(item_def_id);
+            relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, false)
+        }
+    }
+
     fn relate_with_variance<T: Relate<'tcx>>(
         &mut self,
         variance: ty::Variance,
diff --git a/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs b/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs
new file mode 100644
index 00000000000..3f726792b4a
--- /dev/null
+++ b/tests/ui/associated-inherent-types/variance-computation-requires-equality.rs
@@ -0,0 +1,20 @@
+//@ check-pass
+
+#![feature(inherent_associated_types)]
+//~^ WARN the feature `inherent_associated_types` is incomplete
+
+struct D<T> {
+  a: T
+}
+
+impl<T: Default> D<T> {
+    type Item = T;
+
+    fn next() -> Self::Item {
+        Self::Item::default()
+    }
+}
+
+
+fn main() {
+}
diff --git a/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr b/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr
new file mode 100644
index 00000000000..93064f551ab
--- /dev/null
+++ b/tests/ui/associated-inherent-types/variance-computation-requires-equality.stderr
@@ -0,0 +1,11 @@
+warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/variance-computation-requires-equality.rs:3:12
+   |
+LL | #![feature(inherent_associated_types)]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+