Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ impl<'a> Parser<'a> {
&self.sess.span_diagnostic
}

pub(super) fn diagnostic_snapshot(&self) -> Self {
let mut snapshot = self.clone();
// initialize unclosed_delims to avoid duplicate errors.
snapshot.unclosed_delims = vec![];
snapshot
}

pub(super) fn span_to_snippet(&self, span: Span) -> Result<String, SpanSnippetError> {
self.sess.source_map().span_to_snippet(span)
}
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,9 +624,18 @@ impl<'a> Parser<'a> {
GenericArg::Const(self.parse_const_arg()?)
} else if self.check_type() {
// Parse type argument.
let is_const_fn = self.look_ahead(1, |t| t.kind == token::OpenDelim(token::Paren));
let mut snapshot = self.diagnostic_snapshot();
match self.parse_ty() {
Ok(ty) => GenericArg::Type(ty),
Err(err) => {
if is_const_fn {
if let Ok(expr) = snapshot.parse_expr_res(Restrictions::CONST_EXPR, None) {
snapshot.unclosed_delims.extend(self.unclosed_delims.clone());
*self = snapshot;
return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span)));
}
}
// Try to recover from possible `const` arg without braces.
return self.recover_const_arg(start, err).map(Some);
}
Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/const-generics/const-generic-function.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
fn foo<const N: i32>() -> i32 {
N
}

const fn bar(n: i32, m: i32) -> i32 {
n
}

const fn baz() -> i32 {
1
}

const FOO: i32 = 3;

fn main() {
foo::<baz()>(); //~ ERROR expected type, found function `baz`
//~| ERROR unresolved item provided when a constant was expected
foo::<bar(bar(1, 1), bar(1, 1))>(); //~ ERROR expected type, found `1`
foo::<bar(1, 1)>(); //~ ERROR expected type, found `1`
foo::<bar(FOO, 2)>(); //~ ERROR expected type, found `2`
}
54 changes: 54 additions & 0 deletions src/test/ui/const-generics/const-generic-function.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
error: expected type, found `1`
--> $DIR/const-generic-function.rs:18:19
|
LL | foo::<bar(bar(1, 1), bar(1, 1))>();
| ^ expected type
|
help: expressions must be enclosed in braces to be used as const generic arguments
|
LL | foo::<{ bar(bar(1, 1), bar(1, 1)) }>();
| + +

error: expected type, found `1`
--> $DIR/const-generic-function.rs:19:15
|
LL | foo::<bar(1, 1)>();
| ^ expected type
|
help: expressions must be enclosed in braces to be used as const generic arguments
|
LL | foo::<{ bar(1, 1) }>();
| + +

error: expected type, found `2`
--> $DIR/const-generic-function.rs:20:20
|
LL | foo::<bar(FOO, 2)>();
| ^ expected type
|
help: expressions must be enclosed in braces to be used as const generic arguments
|
LL | foo::<{ bar(FOO, 2) }>();
| + +

error[E0573]: expected type, found function `baz`
--> $DIR/const-generic-function.rs:16:11
|
LL | foo::<baz()>();
| ^^^^^ not a type

error[E0747]: unresolved item provided when a constant was expected
--> $DIR/const-generic-function.rs:16:11
|
LL | foo::<baz()>();
| ^^^^^
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
LL | foo::<{ baz() }>();
| + +

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0573, E0747.
For more information about an error, try `rustc --explain E0573`.