diff options
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/parser/generics.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/token_type.rs | 8 |
3 files changed, 39 insertions, 4 deletions
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index b1b84b0b701..d5ac8d1588d 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -297,6 +297,28 @@ impl<'a> Parser<'a> { }) } + /// Parses a rustc-internal fn contract + /// (`rustc_contract_requires(WWW) rustc_contract_ensures(ZZZ)`) + pub(super) fn parse_contract( + &mut self, + ) -> PResult<'a, Option<rustc_ast::ptr::P<ast::FnContract>>> { + let requires = if self.eat_keyword_noexpect(exp!(RustcContractRequires).kw) { + Some(self.parse_expr()?) + } else { + None + }; + let ensures = if self.eat_keyword_noexpect(exp!(RustcContractEnsures).kw) { + Some(self.parse_expr()?) + } else { + None + }; + if requires.is_none() && ensures.is_none() { + Ok(None) + } else { + Ok(Some(rustc_ast::ptr::P(ast::FnContract { requires, ensures }))) + } + } + /// Parses an optional where-clause. /// /// ```ignore (only-for-syntax-highlight) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index f3e56be9f6e..dbdc31f06a2 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -213,9 +213,12 @@ impl<'a> Parser<'a> { self.parse_use_item()? } else if self.check_fn_front_matter(check_pub, case) { // FUNCTION ITEM - let (ident, sig, generics, body) = + let (ident, sig, generics, contract, body) = self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?; - (ident, ItemKind::Fn(Box::new(Fn { defaultness: def_(), sig, generics, body }))) + ( + ident, + ItemKind::Fn(Box::new(Fn { defaultness: def_(), sig, generics, contract, body })), + ) } else if self.eat_keyword(exp!(Extern)) { if self.eat_keyword(exp!(Crate)) { // EXTERN CRATE @@ -2372,7 +2375,7 @@ impl<'a> Parser<'a> { sig_lo: Span, vis: &Visibility, case: Case, - ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<Block>>)> { + ) -> PResult<'a, (Ident, FnSig, Generics, Option<P<FnContract>>, Option<P<Block>>)> { let fn_span = self.token.span; let header = self.parse_fn_front_matter(vis, case)?; // `const ... fn` let ident = self.parse_ident()?; // `foo` @@ -2398,6 +2401,8 @@ impl<'a> Parser<'a> { // inside `parse_fn_body()`. let fn_params_end = self.prev_token.span.shrink_to_hi(); + let contract = self.parse_contract()?; + generics.where_clause = self.parse_where_clause()?; // `where T: Ord` // `fn_params_end` is needed only when it's followed by a where clause. @@ -2409,7 +2414,7 @@ impl<'a> Parser<'a> { let body = self.parse_fn_body(attrs, &ident, &mut sig_hi, fn_parse_mode.req_body, fn_params_end)?; let fn_sig_span = sig_lo.to(sig_hi); - Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, body)) + Ok((ident, FnSig { header, decl, span: fn_sig_span }, generics, contract, body)) } /// Provide diagnostics when function body is not found diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs index 73f3ac001c8..50f03e72f82 100644 --- a/compiler/rustc_parse/src/parser/token_type.rs +++ b/compiler/rustc_parse/src/parser/token_type.rs @@ -108,6 +108,8 @@ pub enum TokenType { KwRef, KwReturn, KwReuse, + KwRustcContractEnsures, + KwRustcContractRequires, KwSafe, KwSelfUpper, KwStatic, @@ -242,6 +244,8 @@ impl TokenType { KwRef, KwReturn, KwReuse, + KwRustcContractEnsures, + KwRustcContractRequires, KwSafe, KwSelfUpper, KwStatic, @@ -314,6 +318,8 @@ impl TokenType { TokenType::KwRef => Some(kw::Ref), TokenType::KwReturn => Some(kw::Return), TokenType::KwReuse => Some(kw::Reuse), + TokenType::KwRustcContractEnsures => Some(kw::RustcContractEnsures), + TokenType::KwRustcContractRequires => Some(kw::RustcContractRequires), TokenType::KwSafe => Some(kw::Safe), TokenType::KwSelfUpper => Some(kw::SelfUpper), TokenType::KwStatic => Some(kw::Static), @@ -544,6 +550,8 @@ macro_rules! exp { (Ref) => { exp!(@kw, Ref, KwRef) }; (Return) => { exp!(@kw, Return, KwReturn) }; (Reuse) => { exp!(@kw, Reuse, KwReuse) }; + (RustcContractEnsures) => { exp!(@kw, RustcContractEnsures, KwRustcContractEnsures) }; + (RustcContractRequires) => { exp!(@kw, RustcContractRequires, KwRustcContractRequires) }; (Safe) => { exp!(@kw, Safe, KwSafe) }; (SelfUpper) => { exp!(@kw, SelfUpper, KwSelfUpper) }; (Static) => { exp!(@kw, Static, KwStatic) }; |
