about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse/src/parser')
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs18
-rw-r--r--compiler/rustc_parse/src/parser/path.rs29
2 files changed, 34 insertions, 13 deletions
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 860e63020bb..42a13376863 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -5,7 +5,7 @@ use rustc_ast::{
     self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause,
 };
 use rustc_errors::PResult;
-use rustc_span::symbol::kw;
+use rustc_span::symbol::{kw, sym};
 
 impl<'a> Parser<'a> {
     /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@@ -56,12 +56,26 @@ impl<'a> Parser<'a> {
         self.expect(&token::Colon)?;
         let ty = self.parse_ty()?;
 
+        // Parse optional const generics default value, taking care of feature gating the spans
+        // with the unstable syntax mechanism.
+        let default = if self.eat(&token::Eq) {
+            // The gated span goes from the `=` to the end of the const argument that follows (and
+            // which could be a block expression).
+            let start = self.prev_token.span;
+            let const_arg = self.parse_const_arg()?;
+            let span = start.to(const_arg.value.span);
+            self.sess.gated_spans.gate(sym::const_generics_defaults, span);
+            Some(const_arg)
+        } else {
+            None
+        };
+
         Ok(GenericParam {
             ident,
             id: ast::DUMMY_NODE_ID,
             attrs: preceding_attrs.into(),
             bounds: Vec::new(),
-            kind: GenericParamKind::Const { ty, kw_span: const_span },
+            kind: GenericParamKind::Const { ty, kw_span: const_span, default },
             is_placeholder: false,
         })
     }
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 60a47ca12b8..43dee391c17 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -515,6 +515,23 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Parse a const argument, e.g. `<3>`. It is assumed the angle brackets will be parsed by
+    /// the caller.
+    pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> {
+        // Parse const argument.
+        let value = if let token::OpenDelim(token::Brace) = self.token.kind {
+            self.parse_block_expr(
+                None,
+                self.token.span,
+                BlockCheckMode::Default,
+                ast::AttrVec::new(),
+            )?
+        } else {
+            self.handle_unambiguous_unbraced_const_arg()?
+        };
+        Ok(AnonConst { id: ast::DUMMY_NODE_ID, value })
+    }
+
     /// Parse a generic argument in a path segment.
     /// This does not include constraints, e.g., `Item = u8`, which is handled in `parse_angle_arg`.
     fn parse_generic_arg(&mut self) -> PResult<'a, Option<GenericArg>> {
@@ -524,17 +541,7 @@ impl<'a> Parser<'a> {
             GenericArg::Lifetime(self.expect_lifetime())
         } else if self.check_const_arg() {
             // Parse const argument.
-            let value = if let token::OpenDelim(token::Brace) = self.token.kind {
-                self.parse_block_expr(
-                    None,
-                    self.token.span,
-                    BlockCheckMode::Default,
-                    ast::AttrVec::new(),
-                )?
-            } else {
-                self.handle_unambiguous_unbraced_const_arg()?
-            };
-            GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })
+            GenericArg::Const(self.parse_const_arg()?)
         } else if self.check_type() {
             // Parse type argument.
             match self.parse_ty() {