Skip to content

Commit cd574ab

Browse files
committed
add parser check for multi-reference self
1 parent 1ed3cd7 commit cd574ab

File tree

3 files changed

+154
-4
lines changed

3 files changed

+154
-4
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ use std::mem::take;
22
use std::ops::{Deref, DerefMut};
33

44
use ast::token::IdentIsRaw;
5-
use rustc_ast as ast;
65
use rustc_ast::token::{self, Lit, LitKind, Token, TokenKind};
76
use rustc_ast::util::parser::AssocOp;
87
use rustc_ast::{
9-
AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode, Block,
10-
BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat, PatKind,
11-
Path, PathSegment, QSelf, Recovered, Ty, TyKind,
8+
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AttrVec, BinOpKind, BindingMode,
9+
Block, BlockCheckMode, Expr, ExprKind, GenericArg, Generics, Item, ItemKind, Param, Pat,
10+
PatKind, Path, PathSegment, QSelf, Recovered, Ty, TyKind,
1211
};
1312
use rustc_ast_pretty::pprust;
1413
use rustc_data_structures::fx::FxHashSet;
@@ -2305,6 +2304,43 @@ impl<'a> Parser<'a> {
23052304
pat.span.shrink_to_lo(),
23062305
)
23072306
}
2307+
PatKind::Ref(ref inner_pat, _) => {
2308+
let mut inner = inner_pat;
2309+
let mut span_vec = vec![pat.span];
2310+
2311+
while let PatKind::Ref(ref inner_type, _) = inner.kind {
2312+
inner = inner_type;
2313+
span_vec.push(inner.span.shrink_to_lo());
2314+
}
2315+
2316+
let span = match span_vec.len() {
2317+
0 | 1 => {
2318+
if let Some(_) = pat.to_ty() {
2319+
err.span_suggestion_verbose(
2320+
pat.span.shrink_to_lo(),
2321+
"explicitly ignore the parameter name",
2322+
"_: ".to_string(),
2323+
Applicability::MachineApplicable,
2324+
);
2325+
maybe_emit_anon_params_note(self, err);
2326+
}
2327+
2328+
return None;
2329+
}
2330+
2 => span_vec[0].until(inner_pat.span.shrink_to_lo()),
2331+
_ => span_vec[0].until(span_vec[span_vec.len() - 2].shrink_to_lo()),
2332+
};
2333+
2334+
err.span_suggestion_verbose(
2335+
span,
2336+
"`self` should be `self`, `&self` or `&mut self`, please remove extra references",
2337+
"".to_string(),
2338+
Applicability::MachineApplicable,
2339+
);
2340+
2341+
maybe_emit_anon_params_note(self, err);
2342+
return None;
2343+
}
23082344
_ => {
23092345
// Otherwise, try to get a type and emit a suggestion.
23102346
if let Some(_) = pat.to_ty() {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
struct A ;
2+
3+
impl A {
4+
fn a(&&self) {}
5+
//~^ ERROR expected one of
6+
//~| HELP `self` should be `self`, `&self` or `&mut self`, please remove extra references
7+
fn b(&&&&&&self) {}
8+
//~^ ERROR expected one of
9+
//~| HELP `self` should be `self`, `&self` or `&mut self`, please remove extra references
10+
fn c(&self) {}
11+
fn d(&mut &self) {}
12+
//~^ ERROR expected one of
13+
//~| HELP `self` should be `self`, `&self` or `&mut self`, please remove extra references
14+
fn e(&mut &&&self) {}
15+
//~^ ERROR expected one of
16+
//~| HELP `self` should be `self`, `&self` or `&mut self`, please remove extra references
17+
fn f(&mut &mut &mut self) {}
18+
//~^ ERROR expected one of
19+
//~| HELP `self` should be `self`, `&self` or `&mut self`, please remove extra references
20+
fn g(&mut & &mut self) {}
21+
//~^ ERROR expected one of
22+
//~| HELP `self` should be `self`, `&self` or `&mut self`, please remove extra references
23+
fn h(&mut & & & && & & self) {}
24+
//~^ ERROR expected one of
25+
//~| HELP `self` should be `self`, `&self` or `&mut self`, please remove extra references
26+
}
27+
28+
fn main() {}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)`
2+
--> $DIR/lot-of-references-self.rs:4:16
3+
|
4+
LL | fn a(&&self) {}
5+
| ^ expected one of 9 possible tokens
6+
|
7+
help: `self` should be `self`, `&self` or `&mut self`, please remove extra references
8+
|
9+
LL - fn a(&&self) {}
10+
LL + fn a(&self) {}
11+
|
12+
13+
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)`
14+
--> $DIR/lot-of-references-self.rs:7:20
15+
|
16+
LL | fn b(&&&&&&self) {}
17+
| ^ expected one of 9 possible tokens
18+
|
19+
help: `self` should be `self`, `&self` or `&mut self`, please remove extra references
20+
|
21+
LL - fn b(&&&&&&self) {}
22+
LL + fn b(&self) {}
23+
|
24+
25+
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)`
26+
--> $DIR/lot-of-references-self.rs:11:20
27+
|
28+
LL | fn d(&mut &self) {}
29+
| ^ expected one of 9 possible tokens
30+
|
31+
help: `self` should be `self`, `&self` or `&mut self`, please remove extra references
32+
|
33+
LL - fn d(&mut &self) {}
34+
LL + fn d(&self) {}
35+
|
36+
37+
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)`
38+
--> $DIR/lot-of-references-self.rs:14:22
39+
|
40+
LL | fn e(&mut &&&self) {}
41+
| ^ expected one of 9 possible tokens
42+
|
43+
help: `self` should be `self`, `&self` or `&mut self`, please remove extra references
44+
|
45+
LL - fn e(&mut &&&self) {}
46+
LL + fn e(&self) {}
47+
|
48+
49+
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)`
50+
--> $DIR/lot-of-references-self.rs:17:29
51+
|
52+
LL | fn f(&mut &mut &mut self) {}
53+
| ^ expected one of 9 possible tokens
54+
|
55+
help: `self` should be `self`, `&self` or `&mut self`, please remove extra references
56+
|
57+
LL - fn f(&mut &mut &mut self) {}
58+
LL + fn f(&mut self) {}
59+
|
60+
61+
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)`
62+
--> $DIR/lot-of-references-self.rs:20:26
63+
|
64+
LL | fn g(&mut & &mut self) {}
65+
| ^ expected one of 9 possible tokens
66+
|
67+
help: `self` should be `self`, `&self` or `&mut self`, please remove extra references
68+
|
69+
LL - fn g(&mut & &mut self) {}
70+
LL + fn g(&mut self) {}
71+
|
72+
73+
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `)`
74+
--> $DIR/lot-of-references-self.rs:23:39
75+
|
76+
LL | fn h(&mut & & & && & & self) {}
77+
| ^ expected one of 9 possible tokens
78+
|
79+
help: `self` should be `self`, `&self` or `&mut self`, please remove extra references
80+
|
81+
LL - fn h(&mut & & & && & & self) {}
82+
LL + fn h(& self) {}
83+
|
84+
85+
error: aborting due to 7 previous errors
86+

0 commit comments

Comments
 (0)