@@ -5,7 +5,7 @@ use rustc_ast::{
55} ;
66use rustc_errors:: { Applicability , PResult } ;
77use rustc_span:: Span ;
8- use rustc_span:: symbol:: { Ident , kw} ;
8+ use rustc_span:: symbol:: { Ident , kw, sym } ;
99use thin_vec:: ThinVec ;
1010
1111use super :: { ForceCollect , Parser , Trailing , UsePreAttrPos } ;
@@ -300,21 +300,34 @@ impl<'a> Parser<'a> {
300300 /// Parses a rustc-internal fn contract
301301 /// (`rustc_contract_requires(WWW) rustc_contract_ensures(ZZZ)`)
302302 pub ( super ) fn parse_contract ( & mut self ) -> PResult < ' a , Option < rustc_ast:: ptr:: P < ast:: FnContract > > > {
303- let requires = if self . eat_keyword ( kw:: RustcContractRequires ) {
304- Some ( self . parse_expr ( ) ?)
303+ let gate = |span| {
304+ if self . psess . contract_attribute_spans . contains ( span) {
305+ // span was generated via a builtin contracts attribute, so gate as end-user visible
306+ self . psess . gated_spans . gate ( sym:: rustc_contracts, span) ;
307+ } else {
308+ // span was not generated via a builtin contracts attribute, so gate as internal machinery
309+ self . psess . gated_spans . gate ( sym:: rustc_contracts_internals, span) ;
310+ }
311+ } ;
312+ let requires = if self . eat_keyword ( kw:: RustcContractRequires ) {
313+ let precond = self . parse_expr ( ) ?;
314+ gate ( precond. span ) ;
315+ Some ( precond)
305316 } else {
306317 None
307318 } ;
308319 let ensures = if self . eat_keyword ( kw:: RustcContractEnsures ) {
309- Some ( self . parse_expr ( ) ?)
320+ let postcond = self . parse_expr ( ) ?;
321+ gate ( postcond. span ) ;
322+ Some ( postcond)
310323 } else {
311324 None
312325 } ;
313326 if requires. is_none ( ) && ensures. is_none ( ) {
314327 Ok ( None )
315328 } else {
316329 Ok ( Some ( rustc_ast:: ptr:: P ( ast:: FnContract { requires, ensures } ) ) )
317- }
330+ }
318331 }
319332
320333 /// Parses an optional where-clause.
0 commit comments