Migrate parts of rustc_expand to session diagnostics

This migrates everything but the `mbe` and `proc_macro` modules. It also
contains a few cleanups and drive-by/accidental diagnostic improvements
which can be seen in the diff for the UI tests.
This commit is contained in:
nils 2022-11-15 14:24:33 +01:00 committed by Nilstrieb
parent a000811405
commit 2f9f097cb8
19 changed files with 640 additions and 236 deletions

View file

@ -1,13 +1,17 @@
use crate::base::ModuleData;
use crate::errors::{
ModuleCircular, ModuleFileNotFound, ModuleInBlock, ModuleInBlockName, ModuleMultipleCandidates,
};
use rustc_ast::ptr::P;
use rustc_ast::{token, AttrVec, Attribute, Inline, Item, ModSpans};
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed};
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_parse::new_parser_from_file;
use rustc_parse::validate_attr;
use rustc_session::parse::ParseSess;
use rustc_session::Session;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use std::iter::once;
use std::path::{self, Path, PathBuf};
@ -242,57 +246,41 @@ pub fn default_submod_path<'a>(
impl ModError<'_> {
fn report(self, sess: &Session, span: Span) -> ErrorGuaranteed {
let diag = &sess.parse_sess.span_diagnostic;
match self {
ModError::CircularInclusion(file_paths) => {
let mut msg = String::from("circular modules: ");
for file_path in &file_paths {
msg.push_str(&file_path.display().to_string());
msg.push_str(" -> ");
}
msg.push_str(&file_paths[0].display().to_string());
diag.struct_span_err(span, &msg)
let path_to_string = |path: &PathBuf| path.display().to_string();
let paths = file_paths
.iter()
.map(path_to_string)
.chain(once(path_to_string(&file_paths[0])))
.collect::<Vec<_>>();
let modules = paths.join(" -> ");
sess.emit_err(ModuleCircular { span, modules })
}
ModError::ModInBlock(ident) => {
let msg = "cannot declare a non-inline module inside a block unless it has a path attribute";
let mut err = diag.struct_span_err(span, msg);
if let Some(ident) = ident {
let note =
format!("maybe `use` the module `{}` instead of redeclaring it", ident);
err.span_note(span, &note);
}
err
}
ModError::FileNotFound(ident, default_path, secondary_path) => {
let mut err = struct_span_err!(
diag,
ModError::ModInBlock(ident) => sess.emit_err(ModuleInBlock {
span,
name: ident.map(|name| ModuleInBlockName { span, name }),
}),
ModError::FileNotFound(name, default_path, secondary_path) => {
sess.emit_err(ModuleFileNotFound {
span,
E0583,
"file not found for module `{}`",
ident,
);
err.help(&format!(
"to create the module `{}`, create file \"{}\" or \"{}\"",
ident,
default_path.display(),
secondary_path.display(),
));
err
name,
default_path: default_path.display().to_string(),
secondary_path: secondary_path.display().to_string(),
})
}
ModError::MultipleCandidates(ident, default_path, secondary_path) => {
let mut err = struct_span_err!(
diag,
ModError::MultipleCandidates(name, default_path, secondary_path) => {
sess.emit_err(ModuleMultipleCandidates {
span,
E0761,
"file for module `{}` found at both \"{}\" and \"{}\"",
ident,
default_path.display(),
secondary_path.display(),
);
err.help("delete or rename one of them to remove the ambiguity");
err
name,
default_path: default_path.display().to_string(),
secondary_path: secondary_path.display().to_string(),
})
}
ModError::ParserError(err) => err,
}.emit()
ModError::ParserError(mut err) => err.emit(),
}
}
}