From cb7d687e96151adc81c55fc48734497a2b48e79c Mon Sep 17 00:00:00 2001 From: Frank King Date: Sun, 19 Jan 2025 23:30:58 +0800 Subject: Implement `&pin const self` and `&pin mut self` sugars --- compiler/rustc_parse/src/parser/item.rs | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3f642a7ac1f..68a16a1c66b 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2959,9 +2959,20 @@ impl<'a> Parser<'a> { this.is_keyword_ahead(n, &[kw::SelfLower]) && this.look_ahead(n + 1, |t| t != &token::PathSep) }; + // Is `pin const self` `n` tokens ahead? + let is_isolated_pin_const_self = |this: &Self, n| { + this.look_ahead(n, |token| token.is_ident_named(sym::pin)) + && this.is_keyword_ahead(n + 1, &[kw::Const]) + && is_isolated_self(this, n + 2) + }; // Is `mut self` `n` tokens ahead? let is_isolated_mut_self = |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1); + // Is `pin mut self` `n` tokens ahead? + let is_isolated_pin_mut_self = |this: &Self, n| { + this.look_ahead(n, |token| token.is_ident_named(sym::pin)) + && is_isolated_mut_self(this, n + 1) + }; // Parse `self` or `self: TYPE`. We already know the current token is `self`. let parse_self_possibly_typed = |this: &mut Self, m| { let eself_ident = expect_self_ident(this); @@ -3021,6 +3032,20 @@ impl<'a> Parser<'a> { self.bump(); self.bump(); SelfKind::Region(None, Mutability::Mut) + } else if is_isolated_pin_const_self(self, 1) { + // `&pin const self` + self.bump(); // & + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); // pin + self.bump(); // const + SelfKind::Pinned(None, Mutability::Not) + } else if is_isolated_pin_mut_self(self, 1) { + // `&pin mut self` + self.bump(); // & + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); // pin + self.bump(); // mut + SelfKind::Pinned(None, Mutability::Mut) } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) { // `&'lt self` self.bump(); @@ -3032,6 +3057,26 @@ impl<'a> Parser<'a> { let lt = self.expect_lifetime(); self.bump(); SelfKind::Region(Some(lt), Mutability::Mut) + } else if self.look_ahead(1, |t| t.is_lifetime()) + && is_isolated_pin_const_self(self, 2) + { + // `&'lt pin const self` + self.bump(); // & + let lt = self.expect_lifetime(); + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); // pin + self.bump(); // const + SelfKind::Pinned(Some(lt), Mutability::Not) + } else if self.look_ahead(1, |t| t.is_lifetime()) + && is_isolated_pin_mut_self(self, 2) + { + // `&'lt pin mut self` + self.bump(); // & + let lt = self.expect_lifetime(); + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); // pin + self.bump(); // mut + SelfKind::Pinned(Some(lt), Mutability::Mut) } else { // `¬_self` return Ok(None); -- cgit 1.4.1-3-g733a5 From 52cd8746bab900aa38210d24c62352170b9f51f8 Mon Sep 17 00:00:00 2001 From: Frank King Date: Wed, 5 Mar 2025 22:13:22 +0800 Subject: Simplify `parse_self_param` --- compiler/rustc_parse/src/parser/item.rs | 63 +++++++++++---------------------- 1 file changed, 20 insertions(+), 43 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 68a16a1c66b..c3b1956ad2e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2954,6 +2954,8 @@ impl<'a> Parser<'a> { } _ => unreachable!(), }; + // is lifetime `n` tokens ahead? + let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime()); // Is `self` `n` tokens ahead? let is_isolated_self = |this: &Self, n| { this.is_keyword_ahead(n, &[kw::SelfLower]) @@ -3023,60 +3025,35 @@ impl<'a> Parser<'a> { let eself_lo = self.token.span; let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind { token::And => { - let eself = if is_isolated_self(self, 1) { - // `&self` - self.bump(); - SelfKind::Region(None, Mutability::Not) - } else if is_isolated_mut_self(self, 1) { - // `&mut self` - self.bump(); - self.bump(); - SelfKind::Region(None, Mutability::Mut) - } else if is_isolated_pin_const_self(self, 1) { - // `&pin const self` + let has_lifetime = is_lifetime(self, 1); + let skip_lifetime_count = has_lifetime as usize; + let eself = if is_isolated_self(self, skip_lifetime_count + 1) { + // `&{'lt} self` self.bump(); // & - self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); - self.bump(); // pin - self.bump(); // const - SelfKind::Pinned(None, Mutability::Not) - } else if is_isolated_pin_mut_self(self, 1) { - // `&pin mut self` + let lifetime = has_lifetime.then(|| self.expect_lifetime()); + SelfKind::Region(lifetime, Mutability::Not) + } else if is_isolated_mut_self(self, skip_lifetime_count + 1) { + // `&{'lt} mut self` self.bump(); // & - self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); - self.bump(); // pin + let lifetime = has_lifetime.then(|| self.expect_lifetime()); self.bump(); // mut - SelfKind::Pinned(None, Mutability::Mut) - } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) { - // `&'lt self` - self.bump(); - let lt = self.expect_lifetime(); - SelfKind::Region(Some(lt), Mutability::Not) - } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) { - // `&'lt mut self` - self.bump(); - let lt = self.expect_lifetime(); - self.bump(); - SelfKind::Region(Some(lt), Mutability::Mut) - } else if self.look_ahead(1, |t| t.is_lifetime()) - && is_isolated_pin_const_self(self, 2) - { - // `&'lt pin const self` + SelfKind::Region(lifetime, Mutability::Mut) + } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) { + // `&{'lt} pin const self` self.bump(); // & - let lt = self.expect_lifetime(); + let lifetime = has_lifetime.then(|| self.expect_lifetime()); self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); self.bump(); // pin self.bump(); // const - SelfKind::Pinned(Some(lt), Mutability::Not) - } else if self.look_ahead(1, |t| t.is_lifetime()) - && is_isolated_pin_mut_self(self, 2) - { - // `&'lt pin mut self` + SelfKind::Pinned(lifetime, Mutability::Not) + } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) { + // `&{'lt} pin mut self` self.bump(); // & - let lt = self.expect_lifetime(); + let lifetime = has_lifetime.then(|| self.expect_lifetime()); self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); self.bump(); // pin self.bump(); // mut - SelfKind::Pinned(Some(lt), Mutability::Mut) + SelfKind::Pinned(lifetime, Mutability::Mut) } else { // `¬_self` return Ok(None); -- cgit 1.4.1-3-g733a5