diff options
| author | SNCPlay42 <SNCPlay42@gmail.com> | 2020-06-21 21:37:17 +0100 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2020-09-15 10:36:06 -0400 |
| commit | 4de9a53d98533868dfa209bfb3604bba92d5e7b1 (patch) | |
| tree | 0f19e96f09dbdbc43f9d1f7d00aa6aaf9a63c56d /compiler/rustc_parse/src | |
| parent | 90b1f5ae59291dd69d72fad41a22277df19dc953 (diff) | |
| download | rust-4de9a53d98533868dfa209bfb3604bba92d5e7b1.tar.gz rust-4de9a53d98533868dfa209bfb3604bba92d5e7b1.zip | |
improve diagnostics for lifetime after `&mut`
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 259764a317d..fc4c62ccbd9 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -276,8 +276,34 @@ impl<'a> Parser<'a> { } fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> { - let opt_lifetime = if self.check_lifetime() { Some(self.expect_lifetime()) } else { None }; + 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(); + 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. + // So we can handle this case as an error here, and suggest `'a mut`. + // If there *is* a plus next though, handling the error later provides better suggestions + // (like adding parentheses) + if !self.look_ahead(1, |t| t.is_like_plus()) { + let lifetime_span = self.token.span; + let span = and_span.to(lifetime_span); + + let mut err = self.struct_span_err(span, "lifetime must precede `mut`"); + if let Ok(lifetime_src) = self.span_to_snippet(lifetime_span) { + err.span_suggestion( + span, + "place the lifetime before `mut`", + format!("&{} mut", lifetime_src), + Applicability::MaybeIncorrect, + ); + } + err.emit(); + + opt_lifetime = Some(self.expect_lifetime()); + } + } let ty = self.parse_ty_no_plus()?; Ok(TyKind::Rptr(opt_lifetime, MutTy { ty, mutbl })) } |
