Skip to content

Commit 6baaa52

Browse files
committed
Allow inline consts to reference generic params
1 parent bf4d7fa commit 6baaa52

8 files changed

+91
-6
lines changed

compiler/rustc_resolve/src/late.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -3101,6 +3101,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
31013101
);
31023102
}
31033103

3104+
fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
3105+
debug!("resolve_anon_const {constant:?}");
3106+
self.with_constant_rib(IsRepeatExpr::No, HasGenericParams::Yes, None, |this| {
3107+
visit::walk_anon_const(this, constant);
3108+
});
3109+
}
3110+
31043111
fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
31053112
// First, record candidate traits for this expression if it could
31063113
// result in the invocation of a method call.
@@ -3257,7 +3264,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
32573264
});
32583265
}
32593266
ExprKind::ConstBlock(ref ct) => {
3260-
self.resolve_anon_const(ct, IsRepeatExpr::No);
3267+
self.resolve_inline_const(ct);
32613268
}
32623269
ExprKind::Index(ref elem, ref idx) => {
32633270
self.resolve_expr(elem, Some(expr));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// build-fail
2+
#![feature(inline_const)]
3+
4+
fn foo<T>() {
5+
const { assert!(std::mem::size_of::<T>() == 0); } //~ ERROR E0080
6+
}
7+
8+
fn bar<const N: usize>() -> usize {
9+
const { N - 1 } //~ ERROR E0080
10+
}
11+
12+
fn main() {
13+
foo::<i32>();
14+
bar::<0>();
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0080]: evaluation of `foo::<i32>::{constant#0}` failed
2+
--> $DIR/const-expr-generic-err.rs:5:13
3+
|
4+
LL | const { assert!(std::mem::size_of::<T>() == 0); }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::<T>() == 0', $DIR/const-expr-generic-err.rs:5:13
6+
|
7+
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
note: the above error was encountered while instantiating `fn foo::<i32>`
10+
--> $DIR/const-expr-generic-err.rs:13:5
11+
|
12+
LL | foo::<i32>();
13+
| ^^^^^^^^^^^^
14+
15+
error[E0080]: evaluation of `bar::<0_usize>::{constant#0}` failed
16+
--> $DIR/const-expr-generic-err.rs:9:13
17+
|
18+
LL | const { N - 1 }
19+
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
20+
21+
note: the above error was encountered while instantiating `fn bar::<0_usize>`
22+
--> $DIR/const-expr-generic-err.rs:14:5
23+
|
24+
LL | bar::<0>();
25+
| ^^^^^^^^^^
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0080`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![feature(inline_const)]
2+
3+
fn foo<T>() {
4+
let _ = [0u8; const { std::mem::size_of::<T>() }];
5+
//~^ ERROR: constant expression depends on a generic parameter
6+
}
7+
8+
fn main() {
9+
foo::<i32>();
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: constant expression depends on a generic parameter
2+
--> $DIR/const-expr-generic-err2.rs:4:19
3+
|
4+
LL | let _ = [0u8; const { std::mem::size_of::<T>() }];
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: this may fail depending on what value the parameter takes
8+
9+
error: aborting due to previous error
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// check-pass
2+
#![feature(inline_const)]
3+
4+
fn foo<T>() -> usize {
5+
const { std::mem::size_of::<T>() }
6+
}
7+
8+
fn bar<const N: usize>() -> usize {
9+
const { N + 1 }
10+
}
11+
12+
fn main() {
13+
foo::<i32>();
14+
bar::<1>();
15+
}

src/test/ui/inline-const/const-match-pat-generic.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#![allow(incomplete_features)]
22
#![feature(inline_const_pat)]
3-
#![feature(generic_const_exprs)]
43

54
// rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter
65

@@ -16,7 +15,7 @@ const fn f(x: usize) -> usize {
1615
x + 1
1716
}
1817

19-
fn bar<const V: usize>() where [(); f(V)]: {
18+
fn bar<const V: usize>() {
2019
match 0 {
2120
const { f(V) } => {},
2221
//~^ ERROR constant pattern depends on a generic parameter

src/test/ui/inline-const/const-match-pat-generic.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
error[E0158]: const parameters cannot be referenced in patterns
2-
--> $DIR/const-match-pat-generic.rs:9:9
2+
--> $DIR/const-match-pat-generic.rs:8:9
33
|
44
LL | const { V } => {},
55
| ^^^^^^^^^^^
66

77
error: constant pattern depends on a generic parameter
8-
--> $DIR/const-match-pat-generic.rs:21:9
8+
--> $DIR/const-match-pat-generic.rs:20:9
99
|
1010
LL | const { f(V) } => {},
1111
| ^^^^^^^^^^^^^^
1212

1313
error: constant pattern depends on a generic parameter
14-
--> $DIR/const-match-pat-generic.rs:21:9
14+
--> $DIR/const-match-pat-generic.rs:20:9
1515
|
1616
LL | const { f(V) } => {},
1717
| ^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)