about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-27 00:22:48 +0000
committerbors <bors@rust-lang.org>2024-01-27 00:22:48 +0000
commitb362939be16f9324dd9e6e36e22b606020068d75 (patch)
tree2ae00c9b2e91f425b4a2f4513c89184cb5cdc5e4 /compiler/rustc_parse/src
parentc073f56a416b541fc66e46fb5265dad870da9229 (diff)
parent6ce96c0c555ed492735312ebfb3db68285aa428f (diff)
downloadrust-b362939be16f9324dd9e6e36e22b606020068d75.tar.gz
rust-b362939be16f9324dd9e6e36e22b606020068d75.zip
Auto merge of #120401 - matthiaskrgr:rollup-7740vrx, r=matthiaskrgr
Rollup of 12 pull requests

Successful merges:

 - #103522 (stabilise array methods)
 - #113489 (impl `From<&[T; N]>` for `Cow<[T]>`)
 - #119342 (Emit suggestion when trying to write exclusive ranges as `..<`)
 - #119562 (Rename `pointer` field on `Pin`)
 - #119800 (Document `rustc_index::vec::IndexVec`)
 - #120205 (std: make `HEAP` initializer never inline)
 - #120277 (Normalize field types before checking validity)
 - #120311 (core: add `From<core::ascii::Char>` implementations)
 - #120366 (mark a doctest with UB as no_run)
 - #120378 (always normalize `LoweredTy` in the new solver)
 - #120382 (Classify closure arguments in refutable pattern in argument error)
 - #120389 (Add fmease to the compiler review rotation)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs25
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs10
2 files changed, 28 insertions, 7 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 720a610fdf5..dd9157564db 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -23,7 +23,7 @@ use crate::parser;
 use crate::parser::attr::InnerAttrPolicy;
 use rustc_ast as ast;
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind};
+use rustc_ast::token::{self, Delimiter, Lit, LitKind, Token, TokenKind};
 use rustc_ast::tokenstream::AttrTokenTree;
 use rustc_ast::util::parser::AssocOp;
 use rustc_ast::{
@@ -448,12 +448,11 @@ impl<'a> Parser<'a> {
             })
         }
 
-        let mut expected = edible
+        self.expected_tokens.extend(edible.iter().chain(inedible).cloned().map(TokenType::Token));
+        let mut expected = self
+            .expected_tokens
             .iter()
-            .chain(inedible)
             .cloned()
-            .map(TokenType::Token)
-            .chain(self.expected_tokens.iter().cloned())
             .filter(|token| {
                 // Filter out suggestions that suggest the same token which was found and deemed incorrect.
                 fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
@@ -2927,6 +2926,22 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
+    /// Check for exclusive ranges written as `..<`
+    pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: PErr<'a>) -> PErr<'a> {
+        if maybe_lt == token::Lt
+            && (self.expected_tokens.contains(&TokenType::Token(token::Gt))
+                || matches!(self.token.kind, token::Literal(..)))
+        {
+            err.span_suggestion(
+                maybe_lt.span,
+                "remove the `<` to write an exclusive range",
+                "",
+                Applicability::MachineApplicable,
+            );
+        }
+        err
+    }
+
     pub fn is_diff_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> bool {
         (0..3).all(|i| self.look_ahead(i, |tok| tok == long_kind))
             && self.look_ahead(3, |tok| tok == short_kind)
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ae3661a530b..b789b65797b 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -482,7 +482,11 @@ impl<'a> Parser<'a> {
         cur_op_span: Span,
     ) -> PResult<'a, P<Expr>> {
         let rhs = if self.is_at_start_of_range_notation_rhs() {
-            Some(self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)?)
+            let maybe_lt = self.token.clone();
+            Some(
+                self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)
+                    .map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))?,
+            )
         } else {
             None
         };
@@ -531,11 +535,13 @@ impl<'a> Parser<'a> {
         let attrs = self.parse_or_use_outer_attributes(attrs)?;
         self.collect_tokens_for_expr(attrs, |this, attrs| {
             let lo = this.token.span;
+            let maybe_lt = this.look_ahead(1, |t| t.clone());
             this.bump();
             let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() {
                 // RHS must be parsed with more associativity than the dots.
                 this.parse_expr_assoc_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed)
-                    .map(|x| (lo.to(x.span), Some(x)))?
+                    .map(|x| (lo.to(x.span), Some(x)))
+                    .map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))?
             } else {
                 (lo, None)
             };