Skip to content

Commit

Permalink
diagnostics: correct generic bounds with doubled colon
Browse files Browse the repository at this point in the history
Fixes #95208
  • Loading branch information
notriddle committed Mar 25, 2022
1 parent 09be68c commit 2a78372
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 0 deletions.
28 changes: 28 additions & 0 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2369,6 +2369,34 @@ impl<'a> Parser<'a> {
Err(err)
}

crate fn maybe_recover_bounds_doubled_colon(&mut self, ty: &Ty) -> PResult<'a, ()> {
let TyKind::Path(qself, path) = &ty.kind else { return Ok(()) };
let qself_position = qself.as_ref().map(|qself| qself.position);
for (i, segments) in path.segments.windows(2).enumerate() {
if qself_position.map(|pos| i < pos).unwrap_or(false) {
continue;
}
if let [a, b] = segments {
let (a_span, b_span) = (a.span(), b.span());
let between_span = a_span.shrink_to_hi().to(b_span.shrink_to_lo());
if self.span_to_snippet(between_span).as_ref().map(|a| &a[..]) == Ok(":: ") {
let mut err = self.struct_span_err(
path.span.shrink_to_hi(),
"expected `:` followed by trait or lifetime",
);
err.span_suggestion(
between_span,
"use single colon",
": ".to_owned(),
Applicability::MachineApplicable,
);
return Err(err);
}
}
}
Ok(())
}

/// Parse and throw away a parenthesized comma separated
/// sequence of patterns until `)` is reached.
fn skip_pat_list(&mut self) -> PResult<'a, ()> {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_parse/src/parser/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ impl<'a> Parser<'a> {
id: ast::DUMMY_NODE_ID,
}))
} else {
self.maybe_recover_bounds_doubled_colon(&ty)?;
self.unexpected()
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/generics/issue-95208-ignore-qself.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// run-rustfix

#[allow(unused)]
struct Struct<T>(T);

impl<T: Iterator> Struct<T> where <T as std:: iter::Iterator>::Item: std::fmt::Display {
//~^ ERROR expected `:` followed by trait or lifetime
//~| HELP use single colon
}

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/generics/issue-95208-ignore-qself.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// run-rustfix

#[allow(unused)]
struct Struct<T>(T);

impl<T: Iterator> Struct<T> where <T as std:: iter::Iterator>::Item:: std::fmt::Display {
//~^ ERROR expected `:` followed by trait or lifetime
//~| HELP use single colon
}

fn main() {}
10 changes: 10 additions & 0 deletions src/test/ui/generics/issue-95208-ignore-qself.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: expected `:` followed by trait or lifetime
--> $DIR/issue-95208-ignore-qself.rs:6:88
|
LL | impl<T: Iterator> Struct<T> where <T as std:: iter::Iterator>::Item:: std::fmt::Display {
| --- ^
| |
| help: use single colon: `:`

error: aborting due to previous error

11 changes: 11 additions & 0 deletions src/test/ui/generics/issue-95208.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// run-rustfix

#[allow(unused)]
struct Struct<T>(T);

impl<T> Struct<T> where T: std::fmt::Display {
//~^ ERROR expected `:` followed by trait or lifetime
//~| HELP use single colon
}

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/generics/issue-95208.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// run-rustfix

#[allow(unused)]
struct Struct<T>(T);

impl<T> Struct<T> where T:: std::fmt::Display {
//~^ ERROR expected `:` followed by trait or lifetime
//~| HELP use single colon
}

fn main() {}
10 changes: 10 additions & 0 deletions src/test/ui/generics/issue-95208.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: expected `:` followed by trait or lifetime
--> $DIR/issue-95208.rs:6:46
|
LL | impl<T> Struct<T> where T:: std::fmt::Display {
| --- ^
| |
| help: use single colon: `:`

error: aborting due to previous error

0 comments on commit 2a78372

Please sign in to comment.