From 3f09a2054921708ac8288ac9912885dbe66682ec Mon Sep 17 00:00:00 2001 From: Jack Rickard Date: Mon, 3 Feb 2025 13:56:20 +0000 Subject: Do not allow attributes on struct field rest patterns This removes support for attributes on struct field rest patterns (the `..`) from the parser. Previously they were being parsed but dropped from the AST, so didn't work and were deleted by rustfmt. --- compiler/rustc_parse/src/parser/pat.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'compiler/rustc_parse/src') diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 64bcb1a5a36..8ce749ec814 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1472,17 +1472,6 @@ impl<'a> Parser<'a> { let mut last_non_comma_dotdot_span = None; while self.token != token::CloseDelim(Delimiter::Brace) { - let attrs = match self.parse_outer_attributes() { - Ok(attrs) => attrs, - Err(err) => { - if let Some(delayed) = delayed_err { - delayed.emit(); - } - return Err(err); - } - }; - let lo = self.token.span; - // check that a comma comes after every field if !ate_comma { let err = if self.token == token::At { @@ -1585,6 +1574,17 @@ impl<'a> Parser<'a> { } } + let attrs = match self.parse_outer_attributes() { + Ok(attrs) => attrs, + Err(err) => { + if let Some(delayed) = delayed_err { + delayed.emit(); + } + return Err(err); + } + }; + let lo = self.token.span; + let field = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { let field = match this.parse_pat_field(lo, attrs) { Ok(field) => Ok(field), -- cgit 1.4.1-3-g733a5 From 0aa2e6b606fdca2c0166b6033e3ea0cb8484eeb7 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 11 Feb 2025 15:26:21 +0800 Subject: Try to recover from path sep error in parser --- compiler/rustc_parse/messages.ftl | 3 -- compiler/rustc_parse/src/errors.rs | 8 ---- compiler/rustc_parse/src/parser/item.rs | 3 -- compiler/rustc_parse/src/parser/path.rs | 15 ++++++- .../single-colon-path-not-const-generics.stderr | 4 +- .../argument-list-from-path-sep-error-129273.fixed | 15 +++++++ .../argument-list-from-path-sep-error-129273.rs | 15 +++++++ ...argument-list-from-path-sep-error-129273.stderr | 14 +++++++ .../struct-field-type-including-single-colon.rs | 8 ++-- ...struct-field-type-including-single-colon.stderr | 47 ++++++++++++++-------- 10 files changed, 92 insertions(+), 40 deletions(-) create mode 100644 tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed create mode 100644 tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs create mode 100644 tests/ui/suggestions/argument-list-from-path-sep-error-129273.stderr (limited to 'compiler/rustc_parse/src') diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index d50bd18a1d7..563081c7240 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -743,9 +743,6 @@ parse_single_colon_import_path = expected `::`, found `:` .suggestion = use double colon .note = import paths are delimited using `::` -parse_single_colon_struct_type = found single colon in a struct field type path - .suggestion = write a path separator here - parse_static_with_generics = static items may not have generic parameters parse_struct_literal_body_without_path = diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 8f0e29c2769..dc03d6f9521 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -3071,14 +3071,6 @@ pub(crate) struct BadItemKind { pub help: bool, } -#[derive(Diagnostic)] -#[diag(parse_single_colon_struct_type)] -pub(crate) struct SingleColonStructType { - #[primary_span] - #[suggestion(code = "::", applicability = "maybe-incorrect", style = "verbose")] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(parse_macro_rules_missing_bang)] pub(crate) struct MacroRulesMissingBang { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 637ed2774a2..c923717ecaf 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2043,9 +2043,6 @@ impl<'a> Parser<'a> { } self.expect_field_ty_separator()?; let ty = self.parse_ty()?; - if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) { - self.dcx().emit_err(errors::SingleColonStructType { span: self.token.span }); - } let default = if self.token == token::Eq { self.bump(); let const_expr = self.parse_expr_anon_const()?; diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 576711e6677..b241aa892db 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -246,8 +246,19 @@ impl<'a> Parser<'a> { segments.push(segment); if self.is_import_coupler() || !self.eat_path_sep() { - if style == PathStyle::Expr - && self.may_recover() + let ok_for_recovery = self.may_recover() + && match style { + PathStyle::Expr => true, + PathStyle::Type if let Some((ident, _)) = self.prev_token.ident() => { + self.token == token::Colon + && ident.as_str().chars().all(|c| c.is_lowercase()) + && self.token.span.lo() == self.prev_token.span.hi() + && self + .look_ahead(1, |token| self.token.span.hi() == token.span.lo()) + } + _ => false, + }; + if ok_for_recovery && self.token == token::Colon && self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident()) { diff --git a/tests/ui/generics/single-colon-path-not-const-generics.stderr b/tests/ui/generics/single-colon-path-not-const-generics.stderr index 4e695b2dcd6..c14a5e62a0c 100644 --- a/tests/ui/generics/single-colon-path-not-const-generics.stderr +++ b/tests/ui/generics/single-colon-path-not-const-generics.stderr @@ -1,8 +1,6 @@ error: path separator must be a double colon --> $DIR/single-colon-path-not-const-generics.rs:8:18 | -LL | pub struct Foo { - | --- while parsing this struct LL | a: Vec, | ^ | @@ -10,7 +8,7 @@ LL | a: Vec, help: use a double colon instead | LL | a: Vec, - | + + | + error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed new file mode 100644 index 00000000000..f5dbf0c8b6f --- /dev/null +++ b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.fixed @@ -0,0 +1,15 @@ +//@ run-rustfix + +use std::fmt; + +struct Hello; + +impl fmt::Display for Hello { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon + write!(f, "hello") + } +} + +fn main() { + let _ = Hello; +} diff --git a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs new file mode 100644 index 00000000000..c41880a26f6 --- /dev/null +++ b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs @@ -0,0 +1,15 @@ +//@ run-rustfix + +use std::fmt; + +struct Hello; + +impl fmt::Display for Hello { + fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result { //~ ERROR path separator must be a double colon + write!(f, "hello") + } +} + +fn main() { + let _ = Hello; +} diff --git a/tests/ui/suggestions/argument-list-from-path-sep-error-129273.stderr b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.stderr new file mode 100644 index 00000000000..92947e3b177 --- /dev/null +++ b/tests/ui/suggestions/argument-list-from-path-sep-error-129273.stderr @@ -0,0 +1,14 @@ +error: path separator must be a double colon + --> $DIR/argument-list-from-path-sep-error-129273.rs:8:30 + | +LL | fn fmt(&self, f: &mut fmt:Formatter) -> fmt::Result { + | ^ + | + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 +help: use a double colon instead + | +LL | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + | + + +error: aborting due to 1 previous error + diff --git a/tests/ui/suggestions/struct-field-type-including-single-colon.rs b/tests/ui/suggestions/struct-field-type-including-single-colon.rs index b7ad6d996f1..a3111028895 100644 --- a/tests/ui/suggestions/struct-field-type-including-single-colon.rs +++ b/tests/ui/suggestions/struct-field-type-including-single-colon.rs @@ -7,14 +7,14 @@ mod foo { struct Foo { a: foo:A, - //~^ ERROR found single colon in a struct field type path - //~| expected `,`, or `}`, found `:` + //~^ ERROR path separator must be a double colon + //~| ERROR struct `A` is private } struct Bar { b: foo::bar:B, - //~^ ERROR found single colon in a struct field type path - //~| expected `,`, or `}`, found `:` + //~^ ERROR path separator must be a double colon + //~| ERROR module `bar` is private } fn main() {} diff --git a/tests/ui/suggestions/struct-field-type-including-single-colon.stderr b/tests/ui/suggestions/struct-field-type-including-single-colon.stderr index 5ffc5b40849..ce16aca1e14 100644 --- a/tests/ui/suggestions/struct-field-type-including-single-colon.stderr +++ b/tests/ui/suggestions/struct-field-type-including-single-colon.stderr @@ -1,40 +1,53 @@ -error: found single colon in a struct field type path +error: path separator must be a double colon --> $DIR/struct-field-type-including-single-colon.rs:9:11 | LL | a: foo:A, | ^ | -help: write a path separator here + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 +help: use a double colon instead | LL | a: foo::A, | + -error: expected `,`, or `}`, found `:` - --> $DIR/struct-field-type-including-single-colon.rs:9:11 - | -LL | struct Foo { - | --- while parsing this struct -LL | a: foo:A, - | ^ - -error: found single colon in a struct field type path +error: path separator must be a double colon --> $DIR/struct-field-type-including-single-colon.rs:15:16 | LL | b: foo::bar:B, | ^ | -help: write a path separator here + = note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 +help: use a double colon instead | LL | b: foo::bar::B, | + -error: expected `,`, or `}`, found `:` - --> $DIR/struct-field-type-including-single-colon.rs:15:16 +error[E0603]: struct `A` is private + --> $DIR/struct-field-type-including-single-colon.rs:9:12 + | +LL | a: foo:A, + | ^ private struct + | +note: the struct `A` is defined here + --> $DIR/struct-field-type-including-single-colon.rs:2:5 + | +LL | struct A; + | ^^^^^^^^^ + +error[E0603]: module `bar` is private + --> $DIR/struct-field-type-including-single-colon.rs:15:13 | -LL | struct Bar { - | --- while parsing this struct LL | b: foo::bar:B, - | ^ + | ^^^ - struct `B` is not publicly re-exported + | | + | private module + | +note: the module `bar` is defined here + --> $DIR/struct-field-type-including-single-colon.rs:3:5 + | +LL | mod bar { + | ^^^^^^^ error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0603`. -- cgit 1.4.1-3-g733a5