@@ -2954,14 +2954,27 @@ impl<'a> Parser<'a> {
2954
2954
}
2955
2955
_ => unreachable ! ( ) ,
2956
2956
} ;
2957
+ // is lifetime `n` tokens ahead?
2958
+ let is_lifetime = |this : & Self , n| this. look_ahead ( n, |t| t. is_lifetime ( ) ) ;
2957
2959
// Is `self` `n` tokens ahead?
2958
2960
let is_isolated_self = |this : & Self , n| {
2959
2961
this. is_keyword_ahead ( n, & [ kw:: SelfLower ] )
2960
2962
&& this. look_ahead ( n + 1 , |t| t != & token:: PathSep )
2961
2963
} ;
2964
+ // Is `pin const self` `n` tokens ahead?
2965
+ let is_isolated_pin_const_self = |this : & Self , n| {
2966
+ this. look_ahead ( n, |token| token. is_ident_named ( sym:: pin) )
2967
+ && this. is_keyword_ahead ( n + 1 , & [ kw:: Const ] )
2968
+ && is_isolated_self ( this, n + 2 )
2969
+ } ;
2962
2970
// Is `mut self` `n` tokens ahead?
2963
2971
let is_isolated_mut_self =
2964
2972
|this : & Self , n| this. is_keyword_ahead ( n, & [ kw:: Mut ] ) && is_isolated_self ( this, n + 1 ) ;
2973
+ // Is `pin mut self` `n` tokens ahead?
2974
+ let is_isolated_pin_mut_self = |this : & Self , n| {
2975
+ this. look_ahead ( n, |token| token. is_ident_named ( sym:: pin) )
2976
+ && is_isolated_mut_self ( this, n + 1 )
2977
+ } ;
2965
2978
// Parse `self` or `self: TYPE`. We already know the current token is `self`.
2966
2979
let parse_self_possibly_typed = |this : & mut Self , m| {
2967
2980
let eself_ident = expect_self_ident ( this) ;
@@ -3012,26 +3025,35 @@ impl<'a> Parser<'a> {
3012
3025
let eself_lo = self . token . span ;
3013
3026
let ( eself, eself_ident, eself_hi) = match self . token . uninterpolate ( ) . kind {
3014
3027
token:: And => {
3015
- let eself = if is_isolated_self ( self , 1 ) {
3016
- // `&self`
3017
- self . bump ( ) ;
3018
- SelfKind :: Region ( None , Mutability :: Not )
3019
- } else if is_isolated_mut_self ( self , 1 ) {
3020
- // `&mut self`
3021
- self . bump ( ) ;
3022
- self . bump ( ) ;
3023
- SelfKind :: Region ( None , Mutability :: Mut )
3024
- } else if self . look_ahead ( 1 , |t| t. is_lifetime ( ) ) && is_isolated_self ( self , 2 ) {
3025
- // `&'lt self`
3026
- self . bump ( ) ;
3027
- let lt = self . expect_lifetime ( ) ;
3028
- SelfKind :: Region ( Some ( lt) , Mutability :: Not )
3029
- } else if self . look_ahead ( 1 , |t| t. is_lifetime ( ) ) && is_isolated_mut_self ( self , 2 ) {
3030
- // `&'lt mut self`
3031
- self . bump ( ) ;
3032
- let lt = self . expect_lifetime ( ) ;
3033
- self . bump ( ) ;
3034
- SelfKind :: Region ( Some ( lt) , Mutability :: Mut )
3028
+ let has_lifetime = is_lifetime ( self , 1 ) ;
3029
+ let skip_lifetime_count = has_lifetime as usize ;
3030
+ let eself = if is_isolated_self ( self , skip_lifetime_count + 1 ) {
3031
+ // `&{'lt} self`
3032
+ self . bump ( ) ; // &
3033
+ let lifetime = has_lifetime. then ( || self . expect_lifetime ( ) ) ;
3034
+ SelfKind :: Region ( lifetime, Mutability :: Not )
3035
+ } else if is_isolated_mut_self ( self , skip_lifetime_count + 1 ) {
3036
+ // `&{'lt} mut self`
3037
+ self . bump ( ) ; // &
3038
+ let lifetime = has_lifetime. then ( || self . expect_lifetime ( ) ) ;
3039
+ self . bump ( ) ; // mut
3040
+ SelfKind :: Region ( lifetime, Mutability :: Mut )
3041
+ } else if is_isolated_pin_const_self ( self , skip_lifetime_count + 1 ) {
3042
+ // `&{'lt} pin const self`
3043
+ self . bump ( ) ; // &
3044
+ let lifetime = has_lifetime. then ( || self . expect_lifetime ( ) ) ;
3045
+ self . psess . gated_spans . gate ( sym:: pin_ergonomics, self . token . span ) ;
3046
+ self . bump ( ) ; // pin
3047
+ self . bump ( ) ; // const
3048
+ SelfKind :: Pinned ( lifetime, Mutability :: Not )
3049
+ } else if is_isolated_pin_mut_self ( self , skip_lifetime_count + 1 ) {
3050
+ // `&{'lt} pin mut self`
3051
+ self . bump ( ) ; // &
3052
+ let lifetime = has_lifetime. then ( || self . expect_lifetime ( ) ) ;
3053
+ self . psess . gated_spans . gate ( sym:: pin_ergonomics, self . token . span ) ;
3054
+ self . bump ( ) ; // pin
3055
+ self . bump ( ) ; // mut
3056
+ SelfKind :: Pinned ( lifetime, Mutability :: Mut )
3035
3057
} else {
3036
3058
// `¬_self`
3037
3059
return Ok ( None ) ;
0 commit comments