From 71d75503506880efa89c902465cdcb205d0eb9e5 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 2 Dec 2020 14:33:26 +0100 Subject: [PATCH] const_evaluatable_checked: fix occurs check --- compiler/rustc_infer/src/infer/combine.rs | 16 ++++++++++++++- compiler/rustc_middle/src/ty/relate.rs | 6 +++++- .../occurs-check/unused-substs-5.rs | 20 +++++++++++++++++++ .../occurs-check/unused-substs-5.stderr | 12 +++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-5.rs create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-5.stderr diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 6a1715ef818..594e2c6205f 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -543,6 +543,10 @@ fn a_is_expected(&self) -> bool { true } + fn visit_ct_substs(&self) -> bool { + true + } + fn binders( &mut self, a: ty::Binder, @@ -716,7 +720,10 @@ fn consts( let variable_table = &mut inner.const_unification_table(); let var_value = variable_table.probe_value(vid); match var_value.val { - ConstVariableValue::Known { value: u } => self.relate(u, u), + ConstVariableValue::Known { value: u } => { + drop(inner); + self.relate(u, u) + } ConstVariableValue::Unknown { universe } => { if self.for_universe.can_name(universe) { Ok(c) @@ -815,6 +822,10 @@ fn a_is_expected(&self) -> bool { true } + fn visit_ct_substs(&self) -> bool { + true + } + fn relate_with_variance>( &mut self, _variance: ty::Variance, @@ -870,6 +881,9 @@ fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { } } } + ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => { + Ok(t) + } _ => relate::super_relate_tys(self, t, t), } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index ef5034e218d..80dc7d89d18 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -33,6 +33,10 @@ pub trait TypeRelation<'tcx>: Sized { /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; + fn visit_ct_substs(&self) -> bool { + false + } + fn with_cause(&mut self, _cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, @@ -579,7 +583,7 @@ pub fn super_relate_consts>( ( ty::ConstKind::Unevaluated(a_def, a_substs, None), ty::ConstKind::Unevaluated(b_def, b_substs, None), - ) if tcx.features().const_evaluatable_checked => { + ) if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => { if tcx.try_unify_abstract_consts(((a_def, a_substs), (b_def, b_substs))) { Ok(a.val) } else { diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.rs b/src/test/ui/const-generics/occurs-check/unused-substs-5.rs new file mode 100644 index 00000000000..e5d487d89b9 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.rs @@ -0,0 +1,20 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +// `N + 1` also depends on `T` here even if it doesn't use it. +fn q(_: T) -> [u8; N + 1] { + todo!() +} + +fn supplier() -> T { + todo!() +} + +fn catch_me() where [u8; N + 1]: Default { + let mut x = supplier(); + x = q::<_, N>(x); //~ ERROR mismatched types +} + +fn main() { + catch_me::<3>(); +} diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr new file mode 100644 index 00000000000..239569dab09 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-5.rs:15:9 + | +LL | x = q::<_, N>(x); + | ^^^^^^^^^^^^ + | | + | cyclic type of infinite size + | help: try using a conversion method: `q::<_, N>(x).to_vec()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. -- 2.44.0