Skip to content

Commit b0625eb

Browse files
committed
boop, ur abstract consts are now expanded
1 parent 7fba12b commit b0625eb

File tree

5 files changed

+132
-4
lines changed

5 files changed

+132
-4
lines changed

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,27 @@ where
609609
/// Tries to unify two abstract constants using structural equality.
610610
pub(super) fn try_unify<'tcx>(
611611
tcx: TyCtxt<'tcx>,
612-
a: AbstractConst<'tcx>,
613-
b: AbstractConst<'tcx>,
612+
mut a: AbstractConst<'tcx>,
613+
mut b: AbstractConst<'tcx>,
614614
) -> bool {
615+
while let Node::Leaf(a_ct) = a.root() {
616+
let a_ct = a_ct.subst(tcx, a.substs);
617+
match AbstractConst::from_const(tcx, a_ct) {
618+
Ok(Some(a_act)) => a = a_act,
619+
Ok(None) => break,
620+
Err(_) => return true,
621+
}
622+
}
623+
624+
while let Node::Leaf(b_ct) = b.root() {
625+
let b_ct = b_ct.subst(tcx, b.substs);
626+
match AbstractConst::from_const(tcx, b_ct) {
627+
Ok(Some(b_act)) => b = b_act,
628+
Ok(None) => break,
629+
Err(_) => return true,
630+
}
631+
}
632+
615633
match (a.root(), b.root()) {
616634
(Node::Leaf(a_ct), Node::Leaf(b_ct)) => {
617635
let a_ct = a_ct.subst(tcx, a.substs);
@@ -632,8 +650,6 @@ pub(super) fn try_unify<'tcx>(
632650
// we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
633651
// means that we only allow inference variables if they are equal.
634652
(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.
637653
(
638654
ty::ConstKind::Unevaluated(a_def, a_substs, None),
639655
ty::ConstKind::Unevaluated(b_def, b_substs, None),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// run-pass
2+
#![feature(const_generics, const_evaluatable_checked)]
3+
#![allow(incomplete_features)]
4+
5+
fn callee<const M2: usize>() -> usize
6+
where
7+
[u8; M2 + 1]: Sized,
8+
{
9+
M2
10+
}
11+
12+
fn caller<const N1: usize>() -> usize
13+
where
14+
[u8; N1 + 1]: Sized,
15+
[u8; (N1 + 1) + 1]: Sized,
16+
{
17+
callee::<{ N1 + 1 }>()
18+
}
19+
20+
fn main() {
21+
assert_eq!(caller::<4>(), 5);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// run-pass
2+
#![feature(const_evaluatable_checked, const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
struct Generic<const K: u64>;
6+
7+
struct ConstU64<const K: u64>;
8+
9+
impl<const K: u64> Generic<K>
10+
where
11+
ConstU64<{ K - 1 }>: ,
12+
{
13+
fn foo(self) -> u64 {
14+
K
15+
}
16+
}
17+
18+
impl<const K: u64> Generic<K>
19+
where
20+
ConstU64<{ K - 1 }>: ,
21+
ConstU64<{ K + 1 }>: ,
22+
ConstU64<{ K + 1 - 1 }>: ,
23+
{
24+
fn bar(self) -> u64 {
25+
let x: Generic<{ K + 1 }> = Generic;
26+
x.foo()
27+
}
28+
}
29+
30+
fn main() {
31+
assert_eq!((Generic::<10>).bar(), 11);
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// run-pass
2+
#![feature(const_generics, const_evaluatable_checked)]
3+
#![allow(incomplete_features)]
4+
5+
fn zero_init<const N: usize>() -> Substs1<N>
6+
where
7+
[u8; N + 1]: ,
8+
{
9+
Substs1([0; N + 1])
10+
}
11+
struct Substs1<const N: usize>([u8; N + 1])
12+
where
13+
[(); N + 1]: ;
14+
15+
fn substs2<const M: usize>() -> Substs1<{ M * 2 }>
16+
where
17+
[(); { M * 2 } + 1]: ,
18+
{
19+
zero_init::<{ M * 2 }>()
20+
}
21+
22+
fn substs3<const L: usize>() -> Substs1<{ (L - 1) * 2 }>
23+
where
24+
[(); (L - 1)]: ,
25+
[(); (L - 1) * 2 + 1]: ,
26+
{
27+
substs2::<{ L - 1 }>()
28+
}
29+
30+
fn main() {
31+
assert_eq!(substs3::<2>().0, [0; 3]);
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// run-pass
2+
#![feature(const_generics, const_evaluatable_checked)]
3+
#![allow(incomplete_features, unused_parens, unused_braces)]
4+
5+
fn zero_init<const N: usize>() -> Substs1<{ (N) }>
6+
where
7+
[u8; { (N) }]: ,
8+
{
9+
Substs1([0; { (N) }])
10+
}
11+
12+
struct Substs1<const N: usize>([u8; { (N) }])
13+
where
14+
[(); { (N) }]: ;
15+
16+
fn substs2<const M: usize>() -> Substs1<{ (M) }> {
17+
zero_init::<{ (M) }>()
18+
}
19+
20+
fn substs3<const L: usize>() -> Substs1<{ (L) }> {
21+
substs2::<{ (L) }>()
22+
}
23+
24+
fn main() {
25+
assert_eq!(substs3::<2>().0, [0; 2]);
26+
}

0 commit comments

Comments
 (0)