Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
Orion Gonzalez committed Oct 2, 2024
1 parent 44722bd commit 011dd54
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 28 deletions.
6 changes: 5 additions & 1 deletion compiler/rustc_ast_pretty/src/pprust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::borrow::Cow;
use rustc_ast as ast;
use rustc_ast::token::{Nonterminal, Token, TokenKind};
use rustc_ast::tokenstream::{TokenStream, TokenTree};
pub use state::{AnnNode, Comments, PpAnn, PrintState, State, print_crate};
pub use state::{print_crate, AnnNode, Comments, PpAnn, PrintState, State};

pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
State::new().nonterminal_to_string(nt)
Expand Down Expand Up @@ -63,6 +63,10 @@ pub fn path_segment_to_string(p: &ast::PathSegment) -> String {
State::new().path_segment_to_string(p)
}

pub fn stmt_to_string(p: &ast::Stmt) -> String {
State::new().stmt_to_string(p)
}

pub fn vis_to_string(v: &ast::Visibility) -> String {
State::new().vis_to_string(v)
}
Expand Down
100 changes: 73 additions & 27 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ use rustc_ast::util::case::Case;
use rustc_ast::{self as ast};
use rustc_ast_pretty::pprust;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err};
use rustc_errors::{struct_span_code_err, Applicability, PResult, StashKey};
use rustc_span::edit_distance::edit_distance;
use rustc_span::edition::Edition;
use rustc_span::symbol::{Ident, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, source_map};
use thin_vec::{ThinVec, thin_vec};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{source_map, ErrorGuaranteed, Span, DUMMY_SP};
use thin_vec::{thin_vec, ThinVec};
use tracing::debug;

use super::diagnostics::{ConsumeClosingDelim, dummy_arg};
use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{
AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, Trailing, UsePreAttrPos,
AttemptLocalParseRecovery, AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle,
Trailing, UsePreAttrPos,
};
use crate::errors::{self, MacroExpandsToAdtField};
use crate::{fluent_generated as fluent, maybe_whole};
Expand Down Expand Up @@ -75,20 +76,8 @@ impl<'a> Parser<'a> {
}

if !self.eat(term) {
let token_str = super::token_descr(&self.token);
if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {
let msg = format!("expected item, found {token_str}");
let mut err = self.dcx().struct_span_err(self.token.span, msg);
let span = self.token.span;
if self.is_kw_followed_by_ident(kw::Let) {
err.span_label(
span,
"consider using `const` or `static` instead of `let` for global variables",
);
} else {
err.span_label(span, "expected item")
.note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");
};
let err = self.fallback_incorrect_item();
return Err(err);
}
}
Expand All @@ -97,6 +86,55 @@ impl<'a> Parser<'a> {
let mod_spans = ModSpans { inner_span: lo.to(self.prev_token.span), inject_use_span };
Ok((attrs, items, mod_spans))
}

/// Tries to parse the item as a statement to provide further diagnostics.
fn fallback_incorrect_item(&mut self) -> rustc_errors::Diag<'a> {
let token_str = super::token_descr(&self.token);
let mut err = self
.dcx()
.struct_span_err(self.token.span, format!("expected item, found {token_str}"));

match self.parse_full_stmt(AttemptLocalParseRecovery::No) {
Ok(Some(stmt)) => {
let span = stmt.span;
match &stmt.kind {
StmtKind::Let(_) => {
err.span_label(span, "unexpected `let` binding outside of a function")
.help(format!("consider using `const` or `static` instead of `let` for global variables, or put it inside of a function: fn foo() {{ {} }}",
pprust::stmt_to_string(&stmt)));
}
StmtKind::Semi(expr) => {
err.span_label(span, "unexpected expression").help(format!(
"consider putting it inside a function: fn foo() {{ {}; }}",
pprust::expr_to_string(expr)
));
}
StmtKind::Expr(expr) => {
err.span_label(span, "unexpected expression").help(format!(
"consider putting it inside a function: fn foo() {{ {} }}",
pprust::expr_to_string(expr)
));
}
StmtKind::Empty => {
unreachable!(
"Should have been handled by maybe_consume_incorrect_semicolon"
);
}
StmtKind::Item(_) | StmtKind::MacCall(_) => {
unreachable!("These should be valid.")
}
};
}
Ok(None) => {} // It's not a statement, not much we can do.
Err(e) => {
// We don't really care about an error parsing this statement.
e.cancel();
}
}
err.note("for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>");

err
}
}

pub(super) type ItemInfo = (Ident, ItemKind);
Expand Down Expand Up @@ -452,7 +490,11 @@ impl<'a> Parser<'a> {
None
};

if let Some(err) = err { Err(self.dcx().create_err(err)) } else { Ok(()) }
if let Some(err) = err {
Err(self.dcx().create_err(err))
} else {
Ok(())
}
}

fn parse_item_builtin(&mut self) -> PResult<'a, Option<ItemInfo>> {
Expand Down Expand Up @@ -1112,7 +1154,11 @@ impl<'a> Parser<'a> {
}

fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
if self.eat_keyword(kw::As) { self.parse_ident_or_underscore().map(Some) } else { Ok(None) }
if self.eat_keyword(kw::As) {
self.parse_ident_or_underscore().map(Some)
} else {
Ok(None)
}
}

fn parse_ident_or_underscore(&mut self) -> PResult<'a, Ident> {
Expand Down Expand Up @@ -1195,7 +1241,7 @@ impl<'a> Parser<'a> {
mut safety: Safety,
) -> PResult<'a, ItemInfo> {
let abi = self.parse_abi(); // ABI?
// FIXME: This recovery should be tested better.
// FIXME: This recovery should be tested better.
if safety == Safety::Default
&& self.token.is_keyword(kw::Unsafe)
&& self.look_ahead(1, |t| *t == token::OpenDelim(Delimiter::Brace))
Expand Down Expand Up @@ -1897,10 +1943,10 @@ impl<'a> Parser<'a> {
// Try to recover extra trailing angle brackets
if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind {
if let Some(last_segment) = segments.last() {
let guar = self.check_trailing_angle_brackets(last_segment, &[
&token::Comma,
&token::CloseDelim(Delimiter::Brace),
]);
let guar = self.check_trailing_angle_brackets(
last_segment,
&[&token::Comma, &token::CloseDelim(Delimiter::Brace)],
);
if let Some(_guar) = guar {
// Handle a case like `Vec<u8>>,` where we can continue parsing fields
// after the comma
Expand Down Expand Up @@ -2107,7 +2153,7 @@ impl<'a> Parser<'a> {
self.unexpected()?;
}
let body = self.parse_token_tree(); // `MacBody`
// Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
// Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
let bspan = body.span();
let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>`
let tokens = TokenStream::new(vec![params, arrow, body]);
Expand Down

0 comments on commit 011dd54

Please sign in to comment.