1
Fork 0

Rollup merge of #81351 - lcnr:big-money-big-prices, r=oli-obk

combine: stop eagerly evaluating consts

`super_relate_consts` eagerly evaluates constants which doesn't seem too great.

I now also finally understand why all of the unused substs test passed. The reason being
that we just evaluated the constants in `super_relate_consts` 😆

While this change isn't strictly necessary as evaluating consts here doesn't hurt, it still feels a lot cleaner to do it this way

r? `@oli-obk` `@nikomatsakis`
This commit is contained in:
Dylan DPC 2021-03-27 20:37:04 +01:00 committed by GitHub
commit 520c9a25df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 109 additions and 30 deletions

View file

@ -543,10 +543,6 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
true true
} }
fn visit_ct_substs(&self) -> bool {
true
}
fn binders<T>( fn binders<T>(
&mut self, &mut self,
a: ty::Binder<T>, a: ty::Binder<T>,
@ -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), _ => relate::super_relate_consts(self, c, c),
} }
} }
@ -822,10 +828,6 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
true true
} }
fn visit_ct_substs(&self) -> bool {
true
}
fn relate_with_variance<T: Relate<'tcx>>( fn relate_with_variance<T: Relate<'tcx>>(
&mut self, &mut self,
_variance: ty::Variance, _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), _ => relate::super_relate_consts(self, c, c),
} }
} }

View file

@ -33,15 +33,6 @@ pub trait TypeRelation<'tcx>: Sized {
/// relation. Just affects error messages. /// relation. Just affects error messages.
fn a_is_expected(&self) -> bool; 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<F, R>(&mut self, _cause: Cause, f: F) -> R fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R
where where
F: FnOnce(&mut Self) -> R, F: FnOnce(&mut Self) -> R,
@ -432,9 +423,9 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
let sz_a = sz_a.try_eval_usize(tcx, relation.param_env()); let sz_a = sz_a.try_eval_usize(tcx, relation.param_env());
let sz_b = sz_b.try_eval_usize(tcx, relation.param_env()); let sz_b = sz_b.try_eval_usize(tcx, relation.param_env());
match (sz_a, sz_b) { match (sz_a, sz_b) {
(Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize( (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err(
expected_found(relation, sz_a_val, sz_b_val), TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)),
)), ),
_ => Err(err), _ => Err(err),
} }
} }
@ -532,7 +523,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
} }
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) (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))) tcx.try_unify_abstract_consts(((au.def, au.substs), (bu.def, bu.substs)))
} }

View file

@ -1,4 +1,3 @@
// run-pass
#![feature(const_generics)] #![feature(const_generics)]
#![allow(incomplete_features, unused_braces)] #![allow(incomplete_features, unused_braces)]
@ -15,4 +14,5 @@ where
fn main() { fn main() {
Foo::foo(); Foo::foo();
//~^ ERROR the function or associated item
} }

View file

@ -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<const N: usize> {}
| -------------------------- 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`.

View file

@ -15,4 +15,5 @@ where
fn main() { fn main() {
Foo::foo(); Foo::foo();
//~^ ERROR the function or associated item
} }

View file

@ -4,6 +4,19 @@ error[E0423]: expected value, found type parameter `T`
LL | impl<T> Bar<T> for [u8; T] {} LL | impl<T> Bar<T> for [u8; T] {}
| ^ not a value | ^ 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<const N: usize> {}
| -------------------------- 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<[(); _]>`
For more information about this error, try `rustc --explain E0423`. error: aborting due to 2 previous errors
Some errors have detailed explanations: E0423, E0599.
For more information about an error, try `rustc --explain E0423`.

View file

@ -1,4 +1,3 @@
// build-pass
#![feature(const_generics)] #![feature(const_generics)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
@ -10,5 +9,5 @@ where
A<N>: Bar<N>; A<N>: Bar<N>;
fn main() { fn main() {
let _ = A; let _ = A; //~ERROR the trait bound
} }

View file

@ -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<const N: usize>
LL | | where
LL | | A<N>: Bar<N>;
| |_________________- required by `A`
...
LL | let _ = A;
| ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>`
|
= help: the following implementations were found:
<A<7_usize> as Bar<N>>
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,4 +1,3 @@
// check-pass
#![feature(const_generics)] #![feature(const_generics)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
@ -24,4 +23,6 @@ fn main() {
// `t` is `ty::Infer(TyVar(_#1t))` // `t` is `ty::Infer(TyVar(_#1t))`
// `foo` contains `ty::Infer(TyVar(_#1t))` in its substs // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs
t = foo; t = foo;
//~^ ERROR mismatched types
//~| NOTE cyclic type
} }

View file

@ -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`.

View file

@ -1,4 +1,3 @@
// check-pass
#![feature(const_generics)] #![feature(const_generics)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
@ -15,4 +14,6 @@ fn main() {
// `t` is `ty::Infer(TyVar(_#1t))` // `t` is `ty::Infer(TyVar(_#1t))`
// `foo` contains `ty::Infer(TyVar(_#1t))` in its substs // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs
t = foo; t = foo;
//~^ ERROR mismatched types
//~| NOTE cyclic type
} }

View file

@ -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`.

View file

@ -1,4 +1,3 @@
// build-pass
#![feature(const_generics)] #![feature(const_generics)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
@ -8,5 +7,5 @@ fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] {
fn main() { fn main() {
let mut arr = Default::default(); let mut arr = Default::default();
arr = bind(arr); arr = bind(arr); //~ ERROR mismatched type
} }

View file

@ -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`.