Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggests turbofish in patterns #114300

Merged
merged 6 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ parse_found_expr_would_be_stmt = expected expression, found `{$token}`
parse_function_body_equals_expr = function body cannot be `= expression;`
.suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;`

parse_generic_args_in_pat_require_turbofish_syntax = generic args in patterns require the turbofish syntax

parse_generic_parameters_without_angle_brackets = generic parameters without surrounding angle brackets
.suggestion = surround the type parameters with angle brackets

Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2731,3 +2731,17 @@ pub(crate) struct WhereClauseBeforeConstBodySugg {
#[suggestion_part(code = "")]
pub right: Span,
}

#[derive(Diagnostic)]
#[diag(parse_generic_args_in_pat_require_turbofish_syntax)]
pub(crate) struct GenericArgsInPatRequireTurbofishSyntax {
#[primary_span]
pub span: Span,
#[suggestion(
parse_sugg_turbofish_syntax,
style = "verbose",
code = "::",
applicability = "maybe-incorrect"
)]
pub suggest_turbofish: Span,
}
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ impl<'a> Parser<'a> {
item
} else {
let do_parse = |this: &mut Self| {
let path = this.parse_path(PathStyle::Mod)?;
let path = this.parse_path(PathStyle::Mod, None)?;
let args = this.parse_attr_args()?;
Ok(ast::AttrItem { path, args, tokens: None })
};
Expand Down Expand Up @@ -387,7 +387,7 @@ impl<'a> Parser<'a> {
}

let lo = self.token.span;
let path = self.parse_path(PathStyle::Mod)?;
let path = self.parse_path(PathStyle::Mod, None)?;
let kind = self.parse_meta_item_kind()?;
let span = lo.to(self.prev_token.span);
Ok(ast::MetaItem { path, kind, span })
Expand Down
26 changes: 19 additions & 7 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,7 @@ impl<'a> Parser<'a> {
self.expect(&token::ModSep)?;

let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None };
self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?;
self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None, None)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super happy with the proliferation of Nones this causes, but I also don't have much of a better proposal (short of having a *_with_pat_location family of methods).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new changes reduce the Nones, but there are still some (seemingly unavoidable at the moment)

path.span = ty_span.to(self.prev_token.span);

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

let (ident, self_sugg, param_sugg, type_sugg, self_span, param_span, type_span) =
let (ident, self_sugg, param_sugg, type_sugg, self_span, param_span, type_span, maybe_name) =
match pat.kind {
PatKind::Ident(_, ident, _) => (
ident,
Expand All @@ -2029,6 +2029,7 @@ impl<'a> Parser<'a> {
pat.span.shrink_to_lo(),
pat.span.shrink_to_hi(),
pat.span.shrink_to_lo(),
true,
),
// Also catches `fn foo(&a)`.
PatKind::Ref(ref inner_pat, mutab)
Expand All @@ -2045,11 +2046,22 @@ impl<'a> Parser<'a> {
pat.span.shrink_to_lo(),
pat.span,
pat.span.shrink_to_lo(),
true,
)
}
_ => unreachable!(),
}
}
},
PatKind::Path(_, ref path) if let Some(segment) = path.segments.last() => (
segment.ident,
"self: ",
": TypeName".to_string(),
"_: ",
pat.span.shrink_to_lo(),
pat.span.shrink_to_hi(),
pat.span.shrink_to_lo(),
path.segments.len() == 1, // Avoid suggesting that `fn foo(a::b)` is fixed with a change to `fn foo(a::b: TypeName)`.
),
_ => {
// Otherwise, try to get a type and emit a suggestion.
if let Some(ty) = pat.to_ty() {
Expand Down Expand Up @@ -2077,7 +2089,7 @@ impl<'a> Parser<'a> {
}
// Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
// `fn foo(HashMap: TypeName<u32>)`.
if self.token != token::Lt {
if self.token != token::Lt && maybe_name {
err.span_suggestion(
param_span,
"if this is a parameter name, give it a type",
Expand All @@ -2100,7 +2112,7 @@ impl<'a> Parser<'a> {
}

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

Expand Down Expand Up @@ -2508,7 +2520,7 @@ impl<'a> Parser<'a> {
// Skip the `:`.
snapshot_pat.bump();
snapshot_type.bump();
match snapshot_pat.parse_pat_no_top_alt(expected) {
match snapshot_pat.parse_pat_no_top_alt(expected, None) {
Err(inner_err) => {
inner_err.cancel();
}
Expand Down Expand Up @@ -2772,7 +2784,7 @@ impl<'a> Parser<'a> {
/// sequence of patterns until `)` is reached.
fn skip_pat_list(&mut self) -> PResult<'a, ()> {
while !self.check(&token::CloseDelim(Delimiter::Parenthesis)) {
self.parse_pat_no_top_alt(None)?;
self.parse_pat_no_top_alt(None, None)?;
if !self.eat(&token::Comma) {
return Ok(());
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ impl<'a> Parser<'a> {
_ => {}
}

match self.parse_path(PathStyle::Expr) {
match self.parse_path(PathStyle::Expr, None) {
Ok(path) => {
let span_after_type = parser_snapshot_after_type.token.span;
let expr = mk_expr(
Expand Down Expand Up @@ -1314,7 +1314,7 @@ impl<'a> Parser<'a> {
}

let fn_span_lo = self.token.span;
let mut seg = self.parse_path_segment(PathStyle::Expr, None)?;
let mut seg = self.parse_path_segment(PathStyle::Expr, None, None)?;
self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]);
self.check_turbofish_missing_angle_brackets(&mut seg);

Expand Down Expand Up @@ -1544,7 +1544,7 @@ impl<'a> Parser<'a> {
})?;
(Some(qself), path)
} else {
(None, self.parse_path(PathStyle::Expr)?)
(None, self.parse_path(PathStyle::Expr, None)?)
};

// `!`, as an operator, is prefix, so we know this isn't that.
Expand Down Expand Up @@ -2338,7 +2338,7 @@ impl<'a> Parser<'a> {
let lo = self.token.span;
let attrs = self.parse_outer_attributes()?;
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
let pat = this.parse_pat_no_top_alt(Some(Expected::ParameterName))?;
let pat = this.parse_pat_no_top_alt(Some(Expected::ParameterName), None)?;
let ty = if this.eat(&token::Colon) {
this.parse_ty()?
} else {
Expand Down Expand Up @@ -2781,7 +2781,7 @@ impl<'a> Parser<'a> {
return None;
}
let pre_pat_snapshot = self.create_snapshot_for_diagnostic();
match self.parse_pat_no_top_alt(None) {
match self.parse_pat_no_top_alt(None, None) {
Ok(_pat) => {
if self.token.kind == token::FatArrow {
// Reached arm end.
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ impl<'a> Parser<'a> {

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

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

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

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1413,7 +1413,7 @@ impl<'a> Parser<'a> {
// Parse `pub(in path)`.
self.bump(); // `(`
self.bump(); // `in`
let path = self.parse_path(PathStyle::Mod)?; // `path`
let path = self.parse_path(PathStyle::Mod, None)?; // `path`
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
let vis = VisibilityKind::Restricted {
path: P(path),
Expand All @@ -1430,7 +1430,7 @@ impl<'a> Parser<'a> {
{
// Parse `pub(crate)`, `pub(self)`, or `pub(super)`.
self.bump(); // `(`
let path = self.parse_path(PathStyle::Mod)?; // `crate`/`super`/`self`
let path = self.parse_path(PathStyle::Mod, None)?; // `crate`/`super`/`self`
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`
let vis = VisibilityKind::Restricted {
path: P(path),
Expand All @@ -1456,7 +1456,7 @@ impl<'a> Parser<'a> {
/// Recovery for e.g. `pub(something) fn ...` or `struct X { pub(something) y: Z }`
fn recover_incorrect_vis_restriction(&mut self) -> PResult<'a, ()> {
self.bump(); // `(`
let path = self.parse_path(PathStyle::Mod)?;
let path = self.parse_path(PathStyle::Mod, None)?;
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)`

let path_str = pprust::path_to_string(&path);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/nonterminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl<'a> Parser<'a> {
},
NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr { .. } => {
token::NtPat(self.collect_tokens_no_attrs(|this| match kind {
NonterminalKind::PatParam { .. } => this.parse_pat_no_top_alt(None),
NonterminalKind::PatParam { .. } => this.parse_pat_no_top_alt(None, None),
NonterminalKind::PatWithOr { .. } => this.parse_pat_allow_top_alt(
None,
RecoverComma::No,
Expand Down Expand Up @@ -168,7 +168,7 @@ impl<'a> Parser<'a> {
}.into_diagnostic(&self.sess.span_diagnostic));
}
NonterminalKind::Path => token::NtPath(
P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?),
P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type, None))?),
),
NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item(true)?)),
NonterminalKind::Vis => token::NtVis(
Expand Down
Loading
Loading