summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_parse/src/parser/item.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_parse/src/parser/item.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_parse/src/parser/item.rs')
-rw-r--r--compiler/rustc_parse/src/parser/item.rs222
1 files changed, 98 insertions, 124 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 6422b8ac1..3783ec41b 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -71,7 +71,7 @@ impl<'a> Parser<'a> {
if !self.eat(term) {
let token_str = super::token_descr(&self.token);
if !self.maybe_consume_incorrect_semicolon(&items) {
- let msg = &format!("expected item, found {token_str}");
+ let msg = format!("expected item, found {token_str}");
let mut err = self.struct_span_err(self.token.span, msg);
let label = if self.is_kw_followed_by_ident(kw::Let) {
"consider using `const` or `static` instead of `let` for global variables"
@@ -181,11 +181,11 @@ impl<'a> Parser<'a> {
/// Error in-case `default` was parsed in an in-appropriate context.
fn error_on_unconsumed_default(&self, def: Defaultness, kind: &ItemKind) {
if let Defaultness::Default(span) = def {
- let msg = format!("{} {} cannot be `default`", kind.article(), kind.descr());
- self.struct_span_err(span, &msg)
- .span_label(span, "`default` because of this")
- .note("only associated `fn`, `const`, and `type` items can be `default`")
- .emit();
+ self.sess.emit_err(errors::InappropriateDefault {
+ span,
+ article: kind.article(),
+ descr: kind.descr(),
+ });
}
}
@@ -265,6 +265,9 @@ impl<'a> Parser<'a> {
// UNION ITEM
self.bump(); // `union`
self.parse_item_union()?
+ } else if self.is_builtin() {
+ // BUILTIN# ITEM
+ return self.parse_item_builtin();
} else if self.eat_keyword(kw::Macro) {
// MACROS 2.0 ITEM
self.parse_item_decl_macro(lo)?
@@ -310,14 +313,7 @@ impl<'a> Parser<'a> {
self.bump();
match self.parse_use_item() {
Ok(u) => {
- self.struct_span_err(span, format!("expected item, found {token_name}"))
- .span_suggestion_short(
- span,
- "items are imported using the `use` keyword",
- "use",
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(errors::RecoverImportAsUse { span, token_name });
Ok(Some(u))
}
Err(e) => {
@@ -441,6 +437,11 @@ impl<'a> Parser<'a> {
}
}
+ fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
+ // To be expanded
+ return Ok(None);
+ }
+
/// 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`
@@ -450,7 +451,7 @@ impl<'a> Parser<'a> {
Ok(args) => {
self.eat_semi_for_macro_if_needed(&args);
self.complain_if_pub_macro(vis, false);
- Ok(MacCall { path, args, prior_type_ascription: self.last_type_ascription })
+ Ok(MacCall { path, args })
}
Err(mut err) => {
@@ -602,10 +603,24 @@ impl<'a> Parser<'a> {
let path = match ty_first.kind {
// This notably includes paths passed through `ty` macro fragments (#46438).
TyKind::Path(None, path) => path,
- _ => {
- self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType {
- span: ty_first.span,
- });
+ other => {
+ if let TyKind::ImplTrait(_, bounds) = other
+ && let [bound] = bounds.as_slice()
+ {
+ // Suggest removing extra `impl` keyword:
+ // `impl<T: Default> impl Default for Wrapper<T>`
+ // ^^^^^
+ let extra_impl_kw = ty_first.span.until(bound.span());
+ self.sess
+ .emit_err(errors::ExtraImplKeywordInTraitImpl {
+ extra_impl_kw,
+ impl_trait_span: ty_first.span
+ });
+ } else {
+ self.sess.emit_err(errors::ExpectedTraitInTraitImplFoundType {
+ span: ty_first.span,
+ });
+ }
err_path(ty_first.span)
}
};
@@ -684,7 +699,7 @@ impl<'a> Parser<'a> {
// ```
&& self
.span_to_snippet(self.prev_token.span)
- .map_or(false, |snippet| snippet == "}")
+ .is_ok_and(|snippet| snippet == "}")
&& self.token.kind == token::Semi;
let mut semicolon_span = self.token.span;
if !is_unnecessary_semicolon {
@@ -795,11 +810,7 @@ impl<'a> Parser<'a> {
// Parse optional colon and supertrait bounds.
let had_colon = self.eat(&token::Colon);
let span_at_colon = self.prev_token.span;
- let bounds = if had_colon {
- self.parse_generic_bounds(Some(self.prev_token.span))?
- } else {
- Vec::new()
- };
+ let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() };
let span_before_eq = self.prev_token.span;
if self.eat(&token::Eq) {
@@ -809,7 +820,7 @@ impl<'a> Parser<'a> {
self.sess.emit_err(errors::BoundsNotAllowedOnTraitAliases { span });
}
- let bounds = self.parse_generic_bounds(None)?;
+ let bounds = self.parse_generic_bounds()?;
generics.where_clause = self.parse_where_clause()?;
self.expect_semi()?;
@@ -890,7 +901,7 @@ impl<'a> Parser<'a> {
// Parse optional colon and param bounds.
let bounds =
- if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() };
+ if self.eat(&token::Colon) { self.parse_generic_bounds()? } else { Vec::new() };
let before_where_clause = self.parse_where_clause()?;
let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
@@ -963,15 +974,8 @@ impl<'a> Parser<'a> {
} else {
// Recover from using a colon as path separator.
while self.eat_noexpect(&token::Colon) {
- self.struct_span_err(self.prev_token.span, "expected `::`, found `:`")
- .span_suggestion_short(
- self.prev_token.span,
- "use double colon",
- "::",
- Applicability::MachineApplicable,
- )
- .note_once("import paths are delimited using `::`")
- .emit();
+ self.sess
+ .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)?;
@@ -1134,13 +1138,11 @@ impl<'a> Parser<'a> {
))
}
- fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &str) -> Option<T> {
+ fn error_bad_item_kind<T>(&self, span: Span, kind: &ItemKind, ctx: &'static str) -> Option<T> {
// FIXME(#100717): needs variant for each `ItemKind` (instead of using `ItemKind::descr()`)
let span = self.sess.source_map().guess_head_span(span);
let descr = kind.descr();
- self.struct_span_err(span, &format!("{descr} is not supported in {ctx}"))
- .help(&format!("consider moving the {descr} out to a nearby module scope"))
- .emit();
+ self.sess.emit_err(errors::BadItemKind { span, descr, ctx });
None
}
@@ -1282,6 +1284,7 @@ impl<'a> Parser<'a> {
}
}
+ let prev_span = self.prev_token.span;
let id = self.parse_ident()?;
let mut generics = self.parse_generics()?;
generics.where_clause = self.parse_where_clause()?;
@@ -1293,10 +1296,28 @@ impl<'a> Parser<'a> {
(thin_vec![], false)
} else {
self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()).map_err(
- |mut e| {
- e.span_label(id.span, "while parsing this enum");
+ |mut err| {
+ err.span_label(id.span, "while parsing this enum");
+ if self.token == token::Colon {
+ let snapshot = self.create_snapshot_for_diagnostic();
+ self.bump();
+ match self.parse_ty() {
+ Ok(_) => {
+ err.span_suggestion_verbose(
+ prev_span,
+ "perhaps you meant to use `struct` here",
+ "struct".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ Err(e) => {
+ e.cancel();
+ }
+ }
+ self.restore_snapshot(snapshot);
+ }
self.recover_stmt();
- e
+ err
},
)?
};
@@ -1445,7 +1466,7 @@ impl<'a> Parser<'a> {
VariantData::Struct(fields, recovered)
} else {
let token_str = super::token_descr(&self.token);
- let msg = &format!("expected `where` or `{{` after union name, found {token_str}");
+ let msg = format!("expected `where` or `{{` after union name, found {token_str}");
let mut err = self.struct_span_err(self.token.span, msg);
err.span_label(self.token.span, "expected `where` or `{` after union name");
return Err(err);
@@ -1481,7 +1502,7 @@ impl<'a> Parser<'a> {
self.eat(&token::CloseDelim(Delimiter::Brace));
} else {
let token_str = super::token_descr(&self.token);
- let msg = &format!(
+ let msg = format!(
"expected {}`{{` after struct name, found {}",
if parsed_where { "" } else { "`where`, or " },
token_str
@@ -1618,7 +1639,7 @@ impl<'a> Parser<'a> {
let sp = self.prev_token.span.shrink_to_hi();
let mut err = self.struct_span_err(
sp,
- &format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
+ format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)),
);
// Try to recover extra trailing angle brackets
@@ -1713,27 +1734,13 @@ impl<'a> Parser<'a> {
self.expect_field_ty_separator()?;
let ty = self.parse_ty()?;
if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) {
- self.struct_span_err(self.token.span, "found single colon in a struct field type path")
- .span_suggestion_verbose(
- self.token.span,
- "write a path separator here",
- "::",
- Applicability::MaybeIncorrect,
- )
- .emit();
+ self.sess.emit_err(errors::SingleColonStructType { span: self.token.span });
}
if self.token.kind == token::Eq {
self.bump();
let const_expr = self.parse_expr_anon_const()?;
let sp = ty.span.shrink_to_hi().to(const_expr.value.span);
- self.struct_span_err(sp, "default values on `struct` fields aren't supported")
- .span_suggestion(
- sp,
- "remove this unsupported default value",
- "",
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(errors::EqualsStructDefault { span: sp });
}
Ok(FieldDef {
span: lo.to(self.prev_token.span),
@@ -1770,7 +1777,7 @@ impl<'a> Parser<'a> {
Ok(_) => {
let mut err = self.struct_span_err(
lo.to(self.prev_token.span),
- &format!("functions are not allowed in {adt_ty} definitions"),
+ format!("functions are not allowed in {adt_ty} definitions"),
);
err.help(
"unlike in C++, Java, and C#, functions are declared in `impl` blocks",
@@ -1789,7 +1796,7 @@ impl<'a> Parser<'a> {
Ok((ident, _)) => {
let mut err = self.struct_span_err(
lo.with_hi(ident.span.hi()),
- &format!("structs are not allowed in {adt_ty} definitions"),
+ format!("structs are not allowed in {adt_ty} definitions"),
);
err.help("consider creating a new `struct` definition instead of nesting");
err
@@ -1871,14 +1878,10 @@ impl<'a> Parser<'a> {
return IsMacroRulesItem::Yes { has_bang: true };
} else if self.look_ahead(1, |t| (t.is_ident())) {
// macro_rules foo
- self.struct_span_err(macro_rules_span, "expected `!` after `macro_rules`")
- .span_suggestion(
- macro_rules_span,
- "add a `!`",
- "macro_rules!",
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(errors::MacroRulesMissingBang {
+ span: macro_rules_span,
+ hi: macro_rules_span.shrink_to_hi(),
+ });
return IsMacroRulesItem::Yes { has_bang: false };
}
@@ -1903,9 +1906,7 @@ impl<'a> Parser<'a> {
if self.eat(&token::Not) {
// Handle macro_rules! foo!
let span = self.prev_token.span;
- self.struct_span_err(span, "macro names aren't followed by a `!`")
- .span_suggestion(span, "remove the `!`", "", Applicability::MachineApplicable)
- .emit();
+ self.sess.emit_err(errors::MacroNameRemoveBang { span });
}
let body = self.parse_delim_args()?;
@@ -1925,25 +1926,9 @@ impl<'a> Parser<'a> {
let vstr = pprust::vis_to_string(vis);
let vstr = vstr.trim_end();
if macro_rules {
- let msg = format!("can't qualify macro_rules invocation with `{vstr}`");
- self.struct_span_err(vis.span, &msg)
- .span_suggestion(
- vis.span,
- "try exporting the macro",
- "#[macro_export]",
- Applicability::MaybeIncorrect, // speculative
- )
- .emit();
+ self.sess.emit_err(errors::MacroRulesVisibility { span: vis.span, vis: vstr });
} else {
- self.struct_span_err(vis.span, "can't qualify macro invocation with `pub`")
- .span_suggestion(
- vis.span,
- "remove the visibility",
- "",
- Applicability::MachineApplicable,
- )
- .help(&format!("try adjusting the macro to put `{vstr}` inside the invocation"))
- .emit();
+ self.sess.emit_err(errors::MacroInvocationVisibility { span: vis.span, vis: vstr });
}
}
@@ -1989,18 +1974,12 @@ impl<'a> Parser<'a> {
let kw_token = self.token.clone();
let kw_str = pprust::token_to_string(&kw_token);
let item = self.parse_item(ForceCollect::No)?;
-
- self.struct_span_err(
- kw_token.span,
- &format!("`{kw_str}` definition cannot be nested inside `{keyword}`"),
- )
- .span_suggestion(
- item.unwrap().span,
- &format!("consider creating a new `{kw_str}` definition instead of nesting"),
- "",
- Applicability::MaybeIncorrect,
- )
- .emit();
+ self.sess.emit_err(errors::NestedAdt {
+ span: kw_token.span,
+ item: item.unwrap().span,
+ kw_str,
+ keyword: keyword.as_str(),
+ });
// We successfully parsed the item but we must inform the caller about nested problem.
return Ok(false);
}
@@ -2139,13 +2118,10 @@ impl<'a> Parser<'a> {
let _ = self.parse_expr()?;
self.expect_semi()?; // `;`
let span = eq_sp.to(self.prev_token.span);
- self.struct_span_err(span, "function body cannot be `= expression;`")
- .multipart_suggestion(
- "surround the expression with `{` and `}` instead of `=` and `;`",
- vec![(eq_sp, "{".to_string()), (self.prev_token.span, " }".to_string())],
- Applicability::MachineApplicable,
- )
- .emit();
+ self.sess.emit_err(errors::FunctionBodyEqualsExpr {
+ span,
+ sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
+ });
(AttrVec::new(), Some(self.mk_block_err(span)))
} else {
let expected = if req_body {
@@ -2289,11 +2265,11 @@ impl<'a> Parser<'a> {
err.span_suggestion(
self.token.uninterpolated_span(),
- &format!("`{original_kw}` already used earlier, remove this one"),
+ format!("`{original_kw}` already used earlier, remove this one"),
"",
Applicability::MachineApplicable,
)
- .span_note(original_sp, &format!("`{original_kw}` first seen here"));
+ .span_note(original_sp, format!("`{original_kw}` first seen here"));
}
// The keyword has not been seen yet, suggest correct placement in the function front matter
else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw {
@@ -2304,7 +2280,7 @@ impl<'a> Parser<'a> {
err.span_suggestion(
correct_pos_sp.to(misplaced_qual_sp),
- &format!("`{misplaced_qual}` must come before `{current_qual}`"),
+ format!("`{misplaced_qual}` must come before `{current_qual}`"),
format!("{misplaced_qual} {current_qual}"),
Applicability::MachineApplicable,
).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`");
@@ -2328,7 +2304,7 @@ impl<'a> Parser<'a> {
if matches!(orig_vis.kind, VisibilityKind::Inherited) {
err.span_suggestion(
sp_start.to(self.prev_token.span),
- &format!("visibility `{vs}` must come before `{snippet}`"),
+ format!("visibility `{vs}` must come before `{snippet}`"),
format!("{vs} {snippet}"),
Applicability::MachineApplicable,
);
@@ -2577,14 +2553,12 @@ impl<'a> Parser<'a> {
}
fn recover_self_param(&mut self) -> bool {
- match self
- .parse_outer_attributes()
- .and_then(|_| self.parse_self_param())
- .map_err(|e| e.cancel())
- {
- Ok(Some(_)) => true,
- _ => false,
- }
+ matches!(
+ self.parse_outer_attributes()
+ .and_then(|_| self.parse_self_param())
+ .map_err(|e| e.cancel()),
+ Ok(Some(_))
+ )
}
}