diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 5e11932eafc4e4bc8e8ceac0f1991830b44a6ee7..ffe947d209dd605a5b3bbd0572f880684a1c528a 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -543,10 +543,6 @@ fn a_is_expected(&self) -> bool { true } - fn visit_ct_substs(&self) -> bool { - true - } - fn binders( &mut self, a: ty::Binder, @@ -737,6 +733,16 @@ fn consts( } } } + 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 @@ fn a_is_expected(&self) -> bool { true } - fn visit_ct_substs(&self) -> bool { - true - } - fn relate_with_variance>( &mut self, _variance: ty::Variance, @@ -959,6 +961,16 @@ fn consts( } } } + 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 c936c30f456dd93736ea6c2c8010b1cc1106fa4d..bc979b885b4958cdbdf7904165f7506cc8491255 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, @@ -432,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), } } @@ -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 bbfd2183b06e386b04004babe545c1abf4d4bf85..45318ca68fcc586f03da6804d73fbccac8cf0c03 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 @@ fn foo() {} fn main() { Foo::foo(); + //~^ 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 new file mode 100644 index 0000000000000000000000000000000000000000..a82a60696b36b1cb27ffbcf7129cded6e27d559e --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-69654-run-pass.stderr @@ -0,0 +1,15 @@ +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 cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds + | + = note: 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 7e775999ebd10f85e721a9eb8eaf599d38c993d8..b1214b12a14403114b984c7358bbc7e3a2f3c1cd 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 @@ fn foo() {} fn main() { Foo::foo(); + //~^ 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 70af7bf25d8491953a15b8395bc58cf88d60e71d..0ce7640f685774a07c20c5b6b8db7d6854d487d0 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]: 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 cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds + | + = note: 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 f56687ecd9329ec6f4a4714e1c61ffcb1b440f2d..6ded9f13bc4fadacbd90a041e571a7522bdaeb55 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 @@ struct A 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 0000000000000000000000000000000000000000..6830288acc0ad25c49e82e5b1b7fcf36c5a085b1 --- /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 12444ec5312d98b42398cb5099a6e838accb309f..2d00141fbf70bb1393262a56a7d2e1b76a1d6d60 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 0000000000000000000000000000000000000000..9532fc21a31b70aebe4fbb69ee60b18f84c2627c --- /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 187e27382fcf29794c2009d0cd822849efabf7ab..2e306f8c4c88fd46eb1784c962b10d3df9384aa7 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 0000000000000000000000000000000000000000..2551d68f9747499f22da42dfc54f41dc6c29b647 --- /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 8e42ceb6d70e90bbdb9b813c51d4999a501aa1dd..9c7f5ab91edb13298a6a868b4909ae6f201e6fdf 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 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 0000000000000000000000000000000000000000..5685eedbdeca82b205fff2130f46f69612e52568 --- /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`.