Skip to content

Commit

Permalink
Deny bare const expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Apr 29, 2020
1 parent 200034a commit 9a5a4b0
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 30 deletions.
40 changes: 33 additions & 7 deletions src/librustc_parse/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,13 +593,39 @@ impl<'a> Parser<'a> {
// we should introduce a GenericArg::Ident in the AST and distinguish when
// lowering to the HIR. For now, idents for const args are not permitted.
let start = self.token.span;
self.parse_expr_res(Restrictions::CONST_EXPR, None).map_err(|mut err| {
err.span_label(
start.shrink_to_lo(),
"while parsing a `const` argument starting here",
);
err
})?
let expr =
self.parse_expr_res(Restrictions::CONST_EXPR, None).map_err(|mut err| {
err.span_label(
start.shrink_to_lo(),
"while parsing a `const` argument starting here",
);
err
})?;
let valid_const = match &expr.kind {
ast::ExprKind::Block(_, _) | ast::ExprKind::Lit(_) => true,
ast::ExprKind::Unary(ast::UnOp::Neg, expr) => match &expr.kind {
ast::ExprKind::Lit(_) => true,
_ => false,
},
_ => false,
};
if !valid_const {
self.struct_span_err(
expr.span,
"`const` generic expressions without braces are not supported",
)
.note("only literals are supported as `const` generic without braces")
.multipart_suggestion(
"surround `const` expressions with braces",
vec![
(expr.span.shrink_to_lo(), "{ ".to_string()),
(expr.span.shrink_to_hi(), " }".to_string()),
],
Applicability::MachineApplicable,
)
.emit();
}
expr
};
GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })
} else if self.check_type() {
Expand Down
16 changes: 6 additions & 10 deletions src/test/ui/const-generics/const-expression-missing-braces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,22 @@ fn foo<const C: usize>() {}
const BAR: usize = 42;

fn a() {
foo::<BAR + 3>();
//~^ ERROR expected one of
foo::<BAR + 3>(); //~ ERROR expected one of
}
fn b() {
foo::<BAR + BAR>();
//~^ ERROR likely `const` expression parsed as trait bounds
foo::<BAR + BAR>(); //~ ERROR likely `const` expression parsed as trait bounds
}
fn c() {
foo::<3 + 3>(); // ok
foo::<3 + 3>(); //~ ERROR `const` generic expressions without braces are not supported
}
fn d() {
foo::<BAR - 3>();
//~^ ERROR expected one of
foo::<BAR - 3>(); //~ ERROR expected one of
}
fn e() {
foo::<BAR - BAR>();
//~^ ERROR expected one of
foo::<BAR - BAR>(); //~ ERROR expected one of
}
fn f() {
foo::<100 - BAR>(); // ok
foo::<100 - BAR>(); //~ ERROR `const` generic expressions without braces are not supported
}
fn g() {
foo::<bar<i32>()>(); //~ ERROR expected one of
Expand Down
44 changes: 34 additions & 10 deletions src/test/ui/const-generics/const-expression-missing-braces.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@ help: to write a `const` expression, surround it with braces for it to be unambi
LL | foo::<{ BAR + 3 }>();
| ^ ^

error: `const` generic expressions without braces are not supported
--> $DIR/const-expression-missing-braces.rs:15:11
|
LL | foo::<3 + 3>();
| ^^^^^
|
= note: only literals are supported as `const` generic without braces
help: surround `const` expressions with braces
|
LL | foo::<{ 3 + 3 }>();
| ^ ^

error: expected one of `,` or `>`, found `-`
--> $DIR/const-expression-missing-braces.rs:20:15
--> $DIR/const-expression-missing-braces.rs:18:15
|
LL | foo::<BAR - 3>();
| ^ expected one of `,` or `>`
Expand All @@ -21,7 +33,7 @@ LL | foo::<{ BAR - 3 }>();
| ^ ^

error: expected one of `,` or `>`, found `-`
--> $DIR/const-expression-missing-braces.rs:24:15
--> $DIR/const-expression-missing-braces.rs:21:15
|
LL | foo::<BAR - BAR>();
| ^ expected one of `,` or `>`
Expand All @@ -31,8 +43,20 @@ help: to write a `const` expression, surround it with braces for it to be unambi
LL | foo::<{ BAR - BAR }>();
| ^ ^

error: `const` generic expressions without braces are not supported
--> $DIR/const-expression-missing-braces.rs:24:11
|
LL | foo::<100 - BAR>();
| ^^^^^^^^^
|
= note: only literals are supported as `const` generic without braces
help: surround `const` expressions with braces
|
LL | foo::<{ 100 - BAR }>();
| ^ ^

error: expected one of `,` or `>`, found `(`
--> $DIR/const-expression-missing-braces.rs:31:19
--> $DIR/const-expression-missing-braces.rs:27:19
|
LL | foo::<bar<i32>()>();
| ^ expected one of `,` or `>`
Expand All @@ -43,7 +67,7 @@ LL | foo::<{ bar<i32>() }>();
| ^ ^

error: expected one of `,` or `>`, found `(`
--> $DIR/const-expression-missing-braces.rs:34:21
--> $DIR/const-expression-missing-braces.rs:30:21
|
LL | foo::<bar::<i32>()>();
| ^ expected one of `,` or `>`
Expand All @@ -54,7 +78,7 @@ LL | foo::<{ bar::<i32>() }>();
| ^ ^

error: expected one of `,` or `>`, found `(`
--> $DIR/const-expression-missing-braces.rs:37:21
--> $DIR/const-expression-missing-braces.rs:33:21
|
LL | foo::<bar::<i32>() + BAR>();
| ^ expected one of `,` or `>`
Expand All @@ -65,7 +89,7 @@ LL | foo::<{ bar::<i32>() + BAR }>();
| ^ ^

error: expected one of `,` or `>`, found `(`
--> $DIR/const-expression-missing-braces.rs:40:21
--> $DIR/const-expression-missing-braces.rs:36:21
|
LL | foo::<bar::<i32>() - BAR>();
| ^ expected one of `,` or `>`
Expand All @@ -76,7 +100,7 @@ LL | foo::<{ bar::<i32>() - BAR }>();
| ^ ^

error: expected one of `,` or `>`, found `-`
--> $DIR/const-expression-missing-braces.rs:43:15
--> $DIR/const-expression-missing-braces.rs:39:15
|
LL | foo::<BAR - bar::<i32>()>();
| ^ expected one of `,` or `>`
Expand All @@ -87,7 +111,7 @@ LL | foo::<{ BAR - bar::<i32>() }>();
| ^ ^

error: expected one of `,` or `>`, found `-`
--> $DIR/const-expression-missing-braces.rs:46:15
--> $DIR/const-expression-missing-braces.rs:42:15
|
LL | foo::<BAR - bar::<i32>()>();
| ^ expected one of `,` or `>`
Expand All @@ -98,7 +122,7 @@ LL | foo::<{ BAR - bar::<i32>() }>();
| ^ ^

error: likely `const` expression parsed as trait bounds
--> $DIR/const-expression-missing-braces.rs:13:11
--> $DIR/const-expression-missing-braces.rs:12:11
|
LL | foo::<BAR + BAR>();
| ^^^^^^^^^ parsed as trait bounds but traits weren't found
Expand All @@ -108,5 +132,5 @@ help: if you meant to write a `const` expression, surround the expression with b
LL | foo::<{ BAR + BAR }>();
| ^ ^

error: aborting due to 10 previous errors
error: aborting due to 12 previous errors

3 changes: 1 addition & 2 deletions src/test/ui/const-generics/const-expression-parameter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// check-pass
#![allow(incomplete_features)]
#![feature(const_generics)]

Expand All @@ -11,7 +10,7 @@ fn foo_a() {
}

fn foo_b() {
i32_identity::<1 + 2>(); // ok
i32_identity::<1 + 2>(); //~ ERROR `const` generic expressions without braces are not supported
}

fn foo_c() {
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/const-generics/const-expression-parameter.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: `const` generic expressions without braces are not supported
--> $DIR/const-expression-parameter.rs:13:20
|
LL | i32_identity::<1 + 2>();
| ^^^^^
|
= note: only literals are supported as `const` generic without braces
help: surround `const` expressions with braces
|
LL | i32_identity::<{ 1 + 2 }>();
| ^ ^

error: aborting due to previous error

1 change: 1 addition & 0 deletions src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,5 +237,6 @@ fn inside_const_generic_arguments() {
if A::<
true && let 1 = 1 //~ ERROR `let` expressions are not supported here
//~^ ERROR `match` is not allowed in a `const`
//~| ERROR `const` generic expressions without braces are not supported
>::O == 5 {}
}
14 changes: 13 additions & 1 deletion src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
error: `const` generic expressions without braces are not supported
--> $DIR/disallowed-positions.rs:238:9
|
LL | true && let 1 = 1
| ^^^^^^^^^^^^^^^^^
|
= note: only literals are supported as `const` generic without braces
help: surround `const` expressions with braces
|
LL | { true && let 1 = 1 }
| ^ ^

error: `let` expressions are not supported here
--> $DIR/disallowed-positions.rs:32:9
|
Expand Down Expand Up @@ -992,7 +1004,7 @@ LL | let 0 = 0?;
= help: the trait `std::ops::Try` is not implemented for `{integer}`
= note: required by `std::ops::Try::into_result`

error: aborting due to 107 previous errors; 2 warnings emitted
error: aborting due to 108 previous errors; 2 warnings emitted

Some errors have detailed explanations: E0277, E0308, E0600, E0614, E0658.
For more information about an error, try `rustc --explain E0277`.

0 comments on commit 9a5a4b0

Please sign in to comment.