Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to recover from path sep error in type parsing #136808

Merged
merged 1 commit into from
Feb 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()?;
Expand Down
15 changes: 13 additions & 2 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
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<foo::bar:A>,
| ^
|
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
help: use a double colon instead
|
LL | a: Vec<foo::bar::A>,
| +
| +

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -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;
}
15 changes: 15 additions & 0 deletions tests/ui/suggestions/argument-list-from-path-sep-error-129273.rs
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/rust-lang/rust/issues/101728>
help: use a double colon instead
|
LL | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
| +

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.
Loading