From d627e2a4e8317fc11ccd69832d482b9ae591084a Mon Sep 17 00:00:00 2001 From: sjwang05 <63834813+sjwang05@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:43:31 -0800 Subject: [PATCH] Fix parser ICE when recovering `dyn`/`impl` after `for<...>` --- compiler/rustc_parse/src/parser/ty.rs | 22 ++++++++++--------- .../parser/recover-hrtb-before-dyn-impl-kw.rs | 4 ++++ .../recover-hrtb-before-dyn-impl-kw.stderr | 8 ++++++- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index b1a57c3dfd97c..90e4a2aac8367 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -304,23 +304,25 @@ impl<'a> Parser<'a> { if self.may_recover() && (self.eat_keyword_noexpect(kw::Impl) || self.eat_keyword_noexpect(kw::Dyn)) { - let kw = self.prev_token.ident().unwrap().0.name; + let kw = self.prev_token.ident().unwrap().0; + let removal_span = kw.span.with_hi(self.token.span.lo()); + let path = self.parse_path(PathStyle::Type)?; + let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); + let kind = + self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?; let mut err = self.sess.create_err(errors::TransposeDynOrImpl { - span: self.prev_token.span, - kw: kw.as_str(), + span: kw.span, + kw: kw.name.as_str(), sugg: errors::TransposeDynOrImplSugg { - removal_span: self.prev_token.span.with_hi(self.token.span.lo()), + removal_span, insertion_span: for_span.shrink_to_lo(), - kw: kw.as_str(), + kw: kw.name.as_str(), }, }); - let path = self.parse_path(PathStyle::Type)?; - let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); - let kind = - self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?; + // Take the parsed bare trait object and turn it either // into a `dyn` object or an `impl Trait`. - let kind = match (kind, kw) { + let kind = match (kind, kw.name) { (TyKind::TraitObject(bounds, _), kw::Dyn) => { TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn) } diff --git a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs index fe363a6887f58..b9e3c5783ebd7 100644 --- a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs +++ b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs @@ -6,4 +6,8 @@ fn test(_: &for<'a> dyn Trait) {} fn test2(_: for<'a> impl Trait) {} //~^ ERROR `for<...>` expected after `impl`, not before +// Issue #118564 +type A2 = dyn dyn>; +//~^ ERROR expected identifier, found `>` + fn main() {} diff --git a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr index 6fc1259b91061..a012220e8c7c9 100644 --- a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr +++ b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr @@ -22,5 +22,11 @@ LL - fn test2(_: for<'a> impl Trait) {} LL + fn test2(_: impl for<'a> Trait) {} | -error: aborting due to 2 previous errors +error: expected identifier, found `>` + --> $DIR/recover-hrtb-before-dyn-impl-kw.rs:10:24 + | +LL | type A2 = dyn dyn>; + | ^ expected identifier + +error: aborting due to 3 previous errors