Skip to content

Commit 2e0a0b4

Browse files
Rollup merge of #78832 - lcnr:const-evaluatable-unevaluated, r=oli-obk
look at assoc ct, check the type of nodes an example where types matter are function objects, see the added test which previously passed. Now does a shallow comparison of unevaluated constants. r? ```@oli-obk```
2 parents 56e0806 + 439171e commit 2e0a0b4

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

+17
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,13 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
512512
block = &self.body.basic_blocks()[next];
513513
} else {
514514
assert_eq!(self.locals[mir::RETURN_PLACE], self.nodes.last().unwrap());
515+
// `AbstractConst`s should not contain any promoteds as they require references which
516+
// are not allowed.
517+
assert!(!self.nodes.iter().any(|n| matches!(
518+
n.node,
519+
Node::Leaf(ty::Const { val: ty::ConstKind::Unevaluated(_, _, Some(_)), ty: _ })
520+
)));
521+
515522
self.nodes[self.locals[mir::RETURN_PLACE]].used = true;
516523
if let Some(&unused) = self.nodes.iter().find(|n| !n.used) {
517524
self.error(Some(unused.span), "dead code")?;
@@ -609,6 +616,10 @@ pub(super) fn try_unify<'tcx>(
609616
(Node::Leaf(a_ct), Node::Leaf(b_ct)) => {
610617
let a_ct = a_ct.subst(tcx, a.substs);
611618
let b_ct = b_ct.subst(tcx, b.substs);
619+
if a_ct.ty != b_ct.ty {
620+
return false;
621+
}
622+
612623
match (a_ct.val, b_ct.val) {
613624
// We can just unify errors with everything to reduce the amount of
614625
// emitted errors here.
@@ -621,6 +632,12 @@ pub(super) fn try_unify<'tcx>(
621632
// we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
622633
// means that we only allow inference variables if they are equal.
623634
(ty::ConstKind::Infer(a_val), ty::ConstKind::Infer(b_val)) => a_val == b_val,
635+
// We may want to instead recurse into unevaluated constants here. That may require some
636+
// care to prevent infinite recursion, so let's just ignore this for now.
637+
(
638+
ty::ConstKind::Unevaluated(a_def, a_substs, None),
639+
ty::ConstKind::Unevaluated(b_def, b_substs, None),
640+
) => a_def == b_def && a_substs == b_substs,
624641
// FIXME(const_evaluatable_checked): We may want to either actually try
625642
// to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like
626643
// this, for now we just return false here.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// run-pass
2+
#![feature(const_generics, const_evaluatable_checked)]
3+
#![allow(incomplete_features)]
4+
5+
pub trait BlockCipher {
6+
const BLOCK_SIZE: usize;
7+
}
8+
9+
struct FooCipher;
10+
impl BlockCipher for FooCipher {
11+
const BLOCK_SIZE: usize = 64;
12+
}
13+
14+
struct BarCipher;
15+
impl BlockCipher for BarCipher {
16+
const BLOCK_SIZE: usize = 32;
17+
}
18+
19+
pub struct Block<C>(C);
20+
21+
pub fn test<C: BlockCipher, const M: usize>()
22+
where
23+
[u8; M - C::BLOCK_SIZE]: Sized,
24+
{
25+
let _ = [0; M - C::BLOCK_SIZE];
26+
}
27+
28+
fn main() {
29+
test::<FooCipher, 128>();
30+
test::<BarCipher, 64>();
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(const_generics, const_evaluatable_checked)]
2+
#![allow(incomplete_features)]
3+
4+
use std::mem::size_of;
5+
use std::marker::PhantomData;
6+
7+
struct Foo<T>(PhantomData<T>);
8+
9+
fn test<T>() -> [u8; size_of::<T>()] {
10+
[0; size_of::<Foo<T>>()]
11+
//~^ ERROR unconstrained generic constant
12+
}
13+
14+
fn main() {
15+
test::<u32>();
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: unconstrained generic constant
2+
--> $DIR/different-fn.rs:10:9
3+
|
4+
LL | [0; size_of::<Foo<T>>()]
5+
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
help: consider adding a `where` bound for this expression
8+
--> $DIR/different-fn.rs:10:9
9+
|
10+
LL | [0; size_of::<Foo<T>>()]
11+
| ^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to previous error
14+

0 commit comments

Comments
 (0)