@@ -2030,7 +2030,7 @@ impl<'a> Parser<'a> {
20302030 start : Span ,
20312031 mut err : DiagnosticBuilder < ' a , ErrorReported > ,
20322032 ) -> PResult < ' a , GenericArg > {
2033- let is_op = AssocOp :: from_token ( & self . token )
2033+ let is_op_or_dot = AssocOp :: from_token ( & self . token )
20342034 . and_then ( |op| {
20352035 if let AssocOp :: Greater
20362036 | AssocOp :: Less
@@ -2046,17 +2046,18 @@ impl<'a> Parser<'a> {
20462046 Some ( op)
20472047 }
20482048 } )
2049- . is_some ( ) ;
2049+ . is_some ( )
2050+ || self . token . kind == TokenKind :: Dot ;
20502051 // This will be true when a trait object type `Foo +` or a path which was a `const fn` with
20512052 // type params has been parsed.
20522053 let was_op =
20532054 matches ! ( self . prev_token. kind, token:: BinOp ( token:: Plus | token:: Shr ) | token:: Gt ) ;
2054- if !is_op && !was_op {
2055+ if !is_op_or_dot && !was_op {
20552056 // We perform these checks and early return to avoid taking a snapshot unnecessarily.
20562057 return Err ( err) ;
20572058 }
20582059 let snapshot = self . clone ( ) ;
2059- if is_op {
2060+ if is_op_or_dot {
20602061 self . bump ( ) ;
20612062 }
20622063 match self . parse_expr_res ( Restrictions :: CONST_EXPR , None ) {
@@ -2080,18 +2081,7 @@ impl<'a> Parser<'a> {
20802081 // |
20812082 // LL | let sr: Vec<{ (u32, _, _) = vec![] };
20822083 // | ^ ^
2083- err. multipart_suggestion (
2084- "expressions must be enclosed in braces to be used as const generic \
2085- arguments",
2086- vec ! [
2087- ( start. shrink_to_lo( ) , "{ " . to_string( ) ) ,
2088- ( expr. span. shrink_to_hi( ) , " }" . to_string( ) ) ,
2089- ] ,
2090- Applicability :: MaybeIncorrect ,
2091- ) ;
2092- let value = self . mk_expr_err ( start. to ( expr. span ) ) ;
2093- err. emit ( ) ;
2094- return Ok ( GenericArg :: Const ( AnonConst { id : ast:: DUMMY_NODE_ID , value } ) ) ;
2084+ return Ok ( self . dummy_const_arg_needs_braces ( err, start. to ( expr. span ) ) ) ;
20952085 }
20962086 }
20972087 Err ( err) => {
@@ -2102,6 +2092,23 @@ impl<'a> Parser<'a> {
21022092 Err ( err)
21032093 }
21042094
2095+ /// Creates a dummy const argument, and reports that the expression must be enclosed in braces
2096+ pub fn dummy_const_arg_needs_braces (
2097+ & self ,
2098+ mut err : DiagnosticBuilder < ' a , ErrorReported > ,
2099+ span : Span ,
2100+ ) -> GenericArg {
2101+ err. multipart_suggestion (
2102+ "expressions must be enclosed in braces to be used as const generic \
2103+ arguments",
2104+ vec ! [ ( span. shrink_to_lo( ) , "{ " . to_string( ) ) , ( span. shrink_to_hi( ) , " }" . to_string( ) ) ] ,
2105+ Applicability :: MaybeIncorrect ,
2106+ ) ;
2107+ let value = self . mk_expr_err ( span) ;
2108+ err. emit ( ) ;
2109+ GenericArg :: Const ( AnonConst { id : ast:: DUMMY_NODE_ID , value } )
2110+ }
2111+
21052112 /// Get the diagnostics for the cases where `move async` is found.
21062113 ///
21072114 /// `move_async_span` starts at the 'm' of the move keyword and ends with the 'c' of the async keyword
0 commit comments