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

Migrate rustc_passes diagnostics #100870

Closed
Closed
Show file tree
Hide file tree
Changes from all 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
22 changes: 22 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/passes.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ passes_debug_visualizer_invalid = invalid argument
.note_2 = OR
.note_3 = expected: `gdb_script_file = "..."`

passes_debug_visualizer_unreadable = couldn't read {$file}: {$error}

passes_rustc_allow_const_fn_unstable = attribute should be applied to `const fn`
.label = not a `const fn`

Expand Down Expand Up @@ -265,3 +267,23 @@ passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]`

passes_link_ordinal = attribute should be applied to a foreign function or static
.label = not a foreign function or static

passes_missing_panic_handler = `#[panic_handler]` function required, but not found

passes_missing_alloc_error_handler = `#[alloc_error_handler]` function required, but not found
.note = use `#![feature(default_alloc_error_handler)]` for a default error handler

passes_missing_lang_item = language item required, but not found: `{$name}`
.note = this can occur when a binary crate with `#![no_std]` is compiled for a target where `{$name}` is defined in the standard library
.help = you may be able to compile for a target that doesn't need `{$name}`, specify a target with `--target` or in `.cargo/config`

passes_lang_item_on_incorrect_target = `{$name}` language item must be applied to a {$expected_target}
.label = attribute should be applied to a {$expected_target}, not a {$actual_target}

passes_unknown_lang_item = definition of an unknown language item: `{$name}`
.label = definition of unknown language item `{$name}`

passes_local_duplicate_lang_item = found duplicate lang item `{$name}`

passes_invalid_attr_at_crate_level = `{$name}` attribute cannot be used at crate level
.suggestion = perhaps you meant to use an outer attribute
37 changes: 10 additions & 27 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! conflicts between multiple such attributes attached to the same
//! item.

use crate::errors;
use crate::errors::{self, DebugVisualizerUnreadable, InvalidAttrAtCrateLevel};
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{fluent, struct_span_err, Applicability, MultiSpan};
Expand Down Expand Up @@ -1842,13 +1842,11 @@ impl CheckAttrVisitor<'_> {
match std::fs::File::open(&file) {
Ok(_) => true,
Err(err) => {
self.tcx
.sess
.struct_span_err(
meta_item.span,
&format!("couldn't read {}: {}", file.display(), err),
)
.emit();
self.tcx.sess.emit_err(DebugVisualizerUnreadable {
span: meta_item.span,
file: &file,
error: err,
});
false
}
}
Expand Down Expand Up @@ -2158,25 +2156,10 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
if attr.style == AttrStyle::Inner {
for attr_to_check in ATTRS_TO_CHECK {
if attr.has_name(*attr_to_check) {
let mut err = tcx.sess.struct_span_err(
attr.span,
&format!(
"`{}` attribute cannot be used at crate level",
attr_to_check.to_ident_string()
),
);
// Only emit an error with a suggestion if we can create a
// string out of the attribute span
if let Ok(src) = tcx.sess.source_map().span_to_snippet(attr.span) {
let replacement = src.replace("#!", "#");
err.span_suggestion_verbose(
attr.span,
"perhaps you meant to use an outer attribute",
replacement,
rustc_errors::Applicability::MachineApplicable,
);
}
err.emit();
tcx.sess.emit_err(InvalidAttrAtCrateLevel {
span: attr.span,
name: *attr_to_check,
});
}
}
}
Expand Down
80 changes: 79 additions & 1 deletion compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use rustc_errors::{Applicability, MultiSpan};
use std::{io::Error, path::Path};

use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan};
use rustc_hir::Target;
use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
use rustc_session::SessionDiagnostic;
use rustc_span::{Span, Symbol};

#[derive(LintDiagnostic)]
Expand Down Expand Up @@ -526,6 +530,15 @@ pub struct DebugVisualizerInvalid {
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(passes::debug_visualizer_unreadable)]
pub struct DebugVisualizerUnreadable<'a> {
#[primary_span]
pub span: Span,
pub file: &'a Path,
pub error: Error,
}

