Skip to content

Commit 89b2fe7

Browse files
committed
Keep the suggestion for wrong arbitrary self types
1 parent 049c728 commit 89b2fe7

File tree

15 files changed

+133
-80
lines changed

15 files changed

+133
-80
lines changed

compiler/rustc_parse/src/parser/attr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<'a> Parser<'a> {
260260
item
261261
} else {
262262
let do_parse = |this: &mut Self| {
263-
let path = this.parse_path(PathStyle::Mod)?;
263+
let path = this.parse_path(PathStyle::Mod, None)?;
264264
let args = this.parse_attr_args()?;
265265
Ok(ast::AttrItem { path, args, tokens: None })
266266
};
@@ -387,7 +387,7 @@ impl<'a> Parser<'a> {
387387
}
388388

389389
let lo = self.token.span;
390-
let path = self.parse_path(PathStyle::Mod)?;
390+
let path = self.parse_path(PathStyle::Mod, None)?;
391391
let kind = self.parse_meta_item_kind()?;
392392
let span = lo.to(self.prev_token.span);
393393
Ok(ast::MetaItem { path, kind, span })

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,7 +1579,7 @@ impl<'a> Parser<'a> {
15791579
self.expect(&token::ModSep)?;
15801580

15811581
let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None };
1582-
self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?;
1582+
self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None, None)?;
15831583
path.span = ty_span.to(self.prev_token.span);
15841584

