about summary refs log tree commit diff
path: root/compiler/rustc_parse
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse')
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs20
1 files changed, 17 insertions, 3 deletions
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index d5ac8d1588d..14b949dbc3d 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -4,7 +4,7 @@ use rustc_ast::{
     WhereClause, token,
 };
 use rustc_errors::{Applicability, PResult};
-use rustc_span::{Ident, Span, kw};
+use rustc_span::{Ident, Span, kw, sym};
 use thin_vec::ThinVec;
 
 use super::{ForceCollect, Parser, Trailing, UsePreAttrPos};
@@ -302,13 +302,27 @@ impl<'a> Parser<'a> {
     pub(super) fn parse_contract(
         &mut self,
     ) -> PResult<'a, Option<rustc_ast::ptr::P<ast::FnContract>>> {
+        let gate = |span| {
+            if self.psess.contract_attribute_spans.contains(span) {
+                // span was generated via a builtin contracts attribute, so gate as end-user visible
+                self.psess.gated_spans.gate(sym::rustc_contracts, span);
+            } else {
+                // span was not generated via a builtin contracts attribute, so gate as internal machinery
+                self.psess.gated_spans.gate(sym::rustc_contracts_internals, span);
+            }
+        };
+
         let requires = if self.eat_keyword_noexpect(exp!(RustcContractRequires).kw) {
-            Some(self.parse_expr()?)
+            let precond = self.parse_expr()?;
+            gate(precond.span);
+            Some(precond)
         } else {
             None
         };
         let ensures = if self.eat_keyword_noexpect(exp!(RustcContractEnsures).kw) {
-            Some(self.parse_expr()?)
+            let postcond = self.parse_expr()?;
+            gate(postcond.span);
+            Some(postcond)
         } else {
             None
         };