Rollup merge of #152235 - JonathanBrouwer:convert_parse, r=JonathanBrouwer
Convert to inline diagnostics in `rustc_parse` This was the most annoying one by far, had to make a few changes to the representation of two errors (no user-facing changes tho), these changes are in separate commits for clarity :) For https://github.com/rust-lang/rust/issues/151366 r? @jdonszelmann
This commit is contained in:
commit
828b9c2cdf
18 changed files with 1448 additions and 1796 deletions
|
|
@ -4381,7 +4381,6 @@ dependencies = [
|
|||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
"rustc_fluent_macro",
|
||||
"rustc_index",
|
||||
"rustc_lexer",
|
||||
"rustc_macros",
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ pub fn default_translator() -> Translator {
|
|||
pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
|
||||
// tidy-alphabetical-start
|
||||
rustc_lint::DEFAULT_LOCALE_RESOURCE,
|
||||
rustc_parse::DEFAULT_LOCALE_RESOURCE,
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -53,10 +53,9 @@ pub struct Compiler {
|
|||
pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg {
|
||||
cfgs.into_iter()
|
||||
.map(|s| {
|
||||
let psess = ParseSess::emitter_with_note(
|
||||
vec![rustc_parse::DEFAULT_LOCALE_RESOURCE],
|
||||
format!("this occurred on the command line: `--cfg={s}`"),
|
||||
);
|
||||
let psess = ParseSess::emitter_with_note(format!(
|
||||
"this occurred on the command line: `--cfg={s}`"
|
||||
));
|
||||
let filename = FileName::cfg_spec_source_code(&s);
|
||||
|
||||
macro_rules! error {
|
||||
|
|
@ -125,10 +124,9 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch
|
|||
let mut check_cfg = CheckCfg { exhaustive_names, exhaustive_values, ..CheckCfg::default() };
|
||||
|
||||
for s in specs {
|
||||
let psess = ParseSess::emitter_with_note(
|
||||
vec![rustc_parse::DEFAULT_LOCALE_RESOURCE],
|
||||
format!("this occurred on the command line: `--check-cfg={s}`"),
|
||||
);
|
||||
let psess = ParseSess::emitter_with_note(format!(
|
||||
"this occurred on the command line: `--check-cfg={s}`"
|
||||
));
|
||||
let filename = FileName::cfg_spec_source_code(&s);
|
||||
|
||||
const VISIT: &str =
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use fluent_syntax::ast::{Expression, InlineExpression, Pattern, PatternElement};
|
|||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::Path;
|
||||
use syn::ext::IdentExt;
|
||||
use synstructure::{Structure, VariantInfo};
|
||||
|
||||
use crate::diagnostics::error::span_err;
|
||||
|
|
@ -100,7 +101,7 @@ fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&Var
|
|||
.bindings()
|
||||
.iter()
|
||||
.flat_map(|b| b.ast().ident.as_ref())
|
||||
.map(|id| id.to_string())
|
||||
.map(|id| id.unraw().to_string())
|
||||
.collect();
|
||||
for variable in variable_references(&message) {
|
||||
if !fields.iter().any(|f| f == variable) {
|
||||
|
|
@ -155,6 +156,8 @@ const ALLOWED_CAPITALIZED_WORDS: &[&str] = &[
|
|||
"MIR",
|
||||
"NaNs",
|
||||
"OK",
|
||||
"Rust",
|
||||
"Unicode",
|
||||
"VS",
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" }
|
|||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_feature = { path = "../rustc_feature" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_lexer = { path = "../rustc_lexer" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -75,8 +75,6 @@ const _: () = {
|
|||
}
|
||||
};
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
// Unwrap the result if `Ok`, otherwise emit the diagnostics and abort.
|
||||
pub fn unwrap_or_emit_fatal<T>(expr: Result<T, Vec<Diag<'_>>>) -> T {
|
||||
match expr {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use rustc_ast::token::{self, MetaVarKind};
|
|||
use rustc_ast::tokenstream::ParserRange;
|
||||
use rustc_ast::{AttrItemKind, Attribute, attr};
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Diag, PResult};
|
||||
use rustc_errors::{Diag, PResult, inline_fluent};
|
||||
use rustc_span::{BytePos, Span};
|
||||
use thin_vec::ThinVec;
|
||||
use tracing::debug;
|
||||
|
|
@ -13,7 +13,7 @@ use super::{
|
|||
Trailing, UsePreAttrPos,
|
||||
};
|
||||
use crate::parser::FnContext;
|
||||
use crate::{errors, exp, fluent_generated as fluent};
|
||||
use crate::{errors, exp};
|
||||
|
||||
// Public for rustfmt usage
|
||||
#[derive(Debug)]
|
||||
|
|
@ -68,7 +68,7 @@ impl<'a> Parser<'a> {
|
|||
let span = self.token.span;
|
||||
let mut err = self
|
||||
.dcx()
|
||||
.struct_span_err(span, fluent::parse_inner_doc_comment_not_permitted);
|
||||
.struct_span_err(span, inline_fluent!("expected outer doc comment"));
|
||||
err.code(E0753);
|
||||
if let Some(replacement_span) = self.annotate_following_item_if_applicable(
|
||||
&mut err,
|
||||
|
|
@ -79,10 +79,12 @@ impl<'a> Parser<'a> {
|
|||
},
|
||||
true,
|
||||
) {
|
||||
err.note(fluent::parse_note);
|
||||
err.note(inline_fluent!(
|
||||
"inner doc comments like this (starting with `//!` or `/*!`) can only appear before items"
|
||||
));
|
||||
err.span_suggestion_verbose(
|
||||
replacement_span,
|
||||
fluent::parse_suggestion,
|
||||
inline_fluent!("you might have meant to write a regular comment"),
|
||||
"",
|
||||
rustc_errors::Applicability::MachineApplicable,
|
||||
);
|
||||
|
|
@ -207,13 +209,25 @@ impl<'a> Parser<'a> {
|
|||
AllowConstBlockItems::Yes,
|
||||
) {
|
||||
Ok(Some(item)) => {
|
||||
// FIXME(#100717)
|
||||
err.arg("item", item.kind.descr());
|
||||
err.span_label(item.span, fluent::parse_label_does_not_annotate_this);
|
||||
err.span_label(
|
||||
item.span,
|
||||
match attr_type {
|
||||
OuterAttributeType::Attribute => {
|
||||
inline_fluent!("the inner attribute doesn't annotate this {$item}")
|
||||
}
|
||||
OuterAttributeType::DocComment | OuterAttributeType::DocBlockComment => {
|
||||
inline_fluent!("the inner doc comment doesn't annotate this {$item}")
|
||||
}
|
||||
},
|
||||
);
|
||||
if suggest_to_outer {
|
||||
err.span_suggestion_verbose(
|
||||
replacement_span,
|
||||
fluent::parse_sugg_change_inner_to_outer,
|
||||
match attr_type {
|
||||
OuterAttributeType::Attribute => inline_fluent!("to annotate the {$item}, change the attribute from inner to outer style"),
|
||||
OuterAttributeType::DocComment | OuterAttributeType::DocBlockComment => inline_fluent!("to annotate the {$item}, change the doc comment from inner to outer style"),
|
||||
},
|
||||
match attr_type {
|
||||
OuterAttributeType::Attribute => "",
|
||||
OuterAttributeType::DocBlockComment => "*",
|
||||
|
|
@ -244,28 +258,42 @@ impl<'a> Parser<'a> {
|
|||
self.dcx()
|
||||
.struct_span_err(
|
||||
attr_sp,
|
||||
fluent::parse_inner_attr_not_permitted_after_outer_doc_comment,
|
||||
inline_fluent!(
|
||||
"an inner attribute is not permitted following an outer doc comment"
|
||||
),
|
||||
)
|
||||
.with_span_label(
|
||||
attr_sp,
|
||||
inline_fluent!("not permitted following an outer doc comment"),
|
||||
)
|
||||
.with_span_label(attr_sp, fluent::parse_label_attr)
|
||||
.with_span_label(
|
||||
prev_doc_comment_span,
|
||||
fluent::parse_label_prev_doc_comment,
|
||||
inline_fluent!("previous doc comment"),
|
||||
)
|
||||
}
|
||||
Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => self
|
||||
.dcx()
|
||||
.struct_span_err(
|
||||
attr_sp,
|
||||
fluent::parse_inner_attr_not_permitted_after_outer_attr,
|
||||
inline_fluent!(
|
||||
"an inner attribute is not permitted following an outer attribute"
|
||||
),
|
||||
)
|
||||
.with_span_label(attr_sp, fluent::parse_label_attr)
|
||||
.with_span_label(prev_outer_attr_sp, fluent::parse_label_prev_attr),
|
||||
Some(InnerAttrForbiddenReason::InCodeBlock) | None => {
|
||||
self.dcx().struct_span_err(attr_sp, fluent::parse_inner_attr_not_permitted)
|
||||
}
|
||||
.with_span_label(
|
||||
attr_sp,
|
||||
inline_fluent!("not permitted following an outer attribute"),
|
||||
)
|
||||
.with_span_label(
|
||||
prev_outer_attr_sp,
|
||||
inline_fluent!("previous outer attribute"),
|
||||
),
|
||||
Some(InnerAttrForbiddenReason::InCodeBlock) | None => self.dcx().struct_span_err(
|
||||
attr_sp,
|
||||
inline_fluent!("an inner attribute is not permitted in this context"),
|
||||
),
|
||||
};
|
||||
|
||||
diag.note(fluent::parse_inner_attr_explanation);
|
||||
diag.note(inline_fluent!("inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files"));
|
||||
if self
|
||||
.annotate_following_item_if_applicable(
|
||||
&mut diag,
|
||||
|
|
@ -275,7 +303,9 @@ impl<'a> Parser<'a> {
|
|||
)
|
||||
.is_some()
|
||||
{
|
||||
diag.note(fluent::parse_outer_attr_explanation);
|
||||
diag.note(inline_fluent!(
|
||||
"outer attributes, like `#[test]`, annotate the item following them"
|
||||
));
|
||||
};
|
||||
diag.emit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use rustc_ast_pretty::pprust;
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, PResult, Subdiagnostic, Suggestions,
|
||||
pluralize,
|
||||
inline_fluent, pluralize,
|
||||
};
|
||||
use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
|
@ -41,10 +41,10 @@ use crate::errors::{
|
|||
TernaryOperatorSuggestion, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
|
||||
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
|
||||
};
|
||||
use crate::exp;
|
||||
use crate::parser::FnContext;
|
||||
use crate::parser::attr::InnerAttrPolicy;
|
||||
use crate::parser::item::IsDotDotDot;
|
||||
use crate::{exp, fluent_generated as fluent};
|
||||
|
||||
/// Creates a placeholder argument.
|
||||
pub(super) fn dummy_arg(ident: Ident, guar: ErrorGuaranteed) -> Param {
|
||||
|
|
@ -1272,7 +1272,7 @@ impl<'a> Parser<'a> {
|
|||
// We made sense of it. Improve the error message.
|
||||
e.span_suggestion_verbose(
|
||||
binop.span.shrink_to_lo(),
|
||||
fluent::parse_sugg_turbofish_syntax,
|
||||
inline_fluent!("use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments"),
|
||||
"::",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -727,25 +727,26 @@ impl<'a> Parser<'a> {
|
|||
);
|
||||
|
||||
let args_span = self.look_ahead(1, |t| t.span).to(span_after_type);
|
||||
let suggestion = errors::ComparisonOrShiftInterpretedAsGenericSugg {
|
||||
left: expr.span.shrink_to_lo(),
|
||||
right: expr.span.shrink_to_hi(),
|
||||
};
|
||||
|
||||
match self.token.kind {
|
||||
token::Lt => {
|
||||
self.dcx().emit_err(errors::ComparisonInterpretedAsGeneric {
|
||||
comparison: self.token.span,
|
||||
r#type: path,
|
||||
args: args_span,
|
||||
suggestion,
|
||||
suggestion: errors::ComparisonInterpretedAsGenericSugg {
|
||||
left: expr.span.shrink_to_lo(),
|
||||
right: expr.span.shrink_to_hi(),
|
||||
},
|
||||
})
|
||||
}
|
||||
token::Shl => self.dcx().emit_err(errors::ShiftInterpretedAsGeneric {
|
||||
shift: self.token.span,
|
||||
r#type: path,
|
||||
args: args_span,
|
||||
suggestion,
|
||||
suggestion: errors::ShiftInterpretedAsGenericSugg {
|
||||
left: expr.span.shrink_to_lo(),
|
||||
right: expr.span.shrink_to_hi(),
|
||||
},
|
||||
}),
|
||||
_ => {
|
||||
// We can end up here even without `<` being the next token, for
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_ast::{
|
|||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Applicability, PResult, StashKey, struct_span_code_err};
|
||||
use rustc_errors::{Applicability, PResult, StashKey, inline_fluent, struct_span_code_err};
|
||||
use rustc_session::lint::builtin::VARARGS_WITHOUT_PATTERN;
|
||||
use rustc_span::edit_distance::edit_distance;
|
||||
use rustc_span::edition::Edition;
|
||||
|
|
@ -26,7 +26,7 @@ use super::{
|
|||
Parser, PathStyle, Recovered, Trailing, UsePreAttrPos,
|
||||
};
|
||||
use crate::errors::{self, FnPointerCannotBeAsync, FnPointerCannotBeConst, MacroExpandsToAdtField};
|
||||
use crate::{exp, fluent_generated as fluent};
|
||||
use crate::exp;
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
/// Parses a source module as a crate. This is the main entry point for the parser.
|
||||
|
|
@ -1721,7 +1721,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
if this.token == token::Bang {
|
||||
if let Err(err) = this.unexpected() {
|
||||
err.with_note(fluent::parse_macro_expands_to_enum_variant).emit();
|
||||
err.with_note(inline_fluent!("macros cannot expand to enum variants")).emit();
|
||||
}
|
||||
|
||||
this.bump();
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ use crate::lexer::StripTokens;
|
|||
use crate::parser::{AllowConstBlockItems, ForceCollect, Parser};
|
||||
use crate::{new_parser_from_source_str, source_str_to_stream, unwrap_or_emit_fatal};
|
||||
|
||||
fn psess() -> ParseSess {
|
||||
ParseSess::new(vec![crate::DEFAULT_LOCALE_RESOURCE])
|
||||
}
|
||||
|
||||
fn filename(sm: &SourceMap, path: &str) -> FileName {
|
||||
FileName::Real(sm.path_mapping().to_real_filename(sm.working_dir(), PathBuf::from(path)))
|
||||
}
|
||||
|
|
@ -46,7 +42,7 @@ fn string_to_parser(psess: &ParseSess, source_str: String) -> Parser<'_> {
|
|||
fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Arc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
|
||||
let output = Arc::new(Mutex::new(Vec::new()));
|
||||
let source_map = Arc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let translator = Translator::with_fallback_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false);
|
||||
let translator = Translator::with_fallback_bundle(vec![], false);
|
||||
let shared: Box<dyn Write + Send> = Box::new(Shared { data: output.clone() });
|
||||
let auto_stream = AutoStream::never(shared);
|
||||
let dcx = DiagCtxt::new(Box::new(
|
||||
|
|
@ -93,7 +89,7 @@ where
|
|||
|
||||
/// Maps a string to tts, using a made-up filename.
|
||||
pub(crate) fn string_to_stream(source_str: String) -> TokenStream {
|
||||
let psess = psess();
|
||||
let psess = ParseSess::new(vec![]);
|
||||
unwrap_or_emit_fatal(source_str_to_stream(
|
||||
&psess,
|
||||
filename(psess.source_map(), "bogofile"),
|
||||
|
|
@ -2243,12 +2239,12 @@ fn sp(a: u32, b: u32) -> Span {
|
|||
|
||||
/// Parses a string, return an expression.
|
||||
fn string_to_expr(source_str: String) -> Box<ast::Expr> {
|
||||
with_error_checking_parse(source_str, &psess(), |p| p.parse_expr())
|
||||
with_error_checking_parse(source_str, &ParseSess::new(vec![]), |p| p.parse_expr())
|
||||
}
|
||||
|
||||
/// Parses a string, returns an item.
|
||||
fn string_to_item(source_str: String) -> Option<Box<ast::Item>> {
|
||||
with_error_checking_parse(source_str, &psess(), |p| {
|
||||
with_error_checking_parse(source_str, &ParseSess::new(vec![]), |p| {
|
||||
p.parse_item(ForceCollect::No, AllowConstBlockItems::Yes)
|
||||
})
|
||||
}
|
||||
|
|
@ -2484,7 +2480,7 @@ let mut fflags: c_int = wb();
|
|||
#[test]
|
||||
fn crlf_doc_comments() {
|
||||
create_default_session_globals_then(|| {
|
||||
let psess = psess();
|
||||
let psess = ParseSess::new(vec![]);
|
||||
|
||||
let name_1 = FileName::Custom("crlf_source_1".to_string());
|
||||
let source = "/// doc comment\r\nfn foo() {}".to_string();
|
||||
|
|
@ -2519,7 +2515,7 @@ fn ttdelim_span() {
|
|||
}
|
||||
|
||||
create_default_session_globals_then(|| {
|
||||
let psess = psess();
|
||||
let psess = ParseSess::new(vec![]);
|
||||
let expr = parse_expr_from_source_str(
|
||||
filename(psess.source_map(), "foo"),
|
||||
"foo!( fn main() { body } )".to_string(),
|
||||
|
|
@ -2555,7 +2551,7 @@ fn look_ahead() {
|
|||
let sym_S = Symbol::intern("S");
|
||||
let raw_no = IdentIsRaw::No;
|
||||
|
||||
let psess = psess();
|
||||
let psess = ParseSess::new(vec![]);
|
||||
let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string());
|
||||
|
||||
// Current position is the `fn`.
|
||||
|
|
@ -2630,7 +2626,7 @@ fn look_ahead_non_outermost_stream() {
|
|||
let sym_S = Symbol::intern("S");
|
||||
let raw_no = IdentIsRaw::No;
|
||||
|
||||
let psess = psess();
|
||||
let psess = ParseSess::new(vec![]);
|
||||
let mut p = string_to_parser(&psess, "mod m { fn f(x: u32) { x } struct S; }".to_string());
|
||||
|
||||
// Move forward to the `fn`, which is not within the outermost token
|
||||
|
|
@ -2662,7 +2658,7 @@ fn look_ahead_non_outermost_stream() {
|
|||
#[test]
|
||||
fn debug_lookahead() {
|
||||
create_default_session_globals_then(|| {
|
||||
let psess = psess();
|
||||
let psess = ParseSess::new(vec![]);
|
||||
let mut p = string_to_parser(&psess, "fn f(x: u32) { x } struct S;".to_string());
|
||||
|
||||
// Current position is the `fn`.
|
||||
|
|
@ -2883,7 +2879,7 @@ fn debug_lookahead() {
|
|||
#[test]
|
||||
fn out_of_line_mod() {
|
||||
create_default_session_globals_then(|| {
|
||||
let psess = psess();
|
||||
let psess = ParseSess::new(vec![]);
|
||||
let item = parse_item_from_source_str(
|
||||
filename(psess.source_map(), "foo"),
|
||||
"mod foo { struct S; mod this_does_not_exist; }".to_owned(),
|
||||
|
|
|
|||
|
|
@ -313,8 +313,8 @@ impl ParseSess {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn emitter_with_note(locale_resources: Vec<&'static str>, note: String) -> Self {
|
||||
let translator = Translator::with_fallback_bundle(locale_resources, false);
|
||||
pub fn emitter_with_note(note: String) -> Self {
|
||||
let translator = Translator::with_fallback_bundle(vec![], false);
|
||||
let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let emitter = Box::new(AnnotateSnippetEmitter::new(
|
||||
stderr_destination(ColorConfig::Auto),
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
//@ needs-symlink
|
||||
//@ needs-subprocess
|
||||
|
||||
// FIXME(151366) Currently `-Ztranslate-additional-ftl` is currently broken
|
||||
//@ ignore-test
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ pub fn main() {
|
|||
}
|
||||
|
||||
fn parse() {
|
||||
let psess = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]);
|
||||
let psess = ParseSess::new(vec![]);
|
||||
|
||||
let path = Path::new(file!());
|
||||
let path = path.canonicalize().unwrap();
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ fn main() {
|
|||
}
|
||||
|
||||
fn run() {
|
||||
let psess = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]);
|
||||
let psess = ParseSess::new(vec![]);
|
||||
|
||||
iter_exprs(2, &mut |mut e| {
|
||||
// If the pretty printer is correct, then `parse(print(e))` should be identical to `e`,
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ fn main() -> ExitCode {
|
|||
};
|
||||
|
||||
rustc_span::create_default_session_globals_then(|| {
|
||||
let psess = &ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]);
|
||||
let psess = &ParseSess::new(vec![]);
|
||||
|
||||
for &source_code in EXPRS {
|
||||
let Some(expr) = parse_expr(psess, source_code) else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue