diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 3f54247ecef21..09bfb3290f4ca 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -866,6 +866,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?)) } + #[tracing::instrument(level = "debug", skip(self))] fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { debug_assert_eq!(t, _t); debug!("ConstInferUnifier: t={:?}", t); @@ -941,6 +942,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } + #[tracing::instrument(level = "debug", skip(self))] fn consts( &mut self, c: &'tcx ty::Const<'tcx>, @@ -951,29 +953,38 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { match c.val { ty::ConstKind::Infer(InferConst::Var(vid)) => { - let mut inner = self.infcx.inner.borrow_mut(); - let variable_table = &mut inner.const_unification_table(); - // Check if the current unification would end up // unifying `target_vid` with a const which contains // an inference variable which is unioned with `target_vid`. // // Not doing so can easily result in stack overflows. - if variable_table.unioned(self.target_vid, vid) { + if self + .infcx + .inner + .borrow_mut() + .const_unification_table() + .unioned(self.target_vid, vid) + { return Err(TypeError::CyclicConst(c)); } - let var_value = variable_table.probe_value(vid); + let var_value = + self.infcx.inner.borrow_mut().const_unification_table().probe_value(vid); match var_value.val { ConstVariableValue::Known { value: u } => self.consts(u, u), ConstVariableValue::Unknown { universe } => { if self.for_universe.can_name(universe) { Ok(c) } else { - let new_var_id = variable_table.new_key(ConstVarValue { - origin: var_value.origin, - val: ConstVariableValue::Unknown { universe: self.for_universe }, - }); + let new_var_id = + self.infcx.inner.borrow_mut().const_unification_table().new_key( + ConstVarValue { + origin: var_value.origin, + val: ConstVariableValue::Unknown { + universe: self.for_universe, + }, + }, + ); Ok(self.tcx().mk_const_var(new_var_id, c.ty)) } } diff --git a/src/test/ui/const-generics/issues/issue-89304.rs b/src/test/ui/const-generics/issues/issue-89304.rs new file mode 100644 index 0000000000000..d544d637cc490 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-89304.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +struct GenericStruct { val: i64 } + +impl From> for GenericStruct<{T + 1}> { + fn from(other: GenericStruct) -> Self { + Self { val: other.val } + } +} + +impl From> for GenericStruct { + fn from(other: GenericStruct<{T + 1}>) -> Self { + Self { val: other.val } + } +} + +fn main() {}