@@ -1613,42 +1613,65 @@ impl<'a> Parser<'a> {
16131613 Applicability :: HasPlaceholders ,
16141614 ) ;
16151615 return Some ( ident) ;
1616- } else if let PatKind :: Ident ( _, ident, _) = pat. kind {
1617- if require_name
1618- && ( self . token == token:: Comma
1619- || self . token == token:: Lt
1620- || self . token == token:: CloseDelim ( token:: Paren ) )
1621- {
1622- // `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
1623- if first_param {
1624- err. span_suggestion (
1625- pat. span ,
1626- "if this is a `self` type, give it a parameter name" ,
1627- format ! ( "self: {}" , ident) ,
1628- Applicability :: MaybeIncorrect ,
1629- ) ;
1630- }
1631- // Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
1632- // `fn foo(HashMap: TypeName<u32>)`.
1633- if self . token != token:: Lt {
1634- err. span_suggestion (
1635- pat. span ,
1636- "if this is a parameter name, give it a type" ,
1637- format ! ( "{}: TypeName" , ident) ,
1638- Applicability :: HasPlaceholders ,
1639- ) ;
1616+ } else if require_name
1617+ && ( self . token == token:: Comma
1618+ || self . token == token:: Lt
1619+ || self . token == token:: CloseDelim ( token:: Paren ) )
1620+ {
1621+ let ( ident, self_sugg, param_sugg, type_sugg) = match pat. kind {
1622+ PatKind :: Ident ( _, ident, _) => (
1623+ ident,
1624+ format ! ( "self: {}" , ident) ,
1625+ format ! ( "{}: TypeName" , ident) ,
1626+ format ! ( "_: {}" , ident) ,
1627+ ) ,
1628+ // Also catches `fn foo(&a)`.
1629+ PatKind :: Ref ( ref pat, mutab) => {
1630+ if let PatKind :: Ident ( _, ident, _) = pat. clone ( ) . into_inner ( ) . kind {
1631+ let mutab = mutab. prefix_str ( ) ;
1632+ (
1633+ ident,
1634+ format ! ( "self: &{}{}" , mutab, ident) ,
1635+ format ! ( "{}: &{}TypeName" , ident, mutab) ,
1636+ format ! ( "_: &{}{}" , mutab, ident) ,
1637+ )
1638+ } else {
1639+ return None ;
1640+ }
16401641 }
1642+ // Ignore other `PatKind`.
1643+ _ => return None ,
1644+ } ;
1645+
1646+ // `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
1647+ if first_param {
16411648 err. span_suggestion (
16421649 pat. span ,
1643- "if this is a type, explicitly ignore the parameter name" ,
1644- format ! ( "_: {}" , ident) ,
1645- Applicability :: MachineApplicable ,
1650+ "if this is a `self` type, give it a parameter name" ,
1651+ self_sugg,
1652+ Applicability :: MaybeIncorrect ,
1653+ ) ;
1654+ }
1655+ // Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
1656+ // `fn foo(HashMap: TypeName<u32>)`.
1657+ if self . token != token:: Lt {
1658+ err. span_suggestion (
1659+ pat. span ,
1660+ "if this is a parameter name, give it a type" ,
1661+ param_sugg,
1662+ Applicability :: HasPlaceholders ,
16461663 ) ;
1647- err. note ( "anonymous parameters are removed in the 2018 edition (see RFC 1685)" ) ;
1648-
1649- // Don't attempt to recover by using the `X` in `X<Y>` as the parameter name.
1650- return if self . token == token:: Lt { None } else { Some ( ident) } ;
16511664 }
1665+ err. span_suggestion (
1666+ pat. span ,
1667+ "if this is a type, explicitly ignore the parameter name" ,
1668+ type_sugg,
1669+ Applicability :: MachineApplicable ,
1670+ ) ;
1671+ err. note ( "anonymous parameters are removed in the 2018 edition (see RFC 1685)" ) ;
1672+
1673+ // Don't attempt to recover by using the `X` in `X<Y>` as the parameter name.
1674+ return if self . token == token:: Lt { None } else { Some ( ident) } ;
16521675 }
16531676 None
16541677 }
0 commit comments