From 42150fb8a12cae86ebee3a7734c2d14ed6b1d0a8 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 24 Jan 2021 20:08:12 +0100 Subject: [PATCH 1/2] combine: stop eagerly evaluating consts --- compiler/rustc_infer/src/infer/combine.rs | 28 +++++++++++++------ compiler/rustc_middle/src/ty/relate.rs | 11 +------- .../issues/issue-69654-run-pass.rs | 2 +- .../issues/issue-69654-run-pass.stderr | 15 ++++++++++ .../ui/const-generics/issues/issue-69654.rs | 1 + .../const-generics/issues/issue-69654.stderr | 17 +++++++++-- .../occurs-check/unused-substs-1.rs | 3 +- .../occurs-check/unused-substs-1.stderr | 17 +++++++++++ .../occurs-check/unused-substs-2.rs | 3 +- .../occurs-check/unused-substs-2.stderr | 9 ++++++ .../occurs-check/unused-substs-3.rs | 3 +- .../occurs-check/unused-substs-3.stderr | 12 ++++++++ .../occurs-check/unused-substs-4.rs | 3 +- .../occurs-check/unused-substs-4.stderr | 9 ++++++ 14 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 src/test/ui/const-generics/issues/issue-69654-run-pass.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-1.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-2.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-3.stderr create mode 100644 src/test/ui/const-generics/occurs-check/unused-substs-4.stderr diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 5e11932eafc4e..ffe947d209dd6 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -543,10 +543,6 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { true } - fn visit_ct_substs(&self) -> bool { - true - } - fn binders( &mut self, a: ty::Binder, @@ -737,6 +733,16 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> { } } } + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if self.tcx().lazy_normalization() => + { + assert_eq!(promoted, None); + let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?; + Ok(self.tcx().mk_const(ty::Const { + ty: c.ty, + val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }), + })) + } _ => relate::super_relate_consts(self, c, c), } } @@ -822,10 +828,6 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { true } - fn visit_ct_substs(&self) -> bool { - true - } - fn relate_with_variance>( &mut self, _variance: ty::Variance, @@ -959,6 +961,16 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { } } } + ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if self.tcx().lazy_normalization() => + { + assert_eq!(promoted, None); + let substs = self.relate_with_variance(ty::Variance::Invariant, substs, substs)?; + Ok(self.tcx().mk_const(ty::Const { + ty: c.ty, + val: ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }), + })) + } _ => relate::super_relate_consts(self, c, c), } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index c936c30f456dd..32a713beef85d 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -33,15 +33,6 @@ pub trait TypeRelation<'tcx>: Sized { /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; - /// Whether we should look into the substs of unevaluated constants - /// even if `feature(const_evaluatable_checked)` is active. - /// - /// This is needed in `combine` to prevent accidentially creating - /// infinite types as we abuse `TypeRelation` to walk a type there. - fn visit_ct_substs(&self) -> bool { - false - } - fn with_cause(&mut self, _cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, @@ -532,7 +523,7 @@ pub fn super_relate_consts>( } (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) - if tcx.features().const_evaluatable_checked && !relation.visit_ct_substs() => + if tcx.features().const_evaluatable_checked => { tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs))) } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs index bbfd2183b06e3..8c0398e8a13ea 100644 --- a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs @@ -1,4 +1,3 @@ -// run-pass #![feature(const_generics)] #![allow(incomplete_features, unused_braces)] @@ -15,4 +14,5 @@ where fn main() { Foo::foo(); + //~^ ERROR no function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr new file mode 100644 index 0000000000000..a95cc0f2a1c32 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr @@ -0,0 +1,15 @@ +error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope + --> $DIR/issue-69654-run-pass.rs:16:10 + | +LL | struct Foo {} + | -------------------------- function or associated item `foo` not found for this +... +LL | Foo::foo(); + | ^^^ function or associated item not found in `Foo<{_: usize}>` + | + = note: the method `foo` exists but the following trait bounds were not satisfied: + `[u8; _]: Bar<[(); _]>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/const-generics/issues/issue-69654.rs b/src/test/ui/const-generics/issues/issue-69654.rs index 7e775999ebd10..38fca98ad4f06 100644 --- a/src/test/ui/const-generics/issues/issue-69654.rs +++ b/src/test/ui/const-generics/issues/issue-69654.rs @@ -15,4 +15,5 @@ where fn main() { Foo::foo(); + //~^ ERROR no function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654.stderr b/src/test/ui/const-generics/issues/issue-69654.stderr index 70af7bf25d849..69cd0806fcd42 100644 --- a/src/test/ui/const-generics/issues/issue-69654.stderr +++ b/src/test/ui/const-generics/issues/issue-69654.stderr @@ -4,6 +4,19 @@ error[E0423]: expected value, found type parameter `T` LL | impl Bar for [u8; T] {} | ^ not a value -error: aborting due to previous error +error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope + --> $DIR/issue-69654.rs:17:10 + | +LL | struct Foo {} + | -------------------------- function or associated item `foo` not found for this +... +LL | Foo::foo(); + | ^^^ function or associated item not found in `Foo<{_: usize}>` + | + = note: the method `foo` exists but the following trait bounds were not satisfied: + `[u8; _]: Bar<[(); _]>` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0423`. +Some errors have detailed explanations: E0423, E0599. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.rs b/src/test/ui/const-generics/occurs-check/unused-substs-1.rs index f56687ecd9329..6ded9f13bc4fa 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-1.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.rs @@ -1,4 +1,3 @@ -// build-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -10,5 +9,5 @@ where A: Bar; fn main() { - let _ = A; + let _ = A; //~ERROR the trait bound } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr new file mode 100644 index 0000000000000..6830288acc0ad --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `A<{_: usize}>: Bar<{_: usize}>` is not satisfied + --> $DIR/unused-substs-1.rs:12:13 + | +LL | / struct A +LL | | where +LL | | A: Bar; + | |_________________- required by `A` +... +LL | let _ = A; + | ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>` + | + = help: the following implementations were found: + as Bar> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-2.rs b/src/test/ui/const-generics/occurs-check/unused-substs-2.rs index 12444ec5312d9..2d00141fbf70b 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-2.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-2.rs @@ -1,4 +1,3 @@ -// check-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -24,4 +23,6 @@ fn main() { // `t` is `ty::Infer(TyVar(_#1t))` // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs t = foo; + //~^ ERROR mismatched types + //~| NOTE cyclic type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr new file mode 100644 index 0000000000000..9532fc21a31b7 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-2.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-2.rs:25:9 + | +LL | t = foo; + | ^^^ cyclic type of infinite size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.rs b/src/test/ui/const-generics/occurs-check/unused-substs-3.rs index 187e27382fcf2..2e306f8c4c88f 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-3.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.rs @@ -1,4 +1,3 @@ -// check-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -15,4 +14,6 @@ fn main() { // `t` is `ty::Infer(TyVar(_#1t))` // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs t = foo; + //~^ ERROR mismatched types + //~| NOTE cyclic type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr new file mode 100644 index 0000000000000..2551d68f97474 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-3.rs:16:9 + | +LL | t = foo; + | ^^^ + | | + | cyclic type of infinite size + | help: try using a conversion method: `foo.to_vec()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-4.rs b/src/test/ui/const-generics/occurs-check/unused-substs-4.rs index 8e42ceb6d70e9..9c7f5ab91edb1 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-4.rs +++ b/src/test/ui/const-generics/occurs-check/unused-substs-4.rs @@ -1,4 +1,3 @@ -// build-pass #![feature(const_generics)] #![allow(incomplete_features)] @@ -8,5 +7,5 @@ fn bind(value: [u8; N]) -> [u8; 3 + 4] { fn main() { let mut arr = Default::default(); - arr = bind(arr); + arr = bind(arr); //~ ERROR mismatched type } diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr new file mode 100644 index 0000000000000..5685eedbdeca8 --- /dev/null +++ b/src/test/ui/const-generics/occurs-check/unused-substs-4.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/unused-substs-4.rs:10:11 + | +LL | arr = bind(arr); + | ^^^^^^^^^ encountered a self-referencing constant + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From e461dddf5828d729b872e27d1a7a7335437ce413 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 15 Mar 2021 23:10:24 +0100 Subject: [PATCH 2/2] update tests --- compiler/rustc_middle/src/ty/relate.rs | 6 +++--- src/test/ui/const-generics/issues/issue-69654-run-pass.rs | 2 +- .../ui/const-generics/issues/issue-69654-run-pass.stderr | 6 +++--- src/test/ui/const-generics/issues/issue-69654.rs | 2 +- src/test/ui/const-generics/issues/issue-69654.stderr | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 32a713beef85d..bc979b885b495 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -423,9 +423,9 @@ pub fn super_relate_tys>( let sz_a = sz_a.try_eval_usize(tcx, relation.param_env()); let sz_b = sz_b.try_eval_usize(tcx, relation.param_env()); match (sz_a, sz_b) { - (Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize( - expected_found(relation, sz_a_val, sz_b_val), - )), + (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err( + TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)), + ), _ => Err(err), } } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs index 8c0398e8a13ea..45318ca68fcc5 100644 --- a/src/test/ui/const-generics/issues/issue-69654-run-pass.rs +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.rs @@ -14,5 +14,5 @@ where fn main() { Foo::foo(); - //~^ ERROR no function or associated item + //~^ ERROR the function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr index a95cc0f2a1c32..a82a60696b36b 100644 --- a/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr @@ -1,13 +1,13 @@ -error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope +error[E0599]: the function or associated item `foo` exists for struct `Foo<{_: usize}>`, but its trait bounds were not satisfied --> $DIR/issue-69654-run-pass.rs:16:10 | LL | struct Foo {} | -------------------------- function or associated item `foo` not found for this ... LL | Foo::foo(); - | ^^^ function or associated item not found in `Foo<{_: usize}>` + | ^^^ function or associated item cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds | - = note: the method `foo` exists but the following trait bounds were not satisfied: + = note: the following trait bounds were not satisfied: `[u8; _]: Bar<[(); _]>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/issues/issue-69654.rs b/src/test/ui/const-generics/issues/issue-69654.rs index 38fca98ad4f06..b1214b12a1440 100644 --- a/src/test/ui/const-generics/issues/issue-69654.rs +++ b/src/test/ui/const-generics/issues/issue-69654.rs @@ -15,5 +15,5 @@ where fn main() { Foo::foo(); - //~^ ERROR no function or associated item + //~^ ERROR the function or associated item } diff --git a/src/test/ui/const-generics/issues/issue-69654.stderr b/src/test/ui/const-generics/issues/issue-69654.stderr index 69cd0806fcd42..0ce7640f68577 100644 --- a/src/test/ui/const-generics/issues/issue-69654.stderr +++ b/src/test/ui/const-generics/issues/issue-69654.stderr @@ -4,16 +4,16 @@ error[E0423]: expected value, found type parameter `T` LL | impl Bar for [u8; T] {} | ^ not a value -error[E0599]: no function or associated item named `foo` found for struct `Foo<{_: usize}>` in the current scope +error[E0599]: the function or associated item `foo` exists for struct `Foo<{_: usize}>`, but its trait bounds were not satisfied --> $DIR/issue-69654.rs:17:10 | LL | struct Foo {} | -------------------------- function or associated item `foo` not found for this ... LL | Foo::foo(); - | ^^^ function or associated item not found in `Foo<{_: usize}>` + | ^^^ function or associated item cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds | - = note: the method `foo` exists but the following trait bounds were not satisfied: + = note: the following trait bounds were not satisfied: `[u8; _]: Bar<[(); _]>` error: aborting due to 2 previous errors