Skip to content

Commit

Permalink
Allow inline consts to reference generic params
Browse files Browse the repository at this point in the history
  • Loading branch information
nbdd0121 committed May 3, 2022
1 parent bf4d7fa commit 6baaa52
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 6 deletions.
9 changes: 8 additions & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3101,6 +3101,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
);
}

fn resolve_inline_const(&mut self, constant: &'ast AnonConst) {
debug!("resolve_anon_const {constant:?}");
self.with_constant_rib(IsRepeatExpr::No, HasGenericParams::Yes, None, |this| {
visit::walk_anon_const(this, constant);
});
}

fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
// First, record candidate traits for this expression if it could
// result in the invocation of a method call.
Expand Down Expand Up @@ -3257,7 +3264,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
});
}
ExprKind::ConstBlock(ref ct) => {
self.resolve_anon_const(ct, IsRepeatExpr::No);
self.resolve_inline_const(ct);
}
ExprKind::Index(ref elem, ref idx) => {
self.resolve_expr(elem, Some(expr));
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/inline-const/const-expr-generic-err.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// build-fail
#![feature(inline_const)]

fn foo<T>() {
const { assert!(std::mem::size_of::<T>() == 0); } //~ ERROR E0080
}

fn bar<const N: usize>() -> usize {
const { N - 1 } //~ ERROR E0080
}

fn main() {
foo::<i32>();
bar::<0>();
}
29 changes: 29 additions & 0 deletions src/test/ui/inline-const/const-expr-generic-err.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error[E0080]: evaluation of `foo::<i32>::{constant#0}` failed
--> $DIR/const-expr-generic-err.rs:5:13
|
LL | const { assert!(std::mem::size_of::<T>() == 0); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::<T>() == 0', $DIR/const-expr-generic-err.rs:5:13
|
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)

note: the above error was encountered while instantiating `fn foo::<i32>`
--> $DIR/const-expr-generic-err.rs:13:5
|
LL | foo::<i32>();
| ^^^^^^^^^^^^

error[E0080]: evaluation of `bar::<0_usize>::{constant#0}` failed
--> $DIR/const-expr-generic-err.rs:9:13
|
LL | const { N - 1 }
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow

note: the above error was encountered while instantiating `fn bar::<0_usize>`
--> $DIR/const-expr-generic-err.rs:14:5
|
LL | bar::<0>();
| ^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0080`.
10 changes: 10 additions & 0 deletions src/test/ui/inline-const/const-expr-generic-err2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![feature(inline_const)]

fn foo<T>() {
let _ = [0u8; const { std::mem::size_of::<T>() }];
//~^ ERROR: constant expression depends on a generic parameter
}

fn main() {
foo::<i32>();
}
10 changes: 10 additions & 0 deletions src/test/ui/inline-const/const-expr-generic-err2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: constant expression depends on a generic parameter
--> $DIR/const-expr-generic-err2.rs:4:19
|
LL | let _ = [0u8; const { std::mem::size_of::<T>() }];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes

error: aborting due to previous error

15 changes: 15 additions & 0 deletions src/test/ui/inline-const/const-expr-generic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// check-pass
#![feature(inline_const)]

fn foo<T>() -> usize {
const { std::mem::size_of::<T>() }
}

fn bar<const N: usize>() -> usize {
const { N + 1 }
}

fn main() {
foo::<i32>();
bar::<1>();
}
3 changes: 1 addition & 2 deletions src/test/ui/inline-const/const-match-pat-generic.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![allow(incomplete_features)]
#![feature(inline_const_pat)]
#![feature(generic_const_exprs)]

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

Expand All @@ -16,7 +15,7 @@ const fn f(x: usize) -> usize {
x + 1
}

fn bar<const V: usize>() where [(); f(V)]: {
fn bar<const V: usize>() {
match 0 {
const { f(V) } => {},
//~^ ERROR constant pattern depends on a generic parameter
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/inline-const/const-match-pat-generic.stderr
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
error[E0158]: const parameters cannot be referenced in patterns
--> $DIR/const-match-pat-generic.rs:9:9
--> $DIR/const-match-pat-generic.rs:8:9
|
LL | const { V } => {},
| ^^^^^^^^^^^

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

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

0 comments on commit 6baaa52

Please sign in to comment.