diff options
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 22 |
2 files changed, 28 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2daa9e2485b..2ce63d011f4 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1791,7 +1791,13 @@ impl<'a> Parser<'a> { if self.check_keyword(kw::Pub) { let sp = sp_start.to(self.prev_token.span); if let Ok(snippet) = self.span_to_snippet(sp) { - let vis = self.parse_visibility(FollowedByType::No)?; + let vis = match self.parse_visibility(FollowedByType::No) { + Ok(v) => v, + Err(mut d) => { + d.cancel(); + return Err(err); + } + }; let vs = pprust::vis_to_string(&vis); let vs = vs.trim_end(); err.span_suggestion( diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index de5a5632600..1fbf01b1b97 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -393,7 +393,7 @@ impl<'a> Parser<'a> { let and_span = self.prev_token.span; let mut opt_lifetime = if self.check_lifetime() { Some(self.expect_lifetime()) } else { None }; - let mutbl = self.parse_mutability(); + let mut mutbl = self.parse_mutability(); if self.token.is_lifetime() && mutbl == Mutability::Mut && opt_lifetime.is_none() { // A lifetime is invalid here: it would be part of a bare trait bound, which requires // it to be followed by a plus, but we disallow plus in the pointee type. @@ -417,6 +417,26 @@ impl<'a> Parser<'a> { opt_lifetime = Some(self.expect_lifetime()); } + } else if self.token.is_keyword(kw::Dyn) + && mutbl == Mutability::Not + && self.look_ahead(1, |t| t.is_keyword(kw::Mut)) + { + // We have `&dyn mut ...`, which is invalid and should be `&mut dyn ...`. + let span = and_span.to(self.look_ahead(1, |t| t.span)); + let mut err = self.struct_span_err(span, "`mut` must precede `dyn`"); + err.span_suggestion( + span, + "place `mut` before `dyn`", + "&mut dyn".to_string(), + Applicability::MachineApplicable, + ); + err.emit(); + + // Recovery + mutbl = Mutability::Mut; + let (dyn_tok, dyn_tok_sp) = (self.token.clone(), self.token_spacing); + self.bump(); + self.bump_with((dyn_tok, dyn_tok_sp)); } let ty = self.parse_ty_no_plus()?; Ok(TyKind::Rptr(opt_lifetime, MutTy { ty, mutbl })) |
