about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/errors.rs76
-rw-r--r--compiler/rustc_parse/src/lexer/unicode_chars.rs2
-rw-r--r--compiler/rustc_parse/src/lib.rs6
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs8
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs62
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs36
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs38
-rw-r--r--compiler/rustc_parse/src/parser/item.rs21
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs4
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs5
-rw-r--r--compiler/rustc_parse/src/parser/path.rs24
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs22
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs13
-rw-r--r--compiler/rustc_parse/src/parser/token_type.rs8
14 files changed, 199 insertions, 126 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 2373ab67d42..8f0e29c2769 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1121,23 +1121,29 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier {
         let token_descr = TokenDescription::from_token(&self.token);
 
         let mut add_token = true;
-        let mut diag = Diag::new(dcx, level, match token_descr {
-            Some(TokenDescription::ReservedIdentifier) => {
-                fluent::parse_expected_identifier_found_reserved_identifier_str
-            }
-            Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str,
-            Some(TokenDescription::ReservedKeyword) => {
-                fluent::parse_expected_identifier_found_reserved_keyword_str
-            }
-            Some(TokenDescription::DocComment) => {
-                fluent::parse_expected_identifier_found_doc_comment_str
-            }
-            Some(TokenDescription::MetaVar(_)) => {
-                add_token = false;
-                fluent::parse_expected_identifier_found_metavar_str
-            }
-            None => fluent::parse_expected_identifier_found_str,
-        });
+        let mut diag = Diag::new(
+            dcx,
+            level,
+            match token_descr {
+                Some(TokenDescription::ReservedIdentifier) => {
+                    fluent::parse_expected_identifier_found_reserved_identifier_str
+                }
+                Some(TokenDescription::Keyword) => {
+                    fluent::parse_expected_identifier_found_keyword_str
+                }
+                Some(TokenDescription::ReservedKeyword) => {
+                    fluent::parse_expected_identifier_found_reserved_keyword_str
+                }
+                Some(TokenDescription::DocComment) => {
+                    fluent::parse_expected_identifier_found_doc_comment_str
+                }
+                Some(TokenDescription::MetaVar(_)) => {
+                    add_token = false;
+                    fluent::parse_expected_identifier_found_metavar_str
+                }
+                None => fluent::parse_expected_identifier_found_str,
+            },
+        );
         diag.span(self.span);
         if add_token {
             diag.arg("token", self.token);
@@ -1182,21 +1188,27 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi {
         let token_descr = TokenDescription::from_token(&self.token);
 
         let mut add_token = true;
-        let mut diag = Diag::new(dcx, level, match token_descr {
-            Some(TokenDescription::ReservedIdentifier) => {
-                fluent::parse_expected_semi_found_reserved_identifier_str
-            }
-            Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
-            Some(TokenDescription::ReservedKeyword) => {
-                fluent::parse_expected_semi_found_reserved_keyword_str
-            }
-            Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
-            Some(TokenDescription::MetaVar(_)) => {
-                add_token = false;
-                fluent::parse_expected_semi_found_metavar_str
-            }
-            None => fluent::parse_expected_semi_found_str,
-        });
+        let mut diag = Diag::new(
+            dcx,
+            level,
+            match token_descr {
+                Some(TokenDescription::ReservedIdentifier) => {
+                    fluent::parse_expected_semi_found_reserved_identifier_str
+                }
+                Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
+                Some(TokenDescription::ReservedKeyword) => {
+                    fluent::parse_expected_semi_found_reserved_keyword_str
+                }
+                Some(TokenDescription::DocComment) => {
+                    fluent::parse_expected_semi_found_doc_comment_str
+                }
+                Some(TokenDescription::MetaVar(_)) => {
+                    add_token = false;
+                    fluent::parse_expected_semi_found_metavar_str
+                }
+                None => fluent::parse_expected_semi_found_str,
+            },
+        );
         diag.span(self.span);
         if add_token {
             diag.arg("token", self.token);
diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index ef8d0f96b61..648a352efd9 100644
--- a/compiler/rustc_parse/src/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -8,7 +8,7 @@ use crate::errors::TokenSubstitution;
 use crate::token::{self, Delimiter};
 
 #[rustfmt::skip] // for line breaks
-pub(super) const UNICODE_ARRAY: &[(char, &str, &str)] = &[
+pub(super) static UNICODE_ARRAY: &[(char, &str, &str)] = &[
     ('
', "Line Separator", " "),
     ('
', "Paragraph Separator", " "),
     (' ', "Ogham Space mark", " "),
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index e681987ff07..1a104ff5e33 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -17,12 +17,12 @@
 
 use std::path::{Path, PathBuf};
 use std::str::Utf8Error;
+use std::sync::Arc;
 
 use rustc_ast as ast;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{AttrItem, Attribute, MetaItemInner, token};
 use rustc_ast_pretty::pprust;
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Diag, EmissionGuarantee, FatalError, PResult, pluralize};
 use rustc_session::parse::ParseSess;
 use rustc_span::source_map::SourceMap;
@@ -147,7 +147,7 @@ pub fn utf8_error<E: EmissionGuarantee>(
 /// the initial token stream.
 fn new_parser_from_source_file(
     psess: &ParseSess,
-    source_file: Lrc<SourceFile>,
+    source_file: Arc<SourceFile>,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
     let end_pos = source_file.end_position();
     let stream = source_file_to_stream(psess, source_file, None)?;
@@ -172,7 +172,7 @@ pub fn source_str_to_stream(
 /// parsing the token stream.
 fn source_file_to_stream<'psess>(
     psess: &'psess ParseSess,
-    source_file: Lrc<SourceFile>,
+    source_file: Arc<SourceFile>,
     override_span: Option<Span>,
 ) -> Result<TokenStream, Vec<Diag<'psess>>> {
     let src = source_file.src.as_ref().unwrap_or_else(|| {
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 434f71beac2..cff998fa137 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -502,10 +502,10 @@ fn make_attr_token_stream(
     for flat_token in iter {
         match flat_token {
             FlatToken::Token((Token { kind: TokenKind::OpenDelim(delim), span }, spacing)) => {
-                stack_rest.push(mem::replace(&mut stack_top, FrameData {
-                    open_delim_sp: Some((delim, span, spacing)),
-                    inner: vec![],
-                }));
+                stack_rest.push(mem::replace(
+                    &mut stack_top,
+                    FrameData { open_delim_sp: Some((delim, span, spacing)), inner: vec![] },
+                ));
             }
             FlatToken::Token((Token { kind: TokenKind::CloseDelim(delim), span }, spacing)) => {
                 let frame_data = mem::replace(&mut stack_top, stack_rest.pop().unwrap());
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 9ee6c2fae1a..72aebb5d121 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1,5 +1,6 @@
 use std::mem::take;
 use std::ops::{Deref, DerefMut};
+use std::sync::Arc;
 
 use ast::token::IdentIsRaw;
 use rustc_ast as ast;
@@ -14,7 +15,6 @@ use rustc_ast::{
 };
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, PResult, Subdiagnostic, Suggestions,
     pluralize,
@@ -684,12 +684,15 @@ impl<'a> Parser<'a> {
             let span = self.token.span.with_lo(pos).with_hi(pos);
             err.span_suggestion_verbose(
                 span,
-                format!("add a space before {} to write a regular comment", match (kind, style) {
-                    (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`",
-                    (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`",
-                    (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`",
-                    (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`",
-                },),
+                format!(
+                    "add a space before {} to write a regular comment",
+                    match (kind, style) {
+                        (token::CommentKind::Line, ast::AttrStyle::Inner) => "`!`",
+                        (token::CommentKind::Block, ast::AttrStyle::Inner) => "`!`",
+                        (token::CommentKind::Line, ast::AttrStyle::Outer) => "the last `/`",
+                        (token::CommentKind::Block, ast::AttrStyle::Outer) => "the last `*`",
+                    },
+                ),
                 " ".to_string(),
                 Applicability::MachineApplicable,
             );
@@ -1894,13 +1897,14 @@ impl<'a> Parser<'a> {
             (token::Eof, None) => (self.prev_token.span, self.token.span),
             _ => (self.prev_token.span.shrink_to_hi(), self.token.span),
         };
-        let msg = format!("expected `{}`, found {}", token_str, match (
-            &self.token.kind,
-            self.subparser_name
-        ) {
-            (token::Eof, Some(origin)) => format!("end of {origin}"),
-            _ => this_token_str,
-        },);
+        let msg = format!(
+            "expected `{}`, found {}",
+            token_str,
+            match (&self.token.kind, self.subparser_name) {
+                (token::Eof, Some(origin)) => format!("end of {origin}"),
+                _ => this_token_str,
+            },
+        );
         let mut err = self.dcx().struct_span_err(sp, msg);
         let label_exp = format!("expected `{token_str}`");
         let sm = self.psess.source_map();
@@ -2403,7 +2407,7 @@ impl<'a> Parser<'a> {
         let mut labels = vec![];
         while let TokenKind::Interpolated(nt) = &tok.kind {
             let tokens = nt.tokens();
-            labels.push(Lrc::clone(nt));
+            labels.push(Arc::clone(nt));
             if let Some(tokens) = tokens
                 && let tokens = tokens.to_attr_token_stream()
                 && let tokens = tokens.0.deref()
@@ -2826,25 +2830,27 @@ impl<'a> Parser<'a> {
                             PatKind::Ident(BindingMode::NONE, ident, None) => {
                                 match &first_pat.kind {
                                     PatKind::Ident(_, old_ident, _) => {
-                                        let path = PatKind::Path(None, Path {
-                                            span: new_span,
-                                            segments: thin_vec![
-                                                PathSegment::from_ident(*old_ident),
-                                                PathSegment::from_ident(*ident),
-                                            ],
-                                            tokens: None,
-                                        });
+                                        let path = PatKind::Path(
+                                            None,
+                                            Path {
+                                                span: new_span,
+                                                segments: thin_vec![
+                                                    PathSegment::from_ident(*old_ident),
+                                                    PathSegment::from_ident(*ident),
+                                                ],
+                                                tokens: None,
+                                            },
+                                        );
                                         first_pat = self.mk_pat(new_span, path);
                                         show_sugg = true;
                                     }
                                     PatKind::Path(old_qself, old_path) => {
                                         let mut segments = old_path.segments.clone();
                                         segments.push(PathSegment::from_ident(*ident));
-                                        let path = PatKind::Path(old_qself.clone(), Path {
-                                            span: new_span,
-                                            segments,
-                                            tokens: None,
-                                        });
+                                        let path = PatKind::Path(
+                                            old_qself.clone(),
+                                            Path { span: new_span, segments, tokens: None },
+                                        );
                                         first_pat = self.mk_pat(new_span, path);
                                         show_sugg = true;
                                     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ffd46f20767..e0e6c2177da 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -807,17 +807,20 @@ impl<'a> Parser<'a> {
         // Check if an illegal postfix operator has been added after the cast.
         // If the resulting expression is not a cast, it is an illegal postfix operator.
         if !matches!(with_postfix.kind, ExprKind::Cast(_, _)) {
-            let msg = format!("cast cannot be followed by {}", match with_postfix.kind {
-                ExprKind::Index(..) => "indexing",
-                ExprKind::Try(_) => "`?`",
-                ExprKind::Field(_, _) => "a field access",
-                ExprKind::MethodCall(_) => "a method call",
-                ExprKind::Call(_, _) => "a function call",
-                ExprKind::Await(_, _) => "`.await`",
-                ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match",
-                ExprKind::Err(_) => return Ok(with_postfix),
-                _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
-            });
+            let msg = format!(
+                "cast cannot be followed by {}",
+                match with_postfix.kind {
+                    ExprKind::Index(..) => "indexing",
+                    ExprKind::Try(_) => "`?`",
+                    ExprKind::Field(_, _) => "a field access",
+                    ExprKind::MethodCall(_) => "a method call",
+                    ExprKind::Call(_, _) => "a function call",
+                    ExprKind::Await(_, _) => "`.await`",
+                    ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match",
+                    ExprKind::Err(_) => return Ok(with_postfix),
+                    _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
+                }
+            );
             let mut err = self.dcx().struct_span_err(span, msg);
 
             let suggest_parens = |err: &mut Diag<'_>| {
@@ -2862,13 +2865,10 @@ impl<'a> Parser<'a> {
                 .emit_err(errors::MissingExpressionInForLoop { span: expr.span.shrink_to_lo() });
             let err_expr = self.mk_expr(expr.span, ExprKind::Err(guar));
             let block = self.mk_block(thin_vec![], BlockCheckMode::Default, self.prev_token.span);
-            return Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::ForLoop {
-                pat,
-                iter: err_expr,
-                body: block,
-                label: opt_label,
-                kind,
-            }));
+            return Ok(self.mk_expr(
+                lo.to(self.prev_token.span),
+                ExprKind::ForLoop { pat, iter: err_expr, body: block, label: opt_label, kind },
+            ));
         }
 
         let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index b1b84b0b701..86816819be2 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};
@@ -297,6 +297,42 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Parses an experimental fn contract
+    /// (`contract_requires(WWW) contract_ensures(ZZZ)`)
+    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::contracts, span);
+            } else {
+                // span was not generated via a builtin contracts attribute, so gate as internal machinery
+                self.psess.gated_spans.gate(sym::contracts_internals, span);
+            }
+        };
+
+        let requires = if self.eat_keyword_noexpect(exp!(ContractRequires).kw) {
+            let precond = self.parse_expr()?;
+            gate(precond.span);
+            Some(precond)
+        } else {
+            None
+        };
+        let ensures = if self.eat_keyword_noexpect(exp!(ContractEnsures).kw) {
+            let postcond = self.parse_expr()?;
+            gate(postcond.span);
+            Some(postcond)
+        } 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..637ed2774a2 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
@@ -1951,10 +1954,10 @@ impl<'a> Parser<'a> {
                 // Try to recover extra trailing angle brackets
                 if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind {
                     if let Some(last_segment) = segments.last() {
-                        let guar = self.check_trailing_angle_brackets(last_segment, &[
-                            exp!(Comma),
-                            exp!(CloseBrace),
-                        ]);
+                        let guar = self.check_trailing_angle_brackets(
+                            last_segment,
+                            &[exp!(Comma), exp!(CloseBrace)],
+                        );
                         if let Some(_guar) = guar {
                             // Handle a case like `Vec<u8>>,` where we can continue parsing fields
                             // after the comma
@@ -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/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index faebb5a40bb..ea464fc8ebb 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -13,6 +13,7 @@ mod ty;
 
 use std::assert_matches::debug_assert_matches;
 use std::ops::Range;
+use std::sync::Arc;
 use std::{fmt, mem, slice};
 
 use attr_wrapper::{AttrWrapper, UsePreAttrPos};
@@ -34,7 +35,6 @@ use rustc_ast::{
 };
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, Diag, FatalError, MultiSpan, PResult};
 use rustc_index::interval::IntervalSet;
 use rustc_session::parse::ParseSess;
@@ -1685,5 +1685,5 @@ pub enum ParseNtResult {
     Lifetime(Ident, IdentIsRaw),
 
     /// This case will eventually be removed, along with `Token::Interpolate`.
-    Nt(Lrc<Nonterminal>),
+    Nt(Arc<Nonterminal>),
 }
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index 67cabb757e9..eefdb641da2 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -1,3 +1,5 @@
+use std::sync::Arc;
+
 use rustc_ast::HasTokens;
 use rustc_ast::ptr::P;
 use rustc_ast::token::Nonterminal::*;
@@ -7,7 +9,6 @@ use rustc_ast::token::{
     self, Delimiter, InvisibleOrigin, MetaVarKind, Nonterminal, NonterminalKind, Token,
 };
 use rustc_ast_pretty::pprust;
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::PResult;
 use rustc_span::{Ident, kw};
 
@@ -235,7 +236,7 @@ impl<'a> Parser<'a> {
             );
         }
 
-        Ok(ParseNtResult::Nt(Lrc::new(nt)))
+        Ok(ParseNtResult::Nt(Arc::new(nt)))
     }
 }
 
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 39737b9e137..576711e6677 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -106,11 +106,10 @@ impl<'a> Parser<'a> {
             self.parse_path_segments(&mut path.segments, style, None)?;
         }
 
-        Ok((qself, Path {
-            segments: path.segments,
-            span: lo.to(self.prev_token.span),
-            tokens: None,
-        }))
+        Ok((
+            qself,
+            Path { segments: path.segments, span: lo.to(self.prev_token.span), tokens: None },
+        ))
     }
 
     /// Recover from an invalid single colon, when the user likely meant a qualified path.
@@ -485,13 +484,16 @@ impl<'a> Parser<'a> {
 
         error.span_suggestion_verbose(
             prev_token_before_parsing.span,
-            format!("consider removing the `::` here to {}", match style {
-                PathStyle::Expr => "call the expression",
-                PathStyle::Pat => "turn this into a tuple struct pattern",
-                _ => {
-                    return;
+            format!(
+                "consider removing the `::` here to {}",
+                match style {
+                    PathStyle::Expr => "call the expression",
+                    PathStyle::Pat => "turn this into a tuple struct pattern",
+                    _ => {
+                        return;
+                    }
                 }
-            }),
+            ),
             "",
             Applicability::MaybeIncorrect,
         );
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 1ddb5fc0a11..a2699b077fc 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -417,14 +417,20 @@ impl<'a> Parser<'a> {
     fn check_let_else_init_trailing_brace(&self, init: &ast::Expr) {
         if let Some(trailing) = classify::expr_trailing_brace(init) {
             let (span, sugg) = match trailing {
-                TrailingBrace::MacCall(mac) => (mac.span(), errors::WrapInParentheses::MacroArgs {
-                    left: mac.args.dspan.open,
-                    right: mac.args.dspan.close,
-                }),
-                TrailingBrace::Expr(expr) => (expr.span, errors::WrapInParentheses::Expression {
-                    left: expr.span.shrink_to_lo(),
-                    right: expr.span.shrink_to_hi(),
-                }),
+                TrailingBrace::MacCall(mac) => (
+                    mac.span(),
+                    errors::WrapInParentheses::MacroArgs {
+                        left: mac.args.dspan.open,
+                        right: mac.args.dspan.close,
+                    },
+                ),
+                TrailingBrace::Expr(expr) => (
+                    expr.span,
+                    errors::WrapInParentheses::Expression {
+                        left: expr.span.shrink_to_lo(),
+                        right: expr.span.shrink_to_hi(),
+                    },
+                ),
             };
             self.dcx().emit_err(errors::InvalidCurlyInLetElse {
                 span: span.with_lo(span.hi() - BytePos(1)),
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index 655ab822359..8b8c81a77a0 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -13,7 +13,6 @@ use rustc_ast::token::{self, Delimiter, Token};
 use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
 use rustc_ast::{self as ast, PatKind, visit};
 use rustc_ast_pretty::pprust::item_to_string;
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::{HumanEmitter, OutputTheme};
 use rustc_errors::{DiagCtxt, MultiSpan, PResult};
 use rustc_session::parse::ParseSess;
@@ -27,7 +26,7 @@ use crate::parser::{ForceCollect, Parser};
 use crate::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
 
 fn psess() -> ParseSess {
-    ParseSess::new(vec![crate::DEFAULT_LOCALE_RESOURCE, crate::DEFAULT_LOCALE_RESOURCE])
+    ParseSess::new(vec![crate::DEFAULT_LOCALE_RESOURCE])
 }
 
 /// Map string to parser (via tts).
@@ -39,13 +38,11 @@ fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
     ))
 }
 
-fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
+fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Arc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
     let output = Arc::new(Mutex::new(Vec::new()));
-    let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-    let fallback_bundle = rustc_errors::fallback_fluent_bundle(
-        vec![crate::DEFAULT_LOCALE_RESOURCE, crate::DEFAULT_LOCALE_RESOURCE],
-        false,
-    );
+    let source_map = Arc::new(SourceMap::new(FilePathMapping::empty()));
+    let fallback_bundle =
+        rustc_errors::fallback_fluent_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false);
     let mut emitter = HumanEmitter::new(Box::new(Shared { data: output.clone() }), fallback_bundle)
         .sm(Some(source_map.clone()))
         .diagnostic_width(Some(140));
diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs
index 73f3ac001c8..40631d9154d 100644
--- a/compiler/rustc_parse/src/parser/token_type.rs
+++ b/compiler/rustc_parse/src/parser/token_type.rs
@@ -83,6 +83,8 @@ pub enum TokenType {
     KwCatch,
     KwConst,
     KwContinue,
+    KwContractEnsures,
+    KwContractRequires,
     KwCrate,
     KwDefault,
     KwDyn,
@@ -217,6 +219,8 @@ impl TokenType {
             KwCatch,
             KwConst,
             KwContinue,
+            KwContractEnsures,
+            KwContractRequires,
             KwCrate,
             KwDefault,
             KwDyn,
@@ -289,6 +293,8 @@ impl TokenType {
             TokenType::KwCatch => Some(kw::Catch),
             TokenType::KwConst => Some(kw::Const),
             TokenType::KwContinue => Some(kw::Continue),
+            TokenType::KwContractEnsures => Some(kw::ContractEnsures),
+            TokenType::KwContractRequires => Some(kw::ContractRequires),
             TokenType::KwCrate => Some(kw::Crate),
             TokenType::KwDefault => Some(kw::Default),
             TokenType::KwDyn => Some(kw::Dyn),
@@ -519,6 +525,8 @@ macro_rules! exp {
     (Catch)          => { exp!(@kw, Catch,      KwCatch) };
     (Const)          => { exp!(@kw, Const,      KwConst) };
     (Continue)       => { exp!(@kw, Continue,   KwContinue) };
+    (ContractEnsures)  => { exp!(@kw, ContractEnsures, KwContractEnsures) };
+    (ContractRequires) => { exp!(@kw, ContractRequires, KwContractRequires) };
     (Crate)          => { exp!(@kw, Crate,      KwCrate) };
     (Default)        => { exp!(@kw, Default,    KwDefault) };
     (Dyn)            => { exp!(@kw, Dyn,        KwDyn) };