diff options
| author | bors <bors@rust-lang.org> | 2018-06-05 01:47:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-06-05 01:47:13 +0000 |
| commit | f9157f5b869fdb14308eaf6778d01ee3d0e1268a (patch) | |
| tree | dd3773889cae79721fa3cee93c982712543b8680 /src/libsyntax/parse | |
| parent | c610be92e2925ab8e789efc835c88247e46c6cbf (diff) | |
| parent | 3303e6847b4e8b413ec65a166337e5f9f8325f28 (diff) | |
| download | rust-f9157f5b869fdb14308eaf6778d01ee3d0e1268a.tar.gz rust-f9157f5b869fdb14308eaf6778d01ee3d0e1268a.zip | |
Auto merge of #51242 - ytausky:mut-ref, r=estebank
Suggest not mutably borrowing a mutable reference This PR would (hopefully) solve #45392. I deviated a bit from @estebank's instructions since the error span only included the borrowed expression (e.g. the `b` in `&mut b`). I also didn't check the mutability of the local binding, since this whole case is concerned with an immutable local. I can see two outstanding questions: 1. `note_immutability_blame` is called in two places, but I only have one test case. I think it covers the call in `report_bckerror`, but I'm not sure how to trigger the call from `report_aliasability_violation`. 2. There is one failing test, where the local binding is `self: &mut Self`. I'm not entirely sure what the correct output should be, but I think the new message should also apply. Unfortunately, since this parameter is parsed differently, its `let_span` covers both the pattern and the type, leading to a wrong suggestion text. I'm not sure how to correctly identify this case.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 28f93328e95..95d519eae58 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5190,36 +5190,36 @@ impl<'a> Parser<'a> { // Only a limited set of initial token sequences is considered self parameters, anything // else is parsed as a normal function parameter list, so some lookahead is required. let eself_lo = self.span; - let (eself, eself_ident) = match self.token { + let (eself, eself_ident, eself_hi) = match self.token { token::BinOp(token::And) => { // &self // &mut self // &'lt self // &'lt mut self // ¬_self - if isolated_self(self, 1) { + (if isolated_self(self, 1) { self.bump(); - (SelfKind::Region(None, Mutability::Immutable), expect_ident(self)) + SelfKind::Region(None, Mutability::Immutable) } else if self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) && isolated_self(self, 2) { self.bump(); self.bump(); - (SelfKind::Region(None, Mutability::Mutable), expect_ident(self)) + SelfKind::Region(None, Mutability::Mutable) } else if self.look_ahead(1, |t| t.is_lifetime()) && isolated_self(self, 2) { self.bump(); let lt = self.expect_lifetime(); - (SelfKind::Region(Some(lt), Mutability::Immutable), expect_ident(self)) + SelfKind::Region(Some(lt), Mutability::Immutable) } else if self.look_ahead(1, |t| t.is_lifetime()) && self.look_ahead(2, |t| t.is_keyword(keywords::Mut)) && isolated_self(self, 3) { self.bump(); let lt = self.expect_lifetime(); self.bump(); - (SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self)) + SelfKind::Region(Some(lt), Mutability::Mutable) } else { return Ok(None); - } + }, expect_ident(self), self.prev_span) } token::BinOp(token::Star) => { // *self @@ -5227,43 +5227,45 @@ impl<'a> Parser<'a> { // *mut self // *not_self // Emit special error for `self` cases. - if isolated_self(self, 1) { + (if isolated_self(self, 1) { self.bump(); self.span_err(self.span, "cannot pass `self` by raw pointer"); - (SelfKind::Value(Mutability::Immutable), expect_ident(self)) + SelfKind::Value(Mutability::Immutable) } else if self.look_ahead(1, |t| t.is_mutability()) && isolated_self(self, 2) { self.bump(); self.bump(); self.span_err(self.span, "cannot pass `self` by raw pointer"); - (SelfKind::Value(Mutability::Immutable), expect_ident(self)) + SelfKind::Value(Mutability::Immutable) } else { return Ok(None); - } + }, expect_ident(self), self.prev_span) } token::Ident(..) => { if isolated_self(self, 0) { // self // self: TYPE let eself_ident = expect_ident(self); - if self.eat(&token::Colon) { + let eself_hi = self.prev_span; + (if self.eat(&token::Colon) { let ty = self.parse_ty()?; - (SelfKind::Explicit(ty, Mutability::Immutable), eself_ident) + SelfKind::Explicit(ty, Mutability::Immutable) } else { - (SelfKind::Value(Mutability::Immutable), eself_ident) - } + SelfKind::Value(Mutability::Immutable) + }, eself_ident, eself_hi) } else if self.token.is_keyword(keywords::Mut) && isolated_self(self, 1) { // mut self // mut self: TYPE self.bump(); let eself_ident = expect_ident(self); - if self.eat(&token::Colon) { + let eself_hi = self.prev_span; + (if self.eat(&token::Colon) { let ty = self.parse_ty()?; - (SelfKind::Explicit(ty, Mutability::Mutable), eself_ident) + SelfKind::Explicit(ty, Mutability::Mutable) } else { - (SelfKind::Value(Mutability::Mutable), eself_ident) - } + SelfKind::Value(Mutability::Mutable) + }, eself_ident, eself_hi) } else { return Ok(None); } @@ -5271,7 +5273,7 @@ impl<'a> Parser<'a> { _ => return Ok(None), }; - let eself = codemap::respan(eself_lo.to(self.prev_span), eself); + let eself = codemap::respan(eself_lo.to(eself_hi), eself); Ok(Some(Arg::from_self(eself, eself_ident))) } |
