@@ -1613,42 +1613,65 @@ impl<'a> Parser<'a> {
1613
1613
Applicability :: HasPlaceholders ,
1614
1614
) ;
1615
1615
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
+ }
1640
1641
}
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 {
1641
1648
err. span_suggestion (
1642
1649
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 ,
1646
1663
) ;
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) } ;
1651
1664
}
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) } ;
1652
1675
}
1653
1676
None
1654
1677
}
0 commit comments