@@ -23,7 +23,10 @@ use super::{
2323 AllowConstBlockItems , AttrWrapper , ExpKeywordPair , ExpTokenPair , FollowedByType , ForceCollect ,
2424 Parser , PathStyle , Recovered , Trailing , UsePreAttrPos ,
2525} ;
26- use crate :: errors:: { self , FnPointerCannotBeAsync , FnPointerCannotBeConst , MacroExpandsToAdtField } ;
26+ use crate :: errors:: {
27+ self , FnPointerCannotBeAsync , FnPointerCannotBeConst , MacroExpandsToAdtField ,
28+ UseDoubleColonSuggestion , UseRegularStructSuggestion ,
29+ } ;
2730use crate :: exp;
2831
2932impl < ' a > Parser < ' a > {
@@ -2084,10 +2087,11 @@ impl<'a> Parser<'a> {
20842087 Safety :: Default
20852088 }
20862089 }
2087-
2090+ /// This is the case where we find `struct Foo<T>(T) where T: Copy;`
2091+ /// Unit like structs are handled in parse_item_struct function
20882092 pub ( super ) fn parse_tuple_struct_body ( & mut self ) -> PResult < ' a , ThinVec < FieldDef > > {
2089- // This is the case where we find `struct Foo<T>(T) where T: Copy;`
2090- // Unit like structs are handled in parse_item_struct function
2093+ let openparen_span = self . token . span ;
2094+ let mut encountered_colon = false ;
20912095 self . parse_paren_comma_seq ( |p| {
20922096 let attrs = p. parse_outer_attributes ( ) ?;
20932097 p. collect_tokens ( None , attrs, ForceCollect :: No , |p, attrs| {
@@ -2109,6 +2113,8 @@ impl<'a> Parser<'a> {
21092113 }
21102114 } ;
21112115 let mut_restriction = p. parse_mut_restriction ( ) ?;
2116+ encountered_colon |=
2117+ p. token . is_ident ( ) && p. look_ahead ( 1 , |tok| tok == & token:: Colon ) ;
21122118 // Unsafe fields are not supported in tuple structs, as doing so would result in a
21132119 // parsing ambiguity for `struct X(unsafe fn())`.
21142120 let ty = match p. parse_ty ( ) {
@@ -2156,6 +2162,19 @@ impl<'a> Parser<'a> {
21562162 } )
21572163 } )
21582164 . map ( |( r, _) | r)
2165+ . map_err ( |mut error| {
2166+ if encountered_colon {
2167+ error. subdiagnostic ( UseDoubleColonSuggestion { colon : self . token . span } ) ;
2168+ self . eat_to_tokens ( & [ exp ! ( CloseParen ) ] ) ;
2169+ self . bump ( ) ;
2170+ error. subdiagnostic ( UseRegularStructSuggestion {
2171+ open : openparen_span,
2172+ close : self . prev_token . span ,
2173+ semicolon : if self . token == token:: Semi { Some ( self . token . span ) } else { None } ,
2174+ } ) ;
2175+ }
2176+ error
2177+ } )
21592178 }
21602179
21612180 /// Parses an element of a struct declaration.
0 commit comments