about summary refs log tree commit diff
path: root/compiler/rustc_parse
diff options
context:
space:
mode:
authorThe rustc-josh-sync Cronjob Bot <github-actions@github.com>2025-07-21 04:17:50 +0000
committerThe rustc-josh-sync Cronjob Bot <github-actions@github.com>2025-07-21 04:17:50 +0000
commitad20b064c30bbe9626e8c99f2b455cc6fd836d18 (patch)
tree1c8ac5ec462a793060ccc53aa22c33a0b9215640 /compiler/rustc_parse
parent897d007f8f2d4018fba5f2884cb1b45846d8a371 (diff)
parent460259d14de0274b97b8801e08cb2fe5f16fdac5 (diff)
downloadrust-ad20b064c30bbe9626e8c99f2b455cc6fd836d18.tar.gz
rust-ad20b064c30bbe9626e8c99f2b455cc6fd836d18.zip
Merge ref '460259d14de0' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh.

Upstream ref: 460259d14de0274b97b8801e08cb2fe5f16fdac5
Filtered ref: 599ee17eb87c83f97eb37fd9fe264da65d4c9461

This merge was created using https://github.com/rust-lang/josh-sync.
Diffstat (limited to 'compiler/rustc_parse')
-rw-r--r--compiler/rustc_parse/Cargo.toml2
-rw-r--r--compiler/rustc_parse/messages.ftl1
-rw-r--r--compiler/rustc_parse/src/errors.rs8
-rw-r--r--compiler/rustc_parse/src/lexer/diagnostics.rs20
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs15
-rw-r--r--compiler/rustc_parse/src/parser/item.rs28
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs1
7 files changed, 58 insertions, 17 deletions
diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml
index c4a0ae2ce9d..a92012f8329 100644
--- a/compiler/rustc_parse/Cargo.toml
+++ b/compiler/rustc_parse/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2024"
 [dependencies]
 # tidy-alphabetical-start
 bitflags = "2.4.1"
-rustc-literal-escaper = "0.0.4"
+rustc-literal-escaper = "0.0.5"
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index af9f8735549..859118a4ade 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -855,6 +855,7 @@ parse_trailing_vert_not_allowed = a trailing `|` is not allowed in an or-pattern
     .suggestion = remove the `{$token}`
 
 parse_trait_alias_cannot_be_auto = trait aliases cannot be `auto`