#[derive(SessionDiagnostic)]
#[diag(passes::rustc_allow_const_fn_unstable)]
pub struct RustcAllowConstFnUnstable {
Expand Down Expand Up @@ -649,3 +662,68 @@ pub struct RustcLintOptDenyFieldAccess {
#[label]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(passes::missing_panic_handler)]
pub struct MissingPanicHandler;

#[derive(SessionDiagnostic)]
#[diag(passes::missing_alloc_error_handler)]
#[note]
pub struct MissingAllocErrorHandler;

#[derive(SessionDiagnostic)]
#[diag(passes::missing_lang_item)]
#[note]
#[help]
pub struct MissingLangItem {
pub name: Symbol,
}

#[derive(SessionDiagnostic)]
#[diag(passes::lang_item_on_incorrect_target, code = "E0718")]
pub struct LangItemOnIncorrectTarget {
#[primary_span]
#[label]
pub span: Span,
pub name: Symbol,
pub expected_target: Target,
pub actual_target: Target,
}

#[derive(SessionDiagnostic)]
#[diag(passes::unknown_lang_item, code = "E0522")]
pub struct UnknownLangItem {
#[primary_span]
#[label]
pub span: Span,
pub name: Symbol,
}

pub struct InvalidAttrAtCrateLevel {
pub span: Span,
pub name: Symbol,
}

impl SessionDiagnostic<'_> for InvalidAttrAtCrateLevel {
fn into_diagnostic(
self,
sess: &'_ rustc_session::parse::ParseSess,
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag = sess.struct_err(rustc_errors::fluent::passes::invalid_attr_at_crate_level);
diag.set_span(self.span);
diag.set_arg("name", self.name);
// Only emit an error with a suggestion if we can create a string out
// of the attribute span
if let Ok(src) = sess.source_map().span_to_snippet(self.span) {
let replacement = src.replace("#!", "#");
diag.span_suggestion_verbose(
self.span,
rustc_errors::fluent::passes::suggestion,
replacement,
rustc_errors::Applicability::MachineApplicable,
);
}
diag
}
}
29 changes: 6 additions & 23 deletions compiler/rustc_passes/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! * Functions called by the compiler itself.

use crate::check_attr::target_from_impl_item;
use crate::errors::{LangItemOnIncorrectTarget, UnknownLangItem};
use crate::weak_lang_items;

use rustc_errors::{pluralize, struct_span_err};
Expand Down Expand Up @@ -42,34 +43,16 @@ impl<'tcx> LanguageItemCollector<'tcx> {
}
// Known lang item with attribute on incorrect target.
Some((_, expected_target)) => {
struct_span_err!(
self.tcx.sess,
self.tcx.sess.emit_err(LangItemOnIncorrectTarget {
span,
E0718,
"`{}` language item must be applied to a {}",
value,
name: value,
expected_target,
)
.span_label(
span,
format!(
"attribute should be applied to a {}, not a {}",
expected_target, actual_target,
),
)
.emit();
actual_target,
});
}
// Unknown lang item.
_ => {
struct_span_err!(
self.tcx.sess,
span,
E0522,
"definition of an unknown language item: `{}`",
value
)
.span_label(span, format!("definition of unknown language item `{}`", value))
.emit();
self.tcx.sess.emit_err(UnknownLangItem { span, name: value });
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_passes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
//! This API is completely unstable and subject to change.

#![allow(rustc::potential_query_instability)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(iter_intersperse)]
#![feature(let_chains)]
Expand Down
15 changes: 5 additions & 10 deletions compiler/rustc_passes/src/weak_lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use rustc_middle::middle::lang_items::required;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::CrateType;

use crate::errors::{MissingAllocErrorHandler, MissingLangItem, MissingPanicHandler};

/// Checks the crate for usage of weak lang items, returning a vector of all the
/// language items required by this crate, but not defined yet.
pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>, items: &mut lang_items::LanguageItems) {
Expand Down Expand Up @@ -71,20 +73,13 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) {
for (name, &item) in WEAK_ITEMS_REFS.iter() {
if missing.contains(&item) && required(tcx, item) && items.require(item).is_err() {
if item == LangItem::PanicImpl {
tcx.sess.err("`#[panic_handler]` function required, but not found");
tcx.sess.emit_err(MissingPanicHandler);
} else if item == LangItem::Oom {
if !tcx.features().default_alloc_error_handler {
tcx.sess.err("`#[alloc_error_handler]` function required, but not found");
tcx.sess.note_without_error("use `#![feature(default_alloc_error_handler)]` for a default error handler");
tcx.sess.emit_err(MissingAllocErrorHandler);
}
} else {
tcx
.sess
.diagnostic()
.struct_err(&format!("language item required, but not found: `{}`", name))
.note(&format!("this can occur when a binary crate with `#![no_std]` is compiled for a target where `{}` is defined in the standard library", name))
.help(&format!("you may be able to compile for a target that doesn't need `{}`, specify a target with `--target` or in `.cargo/config`", name))
.emit();
tcx.sess.emit_err(MissingLangItem { name: *name });
}
}
}
Expand Down