diff options
| author | Eric Holk <ericholk@microsoft.com> | 2024-09-20 12:09:18 -0700 |
|---|---|---|
| committer | Eric Holk <ericholk@microsoft.com> | 2024-10-07 11:15:04 -0700 |
| commit | ae698f819935aae8623f41aa3837cc0a07903c1a (patch) | |
| tree | c13cb2f6aa92365689a10cbc4cbe8a297a5ba382 /compiler/rustc_parse/src/parser | |
| parent | 7caad6925314911eefe54b040d4bc5be940e8f92 (diff) | |
| download | rust-ae698f819935aae8623f41aa3837cc0a07903c1a.tar.gz rust-ae698f819935aae8623f41aa3837cc0a07903c1a.zip | |
Add sugar for &pin (const|mut) types
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index a8ed8b5df9c..ccd6dfda797 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -2,9 +2,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy, - GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, - PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, + self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{Ident, kw, sym}; @@ -529,7 +527,10 @@ impl<'a> Parser<'a> { fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { let and_span = self.prev_token.span; let mut opt_lifetime = self.check_lifetime().then(|| self.expect_lifetime()); - let mut mutbl = self.parse_mutability(); + let (pinned, mut mutbl) = match self.parse_pin_and_mut() { + Some(pin_mut) => pin_mut, + None => (Pinnedness::Not, self.parse_mutability()), + }; if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() { // A lifetime is invalid here: it would be part of a bare trait bound, which requires // it to be followed by a plus, but we disallow plus in the pointee type. @@ -565,7 +566,35 @@ impl<'a> Parser<'a> { self.bump_with((dyn_tok, dyn_tok_sp)); } let ty = self.parse_ty_no_plus()?; - Ok(TyKind::Ref(opt_lifetime, MutTy { ty, mutbl })) + Ok(match pinned { + Pinnedness::Not => TyKind::Ref(opt_lifetime, MutTy { ty, mutbl }), + Pinnedness::Pinned => TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl }), + }) + } + + /// Parses `pin` and `mut` annotations on references. + /// + /// It must be either `pin const` or `pin mut`. + pub(crate) fn parse_pin_and_mut(&mut self) -> Option<(Pinnedness, Mutability)> { + if self.token.is_ident_named(sym::pin) { + let result = self.look_ahead(1, |token| { + if token.is_keyword(kw::Const) { + Some((Pinnedness::Pinned, Mutability::Not)) + } else if token.is_keyword(kw::Mut) { + Some((Pinnedness::Pinned, Mutability::Mut)) + } else { + None + } + }); + if result.is_some() { + self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span); + self.bump(); + self.bump(); + } + result + } else { + None + } } // Parses the `typeof(EXPR)`. |
