diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index 18822351f4f0d..86a24eef7f5bc 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>( &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 0000000000000..3f726792b4a11 --- /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 { + a: T +} + +impl D { + 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 0000000000000..93064f551abdc --- /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 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted +