about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-17 11:18:57 +0000
committerbors <bors@rust-lang.org>2024-10-17 11:18:57 +0000
commite09bf4c07af8a424f9022bfe8d42ec714a51f0be (patch)
tree0aa83217a4da4a550ed80601e35381bb06db1c33 /compiler/rustc_parse/src/parser
parentecf6fc5336a7fe24607b8c394f34a4fcd20079c8 (diff)
parent6e4f8fea36cd04f623c46d99adc3c370b1879883 (diff)
downloadrust-e09bf4c07af8a424f9022bfe8d42ec714a51f0be.tar.gz
rust-e09bf4c07af8a424f9022bfe8d42ec714a51f0be.zip
Auto merge of #18317 - lnicola:sync-from-rust, r=Veykril
minor: sync from downstream
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs2
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs7
-rw-r--r--compiler/rustc_parse/src/parser/item.rs6
-rw-r--r--compiler/rustc_parse/src/parser/path.rs4
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs99
5 files changed, 57 insertions, 61 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index f32307f6ed4..a9384501547 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -2113,7 +2113,7 @@ impl<'a> Parser<'a> {
             && let Some(poly) = bounds
                 .iter()
                 .filter_map(|bound| match bound {
-                    ast::GenericBound::Trait(poly, _) => Some(poly),
+                    ast::GenericBound::Trait(poly) => Some(poly),
                     _ => None,
                 })
                 .last()
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index b9256daa725..5aebe716b0a 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -269,6 +269,13 @@ impl<'a> Parser<'a> {
     ///                  | ( < lifetimes , typaramseq ( , )? > )
     /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
     pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
+        // invalid path separator `::` in function definition
+        // for example `fn invalid_path_separator::<T>() {}`
+        if self.eat_noexpect(&token::PathSep) {
+            self.dcx()
+                .emit_err(errors::InvalidPathSepInFnDefinition { span: self.prev_token.span });
+        }
+
         let span_lo = self.token.span;
         let (params, span) = if self.eat_lt() {
             let params = self.parse_generic_params()?;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 9fc82d84225..36733726564 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1984,7 +1984,7 @@ impl<'a> Parser<'a> {
             }
         }
         self.expect_field_ty_separator()?;
-        let ty = self.parse_ty_for_field_def()?;
+        let ty = self.parse_ty()?;
         if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) {
             self.dcx().emit_err(errors::SingleColonStructType { span: self.token.span });
         }
@@ -2009,9 +2009,7 @@ impl<'a> Parser<'a> {
     /// for better diagnostics and suggestions.
     fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
         let (ident, is_raw) = self.ident_or_err(true)?;
-        if ident.name == kw::Underscore {
-            self.psess.gated_spans.gate(sym::unnamed_fields, lo);
-        } else if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
+        if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() {
             let snapshot = self.create_snapshot_for_diagnostic();
             let err = if self.check_fn_front_matter(false, Case::Sensitive) {
                 let inherited_vis =
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 162ff3b94de..2f19a9b6b20 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -948,8 +948,8 @@ impl<'a> Parser<'a> {
             {
                 return Ok((false, seg.ident, seg.args.as_deref().cloned()));
             } else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
-                && let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE)] =
-                    bounds.as_slice()
+                && let [ast::GenericBound::Trait(trait_ref)] = bounds.as_slice()
+                && trait_ref.modifiers == ast::TraitBoundModifiers::NONE
                 && let [seg] = trait_ref.trait_ref.path.segments.as_slice()
             {
                 return Ok((true, seg.ident, seg.args.as_deref().cloned()));
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index a8ed8b5df9c..c561ea3823d 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -4,7 +4,8 @@ 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,
+    Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty,
+    TyKind,
 };
 use rustc_errors::{Applicability, PResult};
 use rustc_span::symbol::{Ident, kw, sym};
@@ -128,17 +129,6 @@ impl<'a> Parser<'a> {
         )
     }
 
-    /// Parse a type suitable for a field definition.
-    /// The difference from `parse_ty` is that this version
-    /// allows anonymous structs and unions.
-    pub(super) fn parse_ty_for_field_def(&mut self) -> PResult<'a, P<Ty>> {
-        if self.can_begin_anon_struct_or_union() {
-            self.parse_anon_struct_or_union()
-        } else {
-            self.parse_ty()
-        }
-    }
-
     /// Parse a type suitable for a function or function pointer parameter.
     /// The difference from `parse_ty` is that this version allows `...`
     /// (`CVarArgs`) at the top level of the type.
@@ -382,37 +372,6 @@ impl<'a> Parser<'a> {
         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
     }
 
-    /// Parse an anonymous struct or union (only for field definitions):
-    /// ```ignore (feature-not-ready)
-    /// #[repr(C)]
-    /// struct Foo {
-    ///     _: struct { // anonymous struct
-    ///         x: u32,
-    ///         y: f64,
-    ///     }
-    ///     _: union { // anonymous union
-    ///         z: u32,
-    ///         w: f64,
-    ///     }
-    /// }
-    /// ```
-    fn parse_anon_struct_or_union(&mut self) -> PResult<'a, P<Ty>> {
-        assert!(self.token.is_keyword(kw::Union) || self.token.is_keyword(kw::Struct));
-        let is_union = self.token.is_keyword(kw::Union);
-
-        let lo = self.token.span;
-        self.bump();
-
-        let (fields, _recovered) =
-            self.parse_record_struct_body(if is_union { "union" } else { "struct" }, lo, false)?;
-        let span = lo.to(self.prev_token.span);
-        self.psess.gated_spans.gate(sym::unnamed_fields, span);
-        let id = ast::DUMMY_NODE_ID;
-        let kind =
-            if is_union { TyKind::AnonUnion(id, fields) } else { TyKind::AnonStruct(id, fields) };
-        Ok(self.mk_ty(span, kind))
-    }
-
     /// Parses either:
     /// - `(TYPE)`, a parenthesized type.
     /// - `(TYPE,)`, a tuple with a single field of type TYPE.
@@ -461,8 +420,13 @@ impl<'a> Parser<'a> {
         lo: Span,
         parse_plus: bool,
     ) -> PResult<'a, TyKind> {
-        let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
-        let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifiers::NONE)];
+        let poly_trait_ref = PolyTraitRef::new(
+            generic_params,
+            path,
+            TraitBoundModifiers::NONE,
+            lo.to(self.prev_token.span),
+        );
+        let bounds = vec![GenericBound::Trait(poly_trait_ref)];
         self.parse_remaining_bounds(bounds, parse_plus)
     }
 
@@ -529,7 +493,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 +532,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)`.
@@ -813,11 +808,6 @@ impl<'a> Parser<'a> {
         Ok(bounds)
     }
 
-    pub(super) fn can_begin_anon_struct_or_union(&mut self) -> bool {
-        (self.token.is_keyword(kw::Struct) || self.token.is_keyword(kw::Union))
-            && self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace))
-    }
-
     /// Can the current token begin a bound?
     fn can_begin_bound(&mut self) -> bool {
         self.check_path()
@@ -1132,8 +1122,9 @@ impl<'a> Parser<'a> {
             }
         }
 
-        let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span));
-        Ok(GenericBound::Trait(poly_trait, modifiers))
+        let poly_trait =
+            PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span));
+        Ok(GenericBound::Trait(poly_trait))
     }
 
     // recovers a `Fn(..)` parenthesized-style path from `fn(..)`