15851585
let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty));
@@ -2019,7 +2019,7 @@ impl<'a> Parser<'a> {
20192019
{
20202020
let rfc_note = "anonymous parameters are removed in the 2018 edition (see RFC 1685)";
20212021

2022-
let (ident, self_sugg, param_sugg, type_sugg, self_span, param_span, type_span) =
2022+
let (ident, self_sugg, param_sugg, type_sugg, self_span, param_span, type_span, maybe_name) =
20232023
match pat.kind {
20242024
PatKind::Ident(_, ident, _) => (
20252025
ident,
@@ -2029,6 +2029,7 @@ impl<'a> Parser<'a> {
20292029
pat.span.shrink_to_lo(),
20302030
pat.span.shrink_to_hi(),
20312031
pat.span.shrink_to_lo(),
2032+
true,
20322033
),
20332034
// Also catches `fn foo(&a)`.
20342035
PatKind::Ref(ref inner_pat, mutab)
@@ -2045,11 +2046,22 @@ impl<'a> Parser<'a> {
20452046
pat.span.shrink_to_lo(),
20462047
pat.span,
20472048
pat.span.shrink_to_lo(),
2049+
true,
20482050
)
20492051
}
20502052
_ => unreachable!(),
20512053
}
2052-
}
2054+
},
2055+
PatKind::Path(_, ref path) if let Some(segment) = path.segments.last() => (
2056+
segment.ident,
2057+
"self: ",
2058+
": TypeName".to_string(),
2059+
"_: ",
2060+
pat.span.shrink_to_lo(),
2061+
pat.span.shrink_to_hi(),
2062+
pat.span.shrink_to_lo(),
2063+
path.segments.len() == 1, // Avoid suggesting that `fn foo(a::b)` is fixed with a change to `fn foo(a::b: TypeName)`.
2064+
),
20532065
_ => {
20542066
// Otherwise, try to get a type and emit a suggestion.
20552067
if let Some(ty) = pat.to_ty() {
@@ -2077,7 +2089,7 @@ impl<'a> Parser<'a> {
20772089
}
20782090
// Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
20792091
// `fn foo(HashMap: TypeName<u32>)`.
2080-
if self.token != token::Lt {
2092+
if self.token != token::Lt && maybe_name {
20812093
err.span_suggestion(
20822094
param_span,
20832095
"if this is a parameter name, give it a type",
@@ -2100,7 +2112,7 @@ impl<'a> Parser<'a> {
21002112
}
21012113

21022114
pub(super) fn recover_arg_parse(&mut self) -> PResult<'a, (P<ast::Pat>, P<ast::Ty>)> {
2103-
let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName))?;
2115+
let pat = self.parse_pat_no_top_alt(Some(Expected::ArgumentName), None)?;
21042116
self.expect(&token::Colon)?;
21052117
let ty = self.parse_ty()?;
21062118

@@ -2508,7 +2520,7 @@ impl<'a> Parser<'a> {
25082520
// Skip the `:`.
25092521
snapshot_pat.bump();
25102522
snapshot_type.bump();
2511-
match snapshot_pat.parse_pat_no_top_alt(expected) {
2523+
match snapshot_pat.parse_pat_no_top_alt(expected, None) {
25122524
Err(inner_err) => {
25132525
inner_err.cancel();
25142526
}
@@ -2772,7 +2784,7 @@ impl<'a> Parser<'a> {
27722784
/// sequence of patterns until `)` is reached.
27732785
fn skip_pat_list(&mut self) -> PResult<'a, ()> {
27742786
while !self.check(&token::CloseDelim(Delimiter::Parenthesis)) {
2775-
self.parse_pat_no_top_alt(None)?;
2787+
self.parse_pat_no_top_alt(None, None)?;
27762788
if !self.eat(&token::Comma) {
27772789
return Ok(());
27782790
}

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ impl<'a> Parser<'a> {
775775
_ => {}
776776
}
777777

778-
match self.parse_path(PathStyle::Expr) {
778+
match self.parse_path(PathStyle::Expr, None) {
779779
Ok(path) => {
780780
let span_after_type = parser_snapshot_after_type.token.span;
781781
let expr = mk_expr(
@@ -1314,7 +1314,7 @@ impl<'a> Parser<'a> {
13141314
}
13151315

13161316
let fn_span_lo = self.token.span;
1317-
let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
1317+
let mut seg = self.parse_path_segment(PathStyle::Expr, None, None)?;
13181318
self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]);
13191319
self.check_turbofish_missing_angle_brackets(&mut seg);
13201320

@@ -1544,7 +1544,7 @@ impl<'a> Parser<'a> {
15441544
})?;
15451545
(Some(qself), path)
15461546
} else {
1547-
(None, self.parse_path(PathStyle::Expr)?)
1547+
(None, self.parse_path(PathStyle::Expr, None)?)
15481548
};
15491549

15501550
// `!`, as an operator, is prefix, so we know this isn't that.
@@ -2338,7 +2338,7 @@ impl<'a> Parser<'a> {
23382338
let lo = self.token.span;
23392339
let attrs = self.parse_outer_attributes()?;
23402340
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
2341-
let pat = this.parse_pat_no_top_alt(Some(Expected::ParameterName))?;
2341+
let pat = this.parse_pat_no_top_alt(Some(Expected::ParameterName), None)?;
23422342
let ty = if this.eat(&token::Colon) {
23432343
this.parse_ty()?
23442344
} else {
@@ -2781,7 +2781,7 @@ impl<'a> Parser<'a> {
27812781
return None;
27822782
}
27832783
let pre_pat_snapshot = self.create_snapshot_for_diagnostic();
2784-
match self.parse_pat_no_top_alt(None) {
2784+
match self.parse_pat_no_top_alt(None, None) {
27852785
Ok(_pat) => {
27862786
if self.token.kind == token::FatArrow {
27872787
// Reached arm end.

compiler/rustc_parse/src/parser/item.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ impl<'a> Parser<'a> {
452452

453453
/// Parses an item macro, e.g., `item!();`.
454454
fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
455-
let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
455+
let path = self.parse_path(PathStyle::Mod, None)?; // `foo::bar`
456456
self.expect(&token::Not)?; // `!`
457457
match self.parse_delim_args() {
458458
// `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
@@ -976,7 +976,7 @@ impl<'a> Parser<'a> {
976976
self.parse_use_tree_glob_or_nested()?
977977
} else {
978978
// `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
979-
prefix = self.parse_path(PathStyle::Mod)?;
979+
prefix = self.parse_path(PathStyle::Mod, None)?;
980980

981981
if self.eat(&token::ModSep) {
982982
self.parse_use_tree_glob_or_nested()?
@@ -987,7 +987,7 @@ impl<'a> Parser<'a> {
987987
.emit_err(errors::SingleColonImportPath { span: self.prev_token.span });
988988

989989
// We parse the rest of the path and append it to the original prefix.
990-
self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?;
990+
self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None, None)?;
991991
prefix.span = lo.to(self.prev_token.span);
992992
}
993993

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,7 +1413,7 @@ impl<'a> Parser<'a> {
14131413
// Parse `pub(in path)`.
14141414
self.bump(); // `(`
14151415
self.bump(); // `in`
1416-
let path = self.parse_path(PathStyle::Mod)?; // `path`
1416+
let path = self.parse_path(PathStyle::Mod, None)?; // `path`
14171417
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
14181418
let vis = VisibilityKind::Restricted {
14191419
path: P(path),
@@ -1430,7 +1430,7 @@ impl<'a> Parser<'a> {
14301430
{
14311431
// Parse `pub(crate)`, `pub(self)`, or `pub(super)`.
14321432
self.bump(); // `(`
1433-
let path = self.parse_path(PathStyle::Mod)?; // `crate`/`super`/`self`
1433+
let path = self.parse_path(PathStyle::Mod, None)?; // `crate`/`super`/`self`
14341434
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
14351435
let vis = VisibilityKind::Restricted {
14361436
path: P(path),
@@ -1456,7 +1456,7 @@ impl<'a> Parser<'a> {
14561456
/// Recovery for e.g. `pub(something) fn ...` or `struct X { pub(something) y: Z }`
14571457
fn recover_incorrect_vis_restriction(&mut self) -> PResult<'a, ()> {
14581458
self.bump(); // `(`
1459-
let path = self.parse_path(PathStyle::Mod)?;
1459+
let path = self.parse_path(PathStyle::Mod, None)?;
14601460
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
14611461

14621462
let path_str = pprust::path_to_string(&path);

compiler/rustc_parse/src/parser/nonterminal.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'a> Parser<'a> {
131131
},
132132
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr { .. } => {
133133
token::NtPat(self.collect_tokens_no_attrs(|this| match kind {
134-
NonterminalKind::PatParam { .. } => this.parse_pat_no_top_alt(None),
134+
NonterminalKind::PatParam { .. } => this.parse_pat_no_top_alt(None, None),
135135
NonterminalKind::PatWithOr { .. } => this.parse_pat_allow_top_alt(
136136
None,
137137
RecoverComma::No,
@@ -168,7 +168,7 @@ impl<'a> Parser<'a> {
168168
}.into_diagnostic(&self.sess.span_diagnostic));
169169
}
170170
NonterminalKind::Path => token::NtPath(
171-
P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?),
171+
P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type, None))?),
172172
),
173173
NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item(true)?)),
174174
NonterminalKind::Vis => token::NtVis(

compiler/rustc_parse/src/parser/pat.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ enum EatOrResult {
8080
}
8181

8282
/// The syntax location of a given pattern. Used for diagnostics.
83-
pub(super) enum PatternLocation {
83+
#[derive(Clone, Copy)]
84+
pub enum PatternLocation {
8485
LetBinding,
8586
FunctionParameter,
8687
}
@@ -91,8 +92,12 @@ impl<'a> Parser<'a> {
9192
/// Corresponds to `pat<no_top_alt>` in RFC 2535 and does not admit or-patterns
9293
/// at the top level. Used when parsing the parameters of lambda expressions,
9394
/// functions, function pointers, and `pat` macro fragments.
94-
pub fn parse_pat_no_top_alt(&mut self, expected: Option<Expected>) -> PResult<'a, P<Pat>> {
95-
self.parse_pat_with_range_pat(true, expected)
95+
pub fn parse_pat_no_top_alt(
96+
&mut self,
97+
expected: Option<Expected>,
98+
syntax_loc: Option<PatternLocation>,
99+
) -> PResult<'a, P<Pat>> {
100+
self.parse_pat_with_range_pat(true, expected, syntax_loc)
96101
}
97102

98103
/// Parses a pattern.
@@ -110,7 +115,7 @@ impl<'a> Parser<'a> {
110115
ra: RecoverColon,
111116
rt: CommaRecoveryMode,
112117
) -> PResult<'a, P<Pat>> {
113-
self.parse_pat_allow_top_alt_inner(expected, rc, ra, rt).map(|(pat, _)| pat)
118+
self.parse_pat_allow_top_alt_inner(expected, rc, ra, rt, None).map(|(pat, _)| pat)
114119
}
115120

116121
/// Returns the pattern and a bool indicating whether we recovered from a trailing vert (true =
@@ -121,6 +126,7 @@ impl<'a> Parser<'a> {
121126
rc: RecoverComma,
122127
ra: RecoverColon,
123128
rt: CommaRecoveryMode,
129+
syntax_loc: Option<PatternLocation>,
124130
) -> PResult<'a, (P<Pat>, bool)> {
125131
// Keep track of whether we recovered from a trailing vert so that we can avoid duplicated
126132
// suggestions (which bothers rustfix).
@@ -133,7 +139,7 @@ impl<'a> Parser<'a> {
133139
};
134140

135141
// Parse the first pattern (`p_0`).
136-
let mut first_pat = self.parse_pat_no_top_alt(expected)?;
142+
let mut first_pat = self.parse_pat_no_top_alt(expected, syntax_loc.clone())?;
137143
if rc == RecoverComma::Yes {
138144
self.maybe_recover_unexpected_comma(first_pat.span, rt)?;
139145
}
@@ -172,7 +178,7 @@ impl<'a> Parser<'a> {
172178
break;
173179
}
174180
}
175-
let pat = self.parse_pat_no_top_alt(expected).map_err(|mut err| {
181+
let pat = self.parse_pat_no_top_alt(expected, syntax_loc).map_err(|mut err| {
176182
err.span_label(lo, WHILE_PARSING_OR_MSG);
177183
err
178184
})?;
@@ -208,6 +214,7 @@ impl<'a> Parser<'a> {
208214
rc,
209215
RecoverColon::No,
210216
CommaRecoveryMode::LikelyTuple,
217+
Some(syntax_loc),
211218
)?;
212219
let colon = self.eat(&token::Colon);
213220

@@ -319,6 +326,7 @@ impl<'a> Parser<'a> {
319326
&mut self,
320327
allow_range_pat: bool,
321328
expected: Option<Expected>,
329+
syntax_loc: Option<PatternLocation>,
322330
) -> PResult<'a, P<Pat>> {
323331
maybe_recover_from_interpolated_ty_qpath!(self, true);
324332
maybe_whole!(self, NtPat, |x| x);
@@ -393,7 +401,7 @@ impl<'a> Parser<'a> {
393401
(Some(qself), path)
394402
} else {
395403
// Parse an unqualified path
396-
(None, self.parse_path(PathStyle::Pat)?)
404+
(None, self.parse_path(PathStyle::Pat, syntax_loc)?)
397405
};
398406
let span = lo.to(self.prev_token.span);
399407

@@ -485,7 +493,7 @@ impl<'a> Parser<'a> {
485493

486494
// At this point we attempt to parse `@ $pat_rhs` and emit an error.
487495
self.bump(); // `@`
488-
let mut rhs = self.parse_pat_no_top_alt(None)?;
496+
let mut rhs = self.parse_pat_no_top_alt(None, None)?;
489497
let whole_span = lhs.span.to(rhs.span);
490498

491499
if let PatKind::Ident(_, _, sub @ None) = &mut rhs.kind {
@@ -541,7 +549,7 @@ impl<'a> Parser<'a> {
541549
}
542550

543551
let mutbl = self.parse_mutability();
544-
let subpat = self.parse_pat_with_range_pat(false, expected)?;
552+
let subpat = self.parse_pat_with_range_pat(false, expected, None)?;
545553
Ok(PatKind::Ref(subpat, mutbl))
546554
}
547555

@@ -584,7 +592,7 @@ impl<'a> Parser<'a> {
584592
}
585593

586594
// Parse the pattern we hope to be an identifier.
587-
let mut pat = self.parse_pat_no_top_alt(Some(Expected::Identifier))?;
595+
let mut pat = self.parse_pat_no_top_alt(Some(Expected::Identifier), None)?;
588596

589597
// If we don't have `mut $ident (@ pat)?`, error.
590598
if let PatKind::Ident(BindingAnnotation(ByRef::No, m @ Mutability::Not), ..) = &mut pat.kind
@@ -776,7 +784,7 @@ impl<'a> Parser<'a> {
776784
(Some(qself), path)
777785
} else {
778786
// Parse an unqualified path
779-
(None, self.parse_path(PathStyle::Pat)?)
787+
(None, self.parse_path(PathStyle::Pat, None)?)
780788
};
781789
let hi = self.prev_token.span;
782790
Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path)))
@@ -814,7 +822,7 @@ impl<'a> Parser<'a> {
814822
fn parse_pat_ident(&mut self, binding_annotation: BindingAnnotation) -> PResult<'a, PatKind> {
815823
let ident = self.parse_ident()?;
816824
let sub = if self.eat(&token::At) {
817-
Some(self.parse_pat_no_top_alt(Some(Expected::BindingPattern))?)
825+
Some(self.parse_pat_no_top_alt(Some(Expected::BindingPattern), None)?)
818826
} else {
819827
None
820828
};
@@ -903,14 +911,14 @@ impl<'a> Parser<'a> {
903911
// We cannot use `parse_pat_ident()` since it will complain `box`
904912
// is not an identifier.
905913
let sub = if self.eat(&token::At) {
906-
Some(self.parse_pat_no_top_alt(Some(Expected::BindingPattern))?)
914+
Some(self.parse_pat_no_top_alt(Some(Expected::BindingPattern), None)?)
907915
} else {
908916
None
909917
};
910918

911919
Ok(PatKind::Ident(BindingAnnotation::NONE, Ident::new(kw::Box, box_span), sub))
912920
} else {
913-
let pat = self.parse_pat_with_range_pat(false, None)?;
921+
let pat = self.parse_pat_with_range_pat(false, None, None)?;
914922
self.sess.gated_spans.gate(sym::box_patterns, box_span.to(self.prev_token.span));
915923
Ok(PatKind::Box(pat))
916924
}

0 commit comments

Comments
 (0)