Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f773f1b

Browse files
authoredJun 13, 2022
Rollup merge of rust-lang#97709 - compiler-errors:normalize-const-param-ty, r=oli-obk
Normalize consts' tys when relating with `adt_const_params` Fixes rust-lang#97007
2 parents 083721a + 27af8e4 commit f773f1b

File tree

2 files changed

+97
-4
lines changed

2 files changed

+97
-4
lines changed
 

‎compiler/rustc_middle/src/ty/relate.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -579,10 +579,15 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
579579
debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
580580
let tcx = relation.tcx();
581581

582-
// FIXME(oli-obk): once const generics can have generic types, this assertion
583-
// will likely get triggered. Move to `normalize_erasing_regions` at that point.
584-
let a_ty = tcx.erase_regions(a.ty());
585-
let b_ty = tcx.erase_regions(b.ty());
582+
let a_ty;
583+
let b_ty;
584+
if relation.tcx().features().adt_const_params {
585+
a_ty = tcx.normalize_erasing_regions(relation.param_env(), a.ty());
586+
b_ty = tcx.normalize_erasing_regions(relation.param_env(), b.ty());
587+
} else {
588+
a_ty = tcx.erase_regions(a.ty());
589+
b_ty = tcx.erase_regions(b.ty());
590+
}
586591
if a_ty != b_ty {
587592
relation.tcx().sess.delay_span_bug(
588593
DUMMY_SP,
+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// check-pass
2+
3+
#![feature(adt_const_params, generic_const_exprs)]
4+
#![allow(incomplete_features)]
5+
6+
mod lib {
7+
const N_ISLANDS: usize = 4;
8+
const N_BRIDGES: usize = 7;
9+
const BRIDGES: [(usize, usize); 7] = [(0, 1), (0, 1), (0, 2), (0, 3), (0, 3), (1, 2), (2, 3)];
10+
11+
pub type Matrix = [[usize; N_ISLANDS]; N_ISLANDS];
12+
13+
const EMPTY_MATRIX: Matrix = [[0; N_ISLANDS]; N_ISLANDS];
14+
15+
const fn build(mut matrix: Matrix, (to, from): (usize, usize)) -> Matrix {
16+
matrix[to][from] += 1;
17+
matrix[from][to] += 1;
18+
matrix
19+
}
20+
21+
pub const fn walk(mut matrix: Matrix, from: usize, to: usize) -> Matrix {
22+
matrix[from][to] -= 1;
23+
matrix[to][from] -= 1;
24+
matrix
25+
}
26+
27+
const fn to_matrix(bridges: [(usize, usize); N_BRIDGES]) -> Matrix {
28+
let matrix = EMPTY_MATRIX;
29+
30+
let matrix = build(matrix, bridges[0]);
31+
let matrix = build(matrix, bridges[1]);
32+
let matrix = build(matrix, bridges[2]);
33+
let matrix = build(matrix, bridges[3]);
34+
let matrix = build(matrix, bridges[4]);
35+
let matrix = build(matrix, bridges[5]);
36+
let matrix = build(matrix, bridges[6]);
37+
38+
matrix
39+
}
40+
41+
const BRIDGE_MATRIX: [[usize; N_ISLANDS]; N_ISLANDS] = to_matrix(BRIDGES);
42+
43+
pub struct Walk<const CURRENT: usize, const REMAINING: Matrix> {
44+
_p: (),
45+
}
46+
47+
impl Walk<0, BRIDGE_MATRIX> {
48+
pub const fn new() -> Self {
49+
Self { _p: () }
50+
}
51+
}
52+
53+
impl<const CURRENT: usize, const REMAINING: Matrix> Walk<CURRENT, REMAINING> {
54+
pub fn proceed_to<const NEXT: usize>(
55+
self,
56+
) -> Walk<NEXT, { walk(REMAINING, CURRENT, NEXT) }> {
57+
Walk { _p: () }
58+
}
59+
}
60+
61+
pub struct Trophy {
62+
_p: (),
63+
}
64+
65+
impl<const CURRENT: usize> Walk<CURRENT, EMPTY_MATRIX> {
66+
pub fn collect_prize(self) -> Trophy {
67+
Trophy { _p: () }
68+
}
69+
}
70+
}
71+
72+
pub use lib::{Trophy, Walk};
73+
74+
fn main() {
75+
// Example, taking the first step
76+
let _ = Walk::new().proceed_to::<1>();
77+
78+
// Don't be so eager to collect the trophy
79+
// let trophy = Walk::new()
80+
// .proceed_to::<1>()
81+
// .proceed_to::<0>()
82+
// .collect_prize();
83+
84+
// Can't just make a Trophy out of thin air, you must earn it
85+
// let trophy: Trophy = Trophy { _p: () };
86+
87+
// Can you collect the Trophy?
88+
}

0 commit comments

Comments
 (0)
Please sign in to comment.