diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2021-10-30 14:37:02 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-30 14:37:02 +0200 |
| commit | 88e0bea7ca8966c5ee57915cf5afa128168595b2 (patch) | |
| tree | 80c547167275c0298df4f2c20823d9ef5d26eb08 | |
| parent | b531364a1a8af28ad78e52cf0a9bf657640aa17c (diff) | |
| parent | a39c50b64caca297b3e98ebf7cdb68c96ca0f3c1 (diff) | |
| download | rust-88e0bea7ca8966c5ee57915cf5afa128168595b2.tar.gz rust-88e0bea7ca8966c5ee57915cf5afa128168595b2.zip | |
Rollup merge of #90395 - b-naber:const-expr-type-relation, r=oli-obk
Restrict liveness of mutable borrow of inner infcx in ConstInferUnifier::consts Fixes https://github.com/rust-lang/rust/issues/89304 r? ``@oli-obk``
| -rw-r--r-- | compiler/rustc_infer/src/infer/combine.rs | 29 | ||||
| -rw-r--r-- | src/test/ui/const-generics/issues/issue-89304.rs | 20 |
2 files changed, 40 insertions, 9 deletions
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 3f54247ecef..09bfb3290f4 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 00000000000..d544d637cc4 --- /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<const T: usize> { val: i64 } + +impl<const T: usize> From<GenericStruct<T>> for GenericStruct<{T + 1}> { + fn from(other: GenericStruct<T>) -> Self { + Self { val: other.val } + } +} + +impl<const T: usize> From<GenericStruct<{T + 1}>> for GenericStruct<T> { + fn from(other: GenericStruct<{T + 1}>) -> Self { + Self { val: other.val } + } +} + +fn main() {} |