+parse_trait_alias_cannot_be_const = trait aliases cannot be `const`
 parse_trait_alias_cannot_be_unsafe = trait aliases cannot be `unsafe`
 
 parse_transpose_dyn_or_impl = `for<...>` expected after `{$kw}`, not before
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 7f1b0991f0c..4aaaba01fae 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1962,6 +1962,14 @@ pub(crate) struct TraitAliasCannotBeAuto {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_trait_alias_cannot_be_const)]
+pub(crate) struct TraitAliasCannotBeConst {
+    #[primary_span]
+    #[label(parse_trait_alias_cannot_be_const)]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_trait_alias_cannot_be_unsafe)]
 pub(crate) struct TraitAliasCannotBeUnsafe {
     #[primary_span]
diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs
index 0b97d4e6993..6de001fc998 100644
--- a/compiler/rustc_parse/src/lexer/diagnostics.rs
+++ b/compiler/rustc_parse/src/lexer/diagnostics.rs
@@ -34,9 +34,12 @@ pub(super) fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Sp
 
 // When we get a `)` or `]` for `{`, we should emit help message here
 // it's more friendly compared to report `unmatched error` in later phase
-fn report_missing_open_delim(err: &mut Diag<'_>, unmatched_delims: &[UnmatchedDelim]) -> bool {
+pub(super) fn report_missing_open_delim(
+    err: &mut Diag<'_>,
+    unmatched_delims: &mut Vec<UnmatchedDelim>,
+) -> bool {
     let mut reported_missing_open = false;
-    for unmatch_brace in unmatched_delims.iter() {
+    unmatched_delims.retain(|unmatch_brace| {
         if let Some(delim) = unmatch_brace.found_delim
             && matches!(delim, Delimiter::Parenthesis | Delimiter::Bracket)
         {
@@ -45,13 +48,20 @@ fn report_missing_open_delim(err: &mut Diag<'_>, unmatched_delims: &[UnmatchedDe
                 Delimiter::Bracket => "[",
                 _ => unreachable!(),
             };
+
+            if let Some(unclosed_span) = unmatch_brace.unclosed_span {
+                err.span_label(unclosed_span, "the nearest open delimiter");
+            }
             err.span_label(
                 unmatch_brace.found_span.shrink_to_lo(),
                 format!("missing open `{missed_open}` for this delimiter"),
             );
             reported_missing_open = true;
+            false
+        } else {
+            true
         }
-    }
+    });
     reported_missing_open
 }
 
@@ -61,10 +71,6 @@ pub(super) fn report_suspicious_mismatch_block(
     sm: &SourceMap,
     delim: Delimiter,
 ) {
-    if report_missing_open_delim(err, &diag_info.unmatched_delims) {
-        return;
-    }
-
     let mut matched_spans: Vec<(Span, bool)> = diag_info
         .matching_block_spans
         .iter()
diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs
index fbea958dcc5..64748199f28 100644
--- a/compiler/rustc_parse/src/lexer/tokentrees.rs
+++ b/compiler/rustc_parse/src/lexer/tokentrees.rs
@@ -3,7 +3,9 @@ use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, Toke
 use rustc_ast_pretty::pprust::token_to_string;
 use rustc_errors::Diag;
 
-use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level};
+use super::diagnostics::{
+    report_missing_open_delim, report_suspicious_mismatch_block, same_indentation_level,
+};
 use super::{Lexer, UnmatchedDelim};
 
 impl<'psess, 'src> Lexer<'psess, 'src> {
@@ -244,7 +246,16 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
         let msg = format!("unexpected closing delimiter: `{token_str}`");
         let mut err = self.dcx().struct_span_err(self.token.span, msg);
 
-        report_suspicious_mismatch_block(&mut err, &self.diag_info, self.psess.source_map(), delim);
+        // if there is no missing open delim, report suspicious mismatch block
+        if !report_missing_open_delim(&mut err, &mut self.diag_info.unmatched_delims) {
+            report_suspicious_mismatch_block(
+                &mut err,
+                &self.diag_info,
+                self.psess.source_map(),
+                delim,
+            );
+        }
+
         err.span_label(self.token.span, "unexpected closing delimiter");
         err
     }
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index d6cc98d505c..b767b0fcf99 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -244,6 +244,9 @@ impl<'a> Parser<'a> {
             self.bump(); // `static`
             let mutability = self.parse_mutability();
             self.parse_static_item(safety, mutability)?
+        } else if self.check_keyword(exp!(Trait)) || self.check_trait_front_matter() {
+            // TRAIT ITEM
+            self.parse_item_trait(attrs, lo)?
         } else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
             // CONST ITEM
             if self.token.is_keyword(kw::Impl) {
@@ -262,9 +265,6 @@ impl<'a> Parser<'a> {
                     define_opaque: None,
                 }))
             }
-        } else if self.check_keyword(exp!(Trait)) || self.check_auto_or_unsafe_trait_item() {
-            // TRAIT ITEM
-            self.parse_item_trait(attrs, lo)?
         } else if self.check_keyword(exp!(Impl))
             || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Impl])
         {
@@ -373,7 +373,7 @@ impl<'a> Parser<'a> {
     pub(super) fn is_path_start_item(&mut self) -> bool {
         self.is_kw_followed_by_ident(kw::Union) // no: `union::b`, yes: `union U { .. }`
         || self.is_reuse_path_item()
-        || self.check_auto_or_unsafe_trait_item() // no: `auto::b`, yes: `auto trait X { .. }`
+        || self.check_trait_front_matter() // no: `auto::b`, yes: `auto trait X { .. }`
         || self.is_async_fn() // no(2015): `async::b`, yes: `async fn`
         || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) // no: `macro_rules::b`, yes: `macro_rules! mac`
     }
@@ -872,16 +872,19 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Is this an `(unsafe auto? | auto) trait` item?
-    fn check_auto_or_unsafe_trait_item(&mut self) -> bool {
+    /// Is this an `(const unsafe? auto?| unsafe auto? | auto) trait` item?
+    fn check_trait_front_matter(&mut self) -> bool {
         // auto trait
         self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait])
             // unsafe auto trait
             || self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
+            || self.check_keyword(exp!(Const)) && ((self.is_keyword_ahead(1, &[kw::Trait]) || self.is_keyword_ahead(1, &[kw::Auto]) && self.is_keyword_ahead(2, &[kw::Trait]))
+                || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Trait, kw::Auto]))
     }
 
     /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
     fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
+        let constness = self.parse_constness(Case::Sensitive);
         let safety = self.parse_safety(Case::Sensitive);
         // Parse optional `auto` prefix.
         let is_auto = if self.eat_keyword(exp!(Auto)) {
@@ -913,6 +916,9 @@ impl<'a> Parser<'a> {
             self.expect_semi()?;
 
             let whole_span = lo.to(self.prev_token.span);
+            if let Const::Yes(_) = constness {
+                self.dcx().emit_err(errors::TraitAliasCannotBeConst { span: whole_span });
+            }
             if is_auto == IsAuto::Yes {
                 self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
             }
@@ -927,7 +933,15 @@ impl<'a> Parser<'a> {
             // It's a normal trait.
             generics.where_clause = self.parse_where_clause()?;
             let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
-            Ok(ItemKind::Trait(Box::new(Trait { is_auto, safety, ident, generics, bounds, items })))
+            Ok(ItemKind::Trait(Box::new(Trait {
+                constness,
+                is_auto,
+                safety,
+                ident,
+                generics,
+                bounds,
+                items,
+            })))
         }
     }
 
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 783d79d978a..a476f0db37e 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -318,6 +318,7 @@ pub fn check_builtin_meta_item(
                 | sym::rustc_layout_scalar_valid_range_end
                 | sym::no_implicit_prelude
                 | sym::automatically_derived
+                | sym::coverage
         ) {
             return;
         }