mirror of https://github.com/rust-lang/rust.git
Rollup merge of #121382 - nnethercote:rework-untranslatable_diagnostic-lint, r=davidtwco
Rework `untranslatable_diagnostic` lint Currently it only checks calls to functions marked with `#[rustc_lint_diagnostics]`. This PR changes it to check calls to any function with an `impl Into<{D,Subd}iagnosticMessage>` parameter. This greatly improves its coverage and doesn't rely on people remembering to add `#[rustc_lint_diagnostics]`. It also lets us add `#[rustc_lint_diagnostics]` to a number of functions that don't have an `impl Into<{D,Subd}iagnosticMessage>`, such as `Diag::span`. r? ``@davidtwco``
This commit is contained in:
commit
efe9deace8
|
@ -1,6 +1,9 @@
|
||||||
|
use std::borrow::{Borrow, Cow};
|
||||||
|
use std::cmp;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
use std::iter;
|
||||||
|
use std::ops::Bound;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::{borrow::Borrow, cmp, iter, ops::Bound};
|
|
||||||
|
|
||||||
use rustc_index::Idx;
|
use rustc_index::Idx;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
@ -32,7 +35,7 @@ where
|
||||||
pub trait LayoutCalculator {
|
pub trait LayoutCalculator {
|
||||||
type TargetDataLayoutRef: Borrow<TargetDataLayout>;
|
type TargetDataLayoutRef: Borrow<TargetDataLayout>;
|
||||||
|
|
||||||
fn delayed_bug(&self, txt: String);
|
fn delayed_bug(&self, txt: impl Into<Cow<'static, str>>);
|
||||||
fn current_data_layout(&self) -> Self::TargetDataLayoutRef;
|
fn current_data_layout(&self) -> Self::TargetDataLayoutRef;
|
||||||
|
|
||||||
fn scalar_pair<FieldIdx: Idx, VariantIdx: Idx>(
|
fn scalar_pair<FieldIdx: Idx, VariantIdx: Idx>(
|
||||||
|
|
|
@ -22,6 +22,7 @@ use std::collections::hash_map::Entry;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
pub(crate) fn lower_inline_asm(
|
pub(crate) fn lower_inline_asm(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
|
|
@ -1513,6 +1513,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
|
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
|
||||||
let yielded =
|
let yielded =
|
||||||
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
|
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
|
||||||
|
|
|
@ -2272,6 +2272,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.expr_block(block)
|
self.expr_block(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
||||||
match c.value.kind {
|
match c.value.kind {
|
||||||
ExprKind::Underscore => {
|
ExprKind::Underscore => {
|
||||||
|
|
|
@ -17,6 +17,7 @@ use crate::errors;
|
||||||
macro_rules! gate {
|
macro_rules! gate {
|
||||||
($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{
|
($visitor:expr, $feature:ident, $span:expr, $explain:expr) => {{
|
||||||
if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
|
if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
feature_err(&$visitor.sess, sym::$feature, $span, $explain).emit();
|
feature_err(&$visitor.sess, sym::$feature, $span, $explain).emit();
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -34,6 +35,7 @@ macro_rules! gate {
|
||||||
macro_rules! gate_alt {
|
macro_rules! gate_alt {
|
||||||
($visitor:expr, $has_feature:expr, $name:expr, $span:expr, $explain:expr) => {{
|
($visitor:expr, $has_feature:expr, $name:expr, $span:expr, $explain:expr) => {{
|
||||||
if !$has_feature && !$span.allows_unstable($name) {
|
if !$has_feature && !$span.allows_unstable($name) {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
feature_err(&$visitor.sess, $name, $span, $explain).emit();
|
feature_err(&$visitor.sess, $name, $span, $explain).emit();
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
@ -73,6 +75,7 @@ struct PostExpansionVisitor<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PostExpansionVisitor<'a> {
|
impl<'a> PostExpansionVisitor<'a> {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn check_abi(&self, abi: ast::StrLit, constness: ast::Const) {
|
fn check_abi(&self, abi: ast::StrLit, constness: ast::Const) {
|
||||||
let ast::StrLit { symbol_unescaped, span, .. } = abi;
|
let ast::StrLit { symbol_unescaped, span, .. } = abi;
|
||||||
|
|
||||||
|
@ -579,6 +582,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
||||||
if let Ok(snippet) = sm.span_to_snippet(span)
|
if let Ok(snippet) = sm.span_to_snippet(span)
|
||||||
&& snippet == "!"
|
&& snippet == "!"
|
||||||
{
|
{
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
feature_err(sess, sym::never_patterns, span, "`!` patterns are experimental")
|
feature_err(sess, sym::never_patterns, span, "`!` patterns are experimental")
|
||||||
.emit();
|
.emit();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -516,6 +516,7 @@ pub struct Condition {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests if a cfg-pattern matches the cfg set
|
/// Tests if a cfg-pattern matches the cfg set
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
pub fn cfg_matches(
|
pub fn cfg_matches(
|
||||||
cfg: &ast::MetaItem,
|
cfg: &ast::MetaItem,
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
|
@ -566,6 +567,7 @@ fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Feat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) {
|
fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) {
|
||||||
let (cfg, feature, has_feature) = gated_cfg;
|
let (cfg, feature, has_feature) = gated_cfg;
|
||||||
if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
|
if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
|
||||||
|
@ -592,6 +594,7 @@ fn parse_version(s: Symbol) -> Option<RustcVersion> {
|
||||||
|
|
||||||
/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
|
/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
|
||||||
/// evaluate individual items.
|
/// evaluate individual items.
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
pub fn eval_condition(
|
pub fn eval_condition(
|
||||||
cfg: &ast::MetaItem,
|
cfg: &ast::MetaItem,
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
|
|
|
@ -76,6 +76,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
/// LL | for (key, value) in dict {
|
/// LL | for (key, value) in dict {
|
||||||
/// | ^^^^
|
/// | ^^^^
|
||||||
/// ```
|
/// ```
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)] // FIXME
|
||||||
pub(super) fn add_moved_or_invoked_closure_note(
|
pub(super) fn add_moved_or_invoked_closure_note(
|
||||||
&self,
|
&self,
|
||||||
location: Location,
|
location: Location,
|
||||||
|
@ -585,6 +586,7 @@ impl UseSpans<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a span label to the arguments of the closure, if it exists.
|
/// Add a span label to the arguments of the closure, if it exists.
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
pub(super) fn args_subdiag(
|
pub(super) fn args_subdiag(
|
||||||
self,
|
self,
|
||||||
dcx: &rustc_errors::DiagCtxt,
|
dcx: &rustc_errors::DiagCtxt,
|
||||||
|
@ -598,6 +600,7 @@ impl UseSpans<'_> {
|
||||||
|
|
||||||
/// Add a span label to the use of the captured variable, if it exists.
|
/// Add a span label to the use of the captured variable, if it exists.
|
||||||
/// only adds label to the `path_span`
|
/// only adds label to the `path_span`
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
pub(super) fn var_path_only_subdiag(
|
pub(super) fn var_path_only_subdiag(
|
||||||
self,
|
self,
|
||||||
dcx: &rustc_errors::DiagCtxt,
|
dcx: &rustc_errors::DiagCtxt,
|
||||||
|
@ -635,6 +638,7 @@ impl UseSpans<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a subdiagnostic to the use of the captured variable, if it exists.
|
/// Add a subdiagnostic to the use of the captured variable, if it exists.
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
pub(super) fn var_subdiag(
|
pub(super) fn var_subdiag(
|
||||||
self,
|
self,
|
||||||
dcx: &rustc_errors::DiagCtxt,
|
dcx: &rustc_errors::DiagCtxt,
|
||||||
|
@ -1008,6 +1012,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
self.borrow_spans(span, borrow.reserve_location)
|
self.borrow_spans(span, borrow.reserve_location)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn explain_captures(
|
fn explain_captures(
|
||||||
&mut self,
|
&mut self,
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
|
|
|
@ -201,6 +201,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
// For generic associated types (GATs) which implied 'static requirement
|
// For generic associated types (GATs) which implied 'static requirement
|
||||||
// from higher-ranked trait bounds (HRTB). Try to locate span of the trait
|
// from higher-ranked trait bounds (HRTB). Try to locate span of the trait
|
||||||
// and the span which bounded to the trait for adding 'static lifetime suggestion
|
// and the span which bounded to the trait for adding 'static lifetime suggestion
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn suggest_static_lifetime_for_gat_from_hrtb(
|
fn suggest_static_lifetime_for_gat_from_hrtb(
|
||||||
&self,
|
&self,
|
||||||
diag: &mut Diag<'_>,
|
diag: &mut Diag<'_>,
|
||||||
|
@ -254,9 +256,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
hrtb_bounds.iter().for_each(|bound| {
|
hrtb_bounds.iter().for_each(|bound| {
|
||||||
let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { return; };
|
let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { return; };
|
||||||
// FIXME: make this translatable
|
|
||||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
|
||||||
#[allow(rustc::untranslatable_diagnostic)]
|
|
||||||
diag.span_note(
|
diag.span_note(
|
||||||
*trait_span,
|
*trait_span,
|
||||||
"due to current limitations in the borrow checker, this implies a `'static` lifetime"
|
"due to current limitations in the borrow checker, this implies a `'static` lifetime"
|
||||||
|
@ -580,6 +579,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
/// executing...
|
/// executing...
|
||||||
/// = note: ...therefore, returned references to captured variables will escape the closure
|
/// = note: ...therefore, returned references to captured variables will escape the closure
|
||||||
/// ```
|
/// ```
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)] // FIXME
|
||||||
fn report_fnmut_error(
|
fn report_fnmut_error(
|
||||||
&self,
|
&self,
|
||||||
errci: &ErrorConstraintInfo<'tcx>,
|
errci: &ErrorConstraintInfo<'tcx>,
|
||||||
|
@ -761,6 +761,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
/// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it
|
/// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it
|
||||||
/// | is returning data with lifetime `'b`
|
/// | is returning data with lifetime `'b`
|
||||||
/// ```
|
/// ```
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)] // FIXME
|
||||||
fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'tcx> {
|
fn report_general_error(&self, errci: &ErrorConstraintInfo<'tcx>) -> Diag<'tcx> {
|
||||||
let ErrorConstraintInfo {
|
let ErrorConstraintInfo {
|
||||||
fr,
|
fr,
|
||||||
|
@ -822,6 +823,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
/// LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + 'a {
|
/// LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + 'a {
|
||||||
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
/// ```
|
/// ```
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn add_static_impl_trait_suggestion(
|
fn add_static_impl_trait_suggestion(
|
||||||
&self,
|
&self,
|
||||||
diag: &mut Diag<'_>,
|
diag: &mut Diag<'_>,
|
||||||
|
@ -972,6 +975,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
self.suggest_constrain_dyn_trait_in_impl(diag, &visitor.0, ident, self_ty);
|
self.suggest_constrain_dyn_trait_in_impl(diag, &visitor.0, ident, self_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
#[instrument(skip(self, err), level = "debug")]
|
#[instrument(skip(self, err), level = "debug")]
|
||||||
fn suggest_constrain_dyn_trait_in_impl(
|
fn suggest_constrain_dyn_trait_in_impl(
|
||||||
&self,
|
&self,
|
||||||
|
@ -1034,6 +1039,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag);
|
suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) {
|
fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) {
|
||||||
let map = self.infcx.tcx.hir();
|
let map = self.infcx.tcx.hir();
|
||||||
let body_id = map.body_owned_by(self.mir_def_id());
|
let body_id = map.body_owned_by(self.mir_def_id());
|
||||||
|
|
|
@ -62,6 +62,7 @@ impl<'tcx> NonConstOp<'tcx> for FloatingPointOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
||||||
feature_err(
|
feature_err(
|
||||||
&ccx.tcx.sess,
|
&ccx.tcx.sess,
|
||||||
|
@ -556,6 +557,7 @@ impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
|
||||||
Status::Unstable(sym::const_mut_refs)
|
Status::Unstable(sym::const_mut_refs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
||||||
feature_err(
|
feature_err(
|
||||||
&ccx.tcx.sess,
|
&ccx.tcx.sess,
|
||||||
|
@ -589,6 +591,7 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
||||||
let mut err = feature_err(
|
let mut err = feature_err(
|
||||||
&ccx.tcx.sess,
|
&ccx.tcx.sess,
|
||||||
|
@ -632,6 +635,7 @@ pub mod ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
||||||
feature_err(
|
feature_err(
|
||||||
&ccx.tcx.sess,
|
&ccx.tcx.sess,
|
||||||
|
|
|
@ -97,6 +97,7 @@ impl Expander {
|
||||||
/// **Note:** This function doesn't interpret argument 0 in any special way.
|
/// **Note:** This function doesn't interpret argument 0 in any special way.
|
||||||
/// If this function is intended to be used with command line arguments,
|
/// If this function is intended to be used with command line arguments,
|
||||||
/// `argv[0]` must be removed prior to calling it manually.
|
/// `argv[0]` must be removed prior to calling it manually.
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<String> {
|
pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<String> {
|
||||||
let mut expander = Expander::default();
|
let mut expander = Expander::default();
|
||||||
for arg in at_args {
|
for arg in at_args {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
//!
|
//!
|
||||||
//! This API is completely unstable and subject to change.
|
//! This API is completely unstable and subject to change.
|
||||||
|
|
||||||
|
#![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![doc(rust_logo)]
|
#![doc(rust_logo)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
|
|
@ -598,6 +598,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
///
|
///
|
||||||
/// In the meantime, though, callsites are required to deal with the "bug"
|
/// In the meantime, though, callsites are required to deal with the "bug"
|
||||||
/// locally in whichever way makes the most sense.
|
/// locally in whichever way makes the most sense.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn downgrade_to_delayed_bug(&mut self) {
|
pub fn downgrade_to_delayed_bug(&mut self) {
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -631,6 +632,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
with_fn! { with_span_labels,
|
with_fn! { with_span_labels,
|
||||||
/// Labels all the given spans with the provided label.
|
/// Labels all the given spans with the provided label.
|
||||||
/// See [`Self::span_label()`] for more information.
|
/// See [`Self::span_label()`] for more information.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_labels(&mut self, spans: impl IntoIterator<Item = Span>, label: &str) -> &mut Self {
|
pub fn span_labels(&mut self, spans: impl IntoIterator<Item = Span>, label: &str) -> &mut Self {
|
||||||
for span in spans {
|
for span in spans {
|
||||||
self.span_label(span, label.to_string());
|
self.span_label(span, label.to_string());
|
||||||
|
@ -638,6 +640,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
self
|
self
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self {
|
pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self {
|
||||||
let before = self.span.clone();
|
let before = self.span.clone();
|
||||||
self.span(after);
|
self.span(after);
|
||||||
|
@ -653,6 +656,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn note_expected_found(
|
pub fn note_expected_found(
|
||||||
&mut self,
|
&mut self,
|
||||||
expected_label: &dyn fmt::Display,
|
expected_label: &dyn fmt::Display,
|
||||||
|
@ -663,6 +667,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
self.note_expected_found_extra(expected_label, expected, found_label, found, &"", &"")
|
self.note_expected_found_extra(expected_label, expected, found_label, found, &"", &"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn note_expected_found_extra(
|
pub fn note_expected_found_extra(
|
||||||
&mut self,
|
&mut self,
|
||||||
expected_label: &dyn fmt::Display,
|
expected_label: &dyn fmt::Display,
|
||||||
|
@ -705,6 +710,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn note_trait_signature(&mut self, name: Symbol, signature: String) -> &mut Self {
|
pub fn note_trait_signature(&mut self, name: Symbol, signature: String) -> &mut Self {
|
||||||
self.highlighted_note(vec![
|
self.highlighted_note(vec![
|
||||||
StringPart::normal(format!("`{name}` from trait: `")),
|
StringPart::normal(format!("`{name}` from trait: `")),
|
||||||
|
@ -722,12 +728,14 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
self
|
self
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
|
fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
|
||||||
self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
|
self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is like [`Diag::note()`], but it's only printed once.
|
/// This is like [`Diag::note()`], but it's only printed once.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn note_once(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
|
pub fn note_once(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
|
||||||
self.sub(Level::OnceNote, msg, MultiSpan::new());
|
self.sub(Level::OnceNote, msg, MultiSpan::new());
|
||||||
self
|
self
|
||||||
|
@ -748,6 +756,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
|
|
||||||
/// Prints the span with a note above it.
|
/// Prints the span with a note above it.
|
||||||
/// This is like [`Diag::note_once()`], but it gets its own span.
|
/// This is like [`Diag::note_once()`], but it gets its own span.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_note_once<S: Into<MultiSpan>>(
|
pub fn span_note_once<S: Into<MultiSpan>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: S,
|
sp: S,
|
||||||
|
@ -786,12 +795,14 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/// This is like [`Diag::help()`], but it's only printed once.
|
/// This is like [`Diag::help()`], but it's only printed once.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn help_once(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
|
pub fn help_once(&mut self, msg: impl Into<SubdiagMessage>) -> &mut Self {
|
||||||
self.sub(Level::OnceHelp, msg, MultiSpan::new());
|
self.sub(Level::OnceHelp, msg, MultiSpan::new());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a help message attached to this diagnostic with a customizable highlighted message.
|
/// Add a help message attached to this diagnostic with a customizable highlighted message.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn highlighted_help(&mut self, msg: Vec<StringPart>) -> &mut Self {
|
pub fn highlighted_help(&mut self, msg: Vec<StringPart>) -> &mut Self {
|
||||||
self.sub_with_highlights(Level::Help, msg, MultiSpan::new());
|
self.sub_with_highlights(Level::Help, msg, MultiSpan::new());
|
||||||
self
|
self
|
||||||
|
@ -812,12 +823,14 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
/// Disallow attaching suggestions this diagnostic.
|
/// Disallow attaching suggestions this diagnostic.
|
||||||
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
|
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
|
||||||
/// (before and after the call to `disable_suggestions`) will be ignored.
|
/// (before and after the call to `disable_suggestions`) will be ignored.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn disable_suggestions(&mut self) -> &mut Self {
|
pub fn disable_suggestions(&mut self) -> &mut Self {
|
||||||
self.suggestions = Err(SuggestionsDisabled);
|
self.suggestions = Err(SuggestionsDisabled);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper for pushing to `self.suggestions`, if available (not disable).
|
/// Helper for pushing to `self.suggestions`, if available (not disable).
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
|
fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
|
||||||
for subst in &suggestion.substitutions {
|
for subst in &suggestion.substitutions {
|
||||||
for part in &subst.parts {
|
for part in &subst.parts {
|
||||||
|
@ -838,6 +851,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
with_fn! { with_multipart_suggestion,
|
with_fn! { with_multipart_suggestion,
|
||||||
/// Show a suggestion that has multiple parts to it.
|
/// Show a suggestion that has multiple parts to it.
|
||||||
/// In other words, multiple changes need to be applied as part of this suggestion.
|
/// In other words, multiple changes need to be applied as part of this suggestion.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn multipart_suggestion(
|
pub fn multipart_suggestion(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: impl Into<SubdiagMessage>,
|
msg: impl Into<SubdiagMessage>,
|
||||||
|
@ -854,6 +868,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
|
|
||||||
/// Show a suggestion that has multiple parts to it, always as it's own subdiagnostic.
|
/// Show a suggestion that has multiple parts to it, always as it's own subdiagnostic.
|
||||||
/// In other words, multiple changes need to be applied as part of this suggestion.
|
/// In other words, multiple changes need to be applied as part of this suggestion.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn multipart_suggestion_verbose(
|
pub fn multipart_suggestion_verbose(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: impl Into<SubdiagMessage>,
|
msg: impl Into<SubdiagMessage>,
|
||||||
|
@ -869,6 +884,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`Diag::multipart_suggestion()`] but you can set the [`SuggestionStyle`].
|
/// [`Diag::multipart_suggestion()`] but you can set the [`SuggestionStyle`].
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn multipart_suggestion_with_style(
|
pub fn multipart_suggestion_with_style(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: impl Into<SubdiagMessage>,
|
msg: impl Into<SubdiagMessage>,
|
||||||
|
@ -911,6 +927,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
/// be from the message, showing the span label inline would be visually unpleasant
|
/// be from the message, showing the span label inline would be visually unpleasant
|
||||||
/// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't
|
/// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't
|
||||||
/// improve understandability.
|
/// improve understandability.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn tool_only_multipart_suggestion(
|
pub fn tool_only_multipart_suggestion(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: impl Into<SubdiagMessage>,
|
msg: impl Into<SubdiagMessage>,
|
||||||
|
@ -943,6 +960,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
/// * may contain a name of a function, variable, or type, but not whole expressions
|
/// * may contain a name of a function, variable, or type, but not whole expressions
|
||||||
///
|
///
|
||||||
/// See `CodeSuggestion` for more information.
|
/// See `CodeSuggestion` for more information.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_suggestion(
|
pub fn span_suggestion(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -961,6 +979,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
} }
|
} }
|
||||||
|
|
||||||
/// [`Diag::span_suggestion()`] but you can set the [`SuggestionStyle`].
|
/// [`Diag::span_suggestion()`] but you can set the [`SuggestionStyle`].
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_suggestion_with_style(
|
pub fn span_suggestion_with_style(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -986,6 +1005,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
|
|
||||||
with_fn! { with_span_suggestion_verbose,
|
with_fn! { with_span_suggestion_verbose,
|
||||||
/// Always show the suggested change.
|
/// Always show the suggested change.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_suggestion_verbose(
|
pub fn span_suggestion_verbose(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -1006,6 +1026,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
with_fn! { with_span_suggestions,
|
with_fn! { with_span_suggestions,
|
||||||
/// Prints out a message with multiple suggested edits of the code.
|
/// Prints out a message with multiple suggested edits of the code.
|
||||||
/// See also [`Diag::span_suggestion()`].
|
/// See also [`Diag::span_suggestion()`].
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_suggestions(
|
pub fn span_suggestions(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -1022,6 +1043,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
)
|
)
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_suggestions_with_style(
|
pub fn span_suggestions_with_style(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -1052,6 +1074,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
/// Prints out a message with multiple suggested edits of the code, where each edit consists of
|
/// Prints out a message with multiple suggested edits of the code, where each edit consists of
|
||||||
/// multiple parts.
|
/// multiple parts.
|
||||||
/// See also [`Diag::multipart_suggestion()`].
|
/// See also [`Diag::multipart_suggestion()`].
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn multipart_suggestions(
|
pub fn multipart_suggestions(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: impl Into<SubdiagMessage>,
|
msg: impl Into<SubdiagMessage>,
|
||||||
|
@ -1098,6 +1121,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
/// inline, it will only show the message and not the suggestion.
|
/// inline, it will only show the message and not the suggestion.
|
||||||
///
|
///
|
||||||
/// See `CodeSuggestion` for more information.
|
/// See `CodeSuggestion` for more information.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_suggestion_short(
|
pub fn span_suggestion_short(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -1121,6 +1145,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
/// be from the message, showing the span label inline would be visually unpleasant
|
/// be from the message, showing the span label inline would be visually unpleasant
|
||||||
/// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't
|
/// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't
|
||||||
/// improve understandability.
|
/// improve understandability.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span_suggestion_hidden(
|
pub fn span_suggestion_hidden(
|
||||||
&mut self,
|
&mut self,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -1165,6 +1190,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
/// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages
|
/// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages
|
||||||
/// used in the subdiagnostic, so suitable for use with repeated messages (i.e. re-use of
|
/// used in the subdiagnostic, so suitable for use with repeated messages (i.e. re-use of
|
||||||
/// interpolated variables).
|
/// interpolated variables).
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn subdiagnostic(
|
pub fn subdiagnostic(
|
||||||
&mut self,
|
&mut self,
|
||||||
dcx: &crate::DiagCtxt,
|
dcx: &crate::DiagCtxt,
|
||||||
|
@ -1180,6 +1206,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
|
|
||||||
with_fn! { with_span,
|
with_fn! { with_span,
|
||||||
/// Add a span.
|
/// Add a span.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self {
|
pub fn span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self {
|
||||||
self.span = sp.into();
|
self.span = sp.into();
|
||||||
if let Some(span) = self.span.primary_span() {
|
if let Some(span) = self.span.primary_span() {
|
||||||
|
@ -1188,6 +1215,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
self
|
self
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn is_lint(&mut self, name: String, has_future_breakage: bool) -> &mut Self {
|
pub fn is_lint(&mut self, name: String, has_future_breakage: bool) -> &mut Self {
|
||||||
self.is_lint = Some(IsLint { name, has_future_breakage });
|
self.is_lint = Some(IsLint { name, has_future_breakage });
|
||||||
self
|
self
|
||||||
|
@ -1195,6 +1223,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
|
|
||||||
with_fn! { with_code,
|
with_fn! { with_code,
|
||||||
/// Add an error code.
|
/// Add an error code.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn code(&mut self, code: ErrCode) -> &mut Self {
|
pub fn code(&mut self, code: ErrCode) -> &mut Self {
|
||||||
self.code = Some(code);
|
self.code = Some(code);
|
||||||
self
|
self
|
||||||
|
@ -1202,6 +1231,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
|
|
||||||
with_fn! { with_primary_message,
|
with_fn! { with_primary_message,
|
||||||
/// Add a primary message.
|
/// Add a primary message.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn primary_message(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
|
pub fn primary_message(&mut self, msg: impl Into<DiagMessage>) -> &mut Self {
|
||||||
self.messages[0] = (msg.into(), Style::NoStyle);
|
self.messages[0] = (msg.into(), Style::NoStyle);
|
||||||
self
|
self
|
||||||
|
@ -1209,6 +1239,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
||||||
|
|
||||||
with_fn! { with_arg,
|
with_fn! { with_arg,
|
||||||
/// Add an argument.
|
/// Add an argument.
|
||||||
|
#[rustc_lint_diagnostics]
|
||||||
pub fn arg(
|
pub fn arg(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: impl Into<DiagArgName>,
|
name: impl Into<DiagArgName>,
|
||||||
|
|
|
@ -1101,32 +1101,36 @@ impl DiagCtxt {
|
||||||
// Functions beginning with `struct_`/`create_` create a diagnostic. Other
|
// Functions beginning with `struct_`/`create_` create a diagnostic. Other
|
||||||
// functions create and emit a diagnostic all in one go.
|
// functions create and emit a diagnostic all in one go.
|
||||||
impl DiagCtxt {
|
impl DiagCtxt {
|
||||||
// No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing.
|
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
|
||||||
|
// user-facing.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn struct_bug(&self, msg: impl Into<DiagMessage>) -> Diag<'_, BugAbort> {
|
pub fn struct_bug(&self, msg: impl Into<Cow<'static, str>>) -> Diag<'_, BugAbort> {
|
||||||
Diag::new(self, Bug, msg)
|
Diag::new(self, Bug, msg.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing.
|
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
|
||||||
|
// user-facing.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn bug(&self, msg: impl Into<DiagMessage>) -> ! {
|
pub fn bug(&self, msg: impl Into<Cow<'static, str>>) -> ! {
|
||||||
self.struct_bug(msg).emit()
|
self.struct_bug(msg).emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
// No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing.
|
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
|
||||||
|
// user-facing.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn struct_span_bug(
|
pub fn struct_span_bug(
|
||||||
&self,
|
&self,
|
||||||
span: impl Into<MultiSpan>,
|
span: impl Into<MultiSpan>,
|
||||||
msg: impl Into<DiagMessage>,
|
msg: impl Into<Cow<'static, str>>,
|
||||||
) -> Diag<'_, BugAbort> {
|
) -> Diag<'_, BugAbort> {
|
||||||
self.struct_bug(msg).with_span(span)
|
self.struct_bug(msg).with_span(span)
|
||||||
}
|
}
|
||||||
|
|
||||||
// No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing.
|
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
|
||||||
|
// user-facing.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) -> ! {
|
pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<Cow<'static, str>>) -> ! {
|
||||||
self.struct_span_bug(span, msg).emit()
|
self.struct_span_bug(span, msg.into()).emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
@ -1240,24 +1244,28 @@ impl DiagCtxt {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that an error is printed. See `Level::DelayedBug`.
|
/// Ensures that an error is printed. See `Level::DelayedBug`.
|
||||||
// No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing.
|
//
|
||||||
|
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
|
||||||
|
// user-facing.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn delayed_bug(&self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
|
pub fn delayed_bug(&self, msg: impl Into<Cow<'static, str>>) -> ErrorGuaranteed {
|
||||||
Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg).emit()
|
Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that an error is printed. See `Level::DelayedBug`.
|
/// Ensures that an error is printed. See `Level::DelayedBug`.
|
||||||
///
|
///
|
||||||
/// Note: this function used to be called `delay_span_bug`. It was renamed
|
/// Note: this function used to be called `delay_span_bug`. It was renamed
|
||||||
/// to match similar functions like `span_err`, `span_warn`, etc.
|
/// to match similar functions like `span_err`, `span_warn`, etc.
|
||||||
// No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing.
|
//
|
||||||
|
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
|
||||||
|
// user-facing.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn span_delayed_bug(
|
pub fn span_delayed_bug(
|
||||||
&self,
|
&self,
|
||||||
sp: impl Into<MultiSpan>,
|
sp: impl Into<MultiSpan>,
|
||||||
msg: impl Into<DiagMessage>,
|
msg: impl Into<Cow<'static, str>>,
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg).with_span(sp).emit()
|
Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).with_span(sp).emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_lint_diagnostics]
|
#[rustc_lint_diagnostics]
|
||||||
|
|
|
@ -1493,6 +1493,8 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) -> bool {
|
||||||
};
|
};
|
||||||
|
|
||||||
if crate_matches {
|
if crate_matches {
|
||||||
|
// FIXME: make this translatable
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)]
|
||||||
sess.psess.buffer_lint_with_diagnostic(
|
sess.psess.buffer_lint_with_diagnostic(
|
||||||
PROC_MACRO_BACK_COMPAT,
|
PROC_MACRO_BACK_COMPAT,
|
||||||
item.ident.span,
|
item.ident.span,
|
||||||
|
|
|
@ -239,6 +239,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||||
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
|
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
|
||||||
/// is in the original source file. Gives a compiler error if the syntax of
|
/// is in the original source file. Gives a compiler error if the syntax of
|
||||||
/// the attribute is incorrect.
|
/// the attribute is incorrect.
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec<Attribute> {
|
pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec<Attribute> {
|
||||||
let Some((cfg_predicate, expanded_attrs)) =
|
let Some((cfg_predicate, expanded_attrs)) =
|
||||||
rustc_parse::parse_cfg_attr(attr, &self.sess.psess)
|
rustc_parse::parse_cfg_attr(attr, &self.sess.psess)
|
||||||
|
@ -273,6 +274,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn expand_cfg_attr_item(
|
fn expand_cfg_attr_item(
|
||||||
&self,
|
&self,
|
||||||
attr: &Attribute,
|
attr: &Attribute,
|
||||||
|
@ -371,6 +373,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If attributes are not allowed on expressions, emit an error for `attr`
|
/// If attributes are not allowed on expressions, emit an error for `attr`
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
|
pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
|
||||||
if self.features.is_some_and(|features| !features.stmt_expr_attributes)
|
if self.features.is_some_and(|features| !features.stmt_expr_attributes)
|
||||||
|
@ -384,7 +387,6 @@ impl<'a> StripUnconfigured<'a> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if attr.is_doc_comment() {
|
if attr.is_doc_comment() {
|
||||||
#[allow(rustc::untranslatable_diagnostic)]
|
|
||||||
err.help("`///` is for documentation comments. For a plain comment, use `//`.");
|
err.help("`///` is for documentation comments. For a plain comment, use `//`.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -783,6 +783,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
|
fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
|
||||||
let kind = match item {
|
let kind = match item {
|
||||||
Annotatable::Item(_)
|
Annotatable::Item(_)
|
||||||
|
@ -825,6 +826,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
|
impl<'ast, 'a> Visitor<'ast> for GateProcMacroInput<'a> {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn visit_item(&mut self, item: &'ast ast::Item) {
|
fn visit_item(&mut self, item: &'ast ast::Item) {
|
||||||
match &item.kind {
|
match &item.kind {
|
||||||
ItemKind::Mod(_, mod_kind)
|
ItemKind::Mod(_, mod_kind)
|
||||||
|
@ -1689,6 +1691,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
|
|
||||||
// Detect use of feature-gated or invalid attributes on macro invocations
|
// Detect use of feature-gated or invalid attributes on macro invocations
|
||||||
// since they will not be detected after macro expansion.
|
// since they will not be detected after macro expansion.
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
|
fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
|
||||||
let features = self.cx.ecfg.features;
|
let features = self.cx.ecfg.features;
|
||||||
let mut attrs = attrs.iter().peekable();
|
let mut attrs = attrs.iter().peekable();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
|
#![feature(lint_reasons)]
|
||||||
#![feature(macro_metavar_expr)]
|
#![feature(macro_metavar_expr)]
|
||||||
#![feature(map_try_insert)]
|
#![feature(map_try_insert)]
|
||||||
#![feature(proc_macro_diagnostic)]
|
#![feature(proc_macro_diagnostic)]
|
||||||
|
|
|
@ -517,6 +517,9 @@ impl server::FreeFunctions for Rustc<'_, '_> {
|
||||||
Diag::new(&self.psess().dcx, diagnostic.level.to_internal(), message);
|
Diag::new(&self.psess().dcx, diagnostic.level.to_internal(), message);
|
||||||
diag.span(MultiSpan::from_spans(diagnostic.spans));
|
diag.span(MultiSpan::from_spans(diagnostic.spans));
|
||||||
for child in diagnostic.children {
|
for child in diagnostic.children {
|
||||||
|
// This message comes from another diagnostic, and we are just reconstructing the
|
||||||
|
// diagnostic, so there's no need for translation.
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)]
|
||||||
diag.sub(child.level.to_internal(), child.message, MultiSpan::from_spans(child.spans));
|
diag.sub(child.level.to_internal(), child.message, MultiSpan::from_spans(child.spans));
|
||||||
}
|
}
|
||||||
diag.emit();
|
diag.emit();
|
||||||
|
|
|
@ -178,6 +178,7 @@ impl<T: Write> Write for Shared<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // no translation needed for tests
|
||||||
fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) {
|
fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) {
|
||||||
create_default_session_globals_then(|| {
|
create_default_session_globals_then(|| {
|
||||||
let (handler, source_map, output) = create_test_handler();
|
let (handler, source_map, output) = create_test_handler();
|
||||||
|
@ -192,7 +193,6 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
|
||||||
println!("text: {:?}", source_map.span_to_snippet(span));
|
println!("text: {:?}", source_map.span_to_snippet(span));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(rustc::untranslatable_diagnostic)]
|
|
||||||
handler.span_err(msp, "foo");
|
handler.span_err(msp, "foo");
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
|
|
|
@ -695,8 +695,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||||
// Used by the `rustc::potential_query_instability` lint to warn methods which
|
// Used by the `rustc::potential_query_instability` lint to warn methods which
|
||||||
// might not be stable during incremental compilation.
|
// might not be stable during incremental compilation.
|
||||||
rustc_attr!(rustc_lint_query_instability, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
|
rustc_attr!(rustc_lint_query_instability, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
|
||||||
// Used by the `rustc::untranslatable_diagnostic` and `rustc::diagnostic_outside_of_impl` lints
|
// Used by the `rustc::diagnostic_outside_of_impl` lints to assist in changes to diagnostic
|
||||||
// to assist in changes to diagnostic APIs.
|
// APIs. Any function with this attribute will be checked by that lint.
|
||||||
rustc_attr!(rustc_lint_diagnostics, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
|
rustc_attr!(rustc_lint_diagnostics, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
|
||||||
// Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions`
|
// Used by the `rustc::bad_opt_access` lint to identify `DebuggingOptions` and `CodegenOptions`
|
||||||
// types (as well as any others in future).
|
// types (as well as any others in future).
|
||||||
|
|
|
@ -320,6 +320,7 @@ pub struct Config {
|
||||||
|
|
||||||
// JUSTIFICATION: before session exists, only config
|
// JUSTIFICATION: before session exists, only config
|
||||||
#[allow(rustc::bad_opt_access)]
|
#[allow(rustc::bad_opt_access)]
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
|
pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R {
|
||||||
trace!("run_compiler");
|
trace!("run_compiler");
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBackendFn {
|
fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBackendFn {
|
||||||
match unsafe { load_symbol_from_dylib::<MakeBackendFn>(path, "__rustc_codegen_backend") } {
|
match unsafe { load_symbol_from_dylib::<MakeBackendFn>(path, "__rustc_codegen_backend") } {
|
||||||
Ok(backend_sym) => backend_sym,
|
Ok(backend_sym) => backend_sym,
|
||||||
|
@ -227,6 +228,7 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn get_codegen_sysroot(
|
fn get_codegen_sysroot(
|
||||||
early_dcx: &EarlyDiagCtxt,
|
early_dcx: &EarlyDiagCtxt,
|
||||||
maybe_sysroot: &Option<PathBuf>,
|
maybe_sysroot: &Option<PathBuf>,
|
||||||
|
@ -319,6 +321,7 @@ fn get_codegen_sysroot(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
pub(crate) fn check_attr_crate_type(
|
pub(crate) fn check_attr_crate_type(
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
attrs: &[ast::Attribute],
|
attrs: &[ast::Attribute],
|
||||||
|
|
|
@ -621,12 +621,13 @@ pub trait LintContext {
|
||||||
/// Note that this function should only be called for [`LintExpectationId`]s
|
/// Note that this function should only be called for [`LintExpectationId`]s
|
||||||
/// retrieved from the current lint pass. Buffered or manually created ids can
|
/// retrieved from the current lint pass. Buffered or manually created ids can
|
||||||
/// cause ICEs.
|
/// cause ICEs.
|
||||||
#[rustc_lint_diagnostics]
|
|
||||||
fn fulfill_expectation(&self, expectation: LintExpectationId) {
|
fn fulfill_expectation(&self, expectation: LintExpectationId) {
|
||||||
// We need to make sure that submitted expectation ids are correctly fulfilled suppressed
|
// We need to make sure that submitted expectation ids are correctly fulfilled suppressed
|
||||||
// and stored between compilation sessions. To not manually do these steps, we simply create
|
// and stored between compilation sessions. To not manually do these steps, we simply create
|
||||||
// a dummy diagnostic and emit is as usual, which will be suppressed and stored like a normal
|
// a dummy diagnostic and emit it as usual, which will be suppressed and stored like a
|
||||||
// expected lint diagnostic.
|
// normal expected lint diagnostic.
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)]
|
||||||
self.sess()
|
self.sess()
|
||||||
.dcx()
|
.dcx()
|
||||||
.struct_expect(
|
.struct_expect(
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_ast as ast;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::{def_id::DefId, Expr, ExprKind, GenericArg, PatKind, Path, PathSegment, QPath};
|
use rustc_hir::{def_id::DefId, Expr, ExprKind, GenericArg, PatKind, Path, PathSegment, QPath};
|
||||||
use rustc_hir::{BinOp, BinOpKind, HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind};
|
use rustc_hir::{BinOp, BinOpKind, HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind};
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty::{self, Ty as MiddleTy};
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||||
use rustc_span::symbol::{kw, sym, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
|
@ -338,10 +338,11 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_tool_lint! {
|
declare_tool_lint! {
|
||||||
/// The `untranslatable_diagnostic` lint detects diagnostics created
|
/// The `untranslatable_diagnostic` lint detects messages passed to functions with `impl
|
||||||
/// without using translatable Fluent strings.
|
/// Into<{D,Subd}iagMessage` parameters without using translatable Fluent strings.
|
||||||
///
|
///
|
||||||
/// More details on translatable diagnostics can be found [here](https://rustc-dev-guide.rust-lang.org/diagnostics/translation.html).
|
/// More details on translatable diagnostics can be found
|
||||||
|
/// [here](https://rustc-dev-guide.rust-lang.org/diagnostics/translation.html).
|
||||||
pub rustc::UNTRANSLATABLE_DIAGNOSTIC,
|
pub rustc::UNTRANSLATABLE_DIAGNOSTIC,
|
||||||
Deny,
|
Deny,
|
||||||
"prevent creation of diagnostics which cannot be translated",
|
"prevent creation of diagnostics which cannot be translated",
|
||||||
|
@ -349,11 +350,13 @@ declare_tool_lint! {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_tool_lint! {
|
declare_tool_lint! {
|
||||||
/// The `diagnostic_outside_of_impl` lint detects diagnostics created manually,
|
/// The `diagnostic_outside_of_impl` lint detects calls to functions annotated with
|
||||||
/// and inside an `IntoDiagnostic`/`AddToDiagnostic` implementation,
|
/// `#[rustc_lint_diagnostics]` that are outside an `IntoDiagnostic`, `AddToDiagnostic`, or
|
||||||
/// or a `#[derive(Diagnostic)]`/`#[derive(Subdiagnostic)]` expansion.
|
/// `DecorateLint` impl, or a `#[derive(Diagnostic)]`, `#[derive(Subdiagnostic)]`,
|
||||||
|
/// `#[derive(DecorateLint)]` expansion.
|
||||||
///
|
///
|
||||||
/// More details on diagnostics implementations can be found [here](https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html).
|
/// More details on diagnostics implementations can be found
|
||||||
|
/// [here](https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html).
|
||||||
pub rustc::DIAGNOSTIC_OUTSIDE_OF_IMPL,
|
pub rustc::DIAGNOSTIC_OUTSIDE_OF_IMPL,
|
||||||
Deny,
|
Deny,
|
||||||
"prevent creation of diagnostics outside of `IntoDiagnostic`/`AddToDiagnostic` impls",
|
"prevent creation of diagnostics outside of `IntoDiagnostic`/`AddToDiagnostic` impls",
|
||||||
|
@ -364,54 +367,130 @@ declare_lint_pass!(Diagnostics => [UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE
|
||||||
|
|
||||||
impl LateLintPass<'_> for Diagnostics {
|
impl LateLintPass<'_> for Diagnostics {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
let Some((span, def_id, args)) = typeck_results_of_method_fn(cx, expr) else { return };
|
// Only check function calls and method calls.
|
||||||
debug!(?span, ?def_id, ?args);
|
let (span, def_id, fn_gen_args, call_tys) = match expr.kind {
|
||||||
let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, args)
|
ExprKind::Call(callee, args) => {
|
||||||
|
match cx.typeck_results().node_type(callee.hir_id).kind() {
|
||||||
|
&ty::FnDef(def_id, fn_gen_args) => {
|
||||||
|
let call_tys: Vec<_> =
|
||||||
|
args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect();
|
||||||
|
(callee.span, def_id, fn_gen_args, call_tys)
|
||||||
|
}
|
||||||
|
_ => return, // occurs for fns passed as args
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExprKind::MethodCall(segment, _recv, args, _span) => {
|
||||||
|
let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
|
||||||
|
let fn_gen_args = cx.typeck_results().node_args(expr.hir_id);
|
||||||
|
let mut call_tys: Vec<_> =
|
||||||
|
args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect();
|
||||||
|
call_tys.insert(0, cx.tcx.types.self_param); // dummy inserted for `self`
|
||||||
|
(segment.ident.span, def_id, fn_gen_args, call_tys)
|
||||||
|
}
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Is the callee marked with `#[rustc_lint_diagnostics]`?
|
||||||
|
let has_attr = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, fn_gen_args)
|
||||||
.ok()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.is_some_and(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics));
|
.is_some_and(|inst| cx.tcx.has_attr(inst.def_id(), sym::rustc_lint_diagnostics));
|
||||||
if !has_attr {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut found_parent_with_attr = false;
|
// Closure: is the type `{D,Subd}iagMessage`?
|
||||||
let mut found_impl = false;
|
let is_diag_message = |ty: MiddleTy<'_>| {
|
||||||
for (hir_id, parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
|
|
||||||
if let Some(owner_did) = hir_id.as_owner() {
|
|
||||||
found_parent_with_attr = found_parent_with_attr
|
|
||||||
|| cx.tcx.has_attr(owner_did, sym::rustc_lint_diagnostics);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!(?parent);
|
|
||||||
if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent
|
|
||||||
&& let Impl { of_trait: Some(of_trait), .. } = impl_
|
|
||||||
&& let Some(def_id) = of_trait.trait_def_id()
|
|
||||||
&& let Some(name) = cx.tcx.get_diagnostic_name(def_id)
|
|
||||||
&& matches!(name, sym::IntoDiagnostic | sym::AddToDiagnostic | sym::DecorateLint)
|
|
||||||
{
|
|
||||||
found_impl = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug!(?found_impl);
|
|
||||||
if !found_parent_with_attr && !found_impl {
|
|
||||||
cx.emit_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut found_diagnostic_message = false;
|
|
||||||
for ty in args.types() {
|
|
||||||
debug!(?ty);
|
|
||||||
if let Some(adt_def) = ty.ty_adt_def()
|
if let Some(adt_def) = ty.ty_adt_def()
|
||||||
&& let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did())
|
&& let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did())
|
||||||
&& matches!(name, sym::DiagMessage | sym::SubdiagMessage)
|
&& matches!(name, sym::DiagMessage | sym::SubdiagMessage)
|
||||||
{
|
{
|
||||||
found_diagnostic_message = true;
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Does the callee have a `impl Into<{D,Subd}iagMessage>` parameter? (There should be at
|
||||||
|
// most one.)
|
||||||
|
let mut impl_into_diagnostic_message_param = None;
|
||||||
|
let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
|
||||||
|
let predicates = cx.tcx.predicates_of(def_id).instantiate_identity(cx.tcx).predicates;
|
||||||
|
for (i, ¶m_ty) in fn_sig.inputs().iter().enumerate() {
|
||||||
|
if let ty::Param(p) = param_ty.kind() {
|
||||||
|
// It is a type parameter. Check if it is `impl Into<{D,Subd}iagMessage>`.
|
||||||
|
for pred in predicates.iter() {
|
||||||
|
if let Some(trait_pred) = pred.as_trait_clause()
|
||||||
|
&& let trait_ref = trait_pred.skip_binder().trait_ref
|
||||||
|
&& trait_ref.self_ty() == param_ty // correct predicate for the param?
|
||||||
|
&& cx.tcx.is_diagnostic_item(sym::Into, trait_ref.def_id)
|
||||||
|
&& let ty1 = trait_ref.args.type_at(1)
|
||||||
|
&& is_diag_message(ty1)
|
||||||
|
{
|
||||||
|
if impl_into_diagnostic_message_param.is_some() {
|
||||||
|
cx.tcx.dcx().span_bug(
|
||||||
|
span,
|
||||||
|
"can't handle multiple `impl Into<{D,Sub}iagMessage>` params",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
impl_into_diagnostic_message_param = Some((i, p.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the callee interesting?
|
||||||
|
if !has_attr && impl_into_diagnostic_message_param.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the parent method marked with `#[rustc_lint_diagnostics]`?
|
||||||
|
let mut parent_has_attr = false;
|
||||||
|
for (hir_id, _parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
|
||||||
|
if let Some(owner_did) = hir_id.as_owner()
|
||||||
|
&& cx.tcx.has_attr(owner_did, sym::rustc_lint_diagnostics)
|
||||||
|
{
|
||||||
|
parent_has_attr = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug!(?found_diagnostic_message);
|
|
||||||
if !found_parent_with_attr && !found_diagnostic_message {
|
// Calls to `#[rustc_lint_diagnostics]`-marked functions should only occur:
|
||||||
cx.emit_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, UntranslatableDiag);
|
// - inside an impl of `IntoDiagnostic`, `AddToDiagnostic`, or `DecorateLint`, or
|
||||||
|
// - inside a parent function that is itself marked with `#[rustc_lint_diagnostics]`.
|
||||||
|
//
|
||||||
|
// Otherwise, emit a `DIAGNOSTIC_OUTSIDE_OF_IMPL` lint.
|
||||||
|
if has_attr && !parent_has_attr {
|
||||||
|
let mut is_inside_appropriate_impl = false;
|
||||||
|
for (_hir_id, parent) in cx.tcx.hir().parent_iter(expr.hir_id) {
|
||||||
|
debug!(?parent);
|
||||||
|
if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent
|
||||||
|
&& let Impl { of_trait: Some(of_trait), .. } = impl_
|
||||||
|
&& let Some(def_id) = of_trait.trait_def_id()
|
||||||
|
&& let Some(name) = cx.tcx.get_diagnostic_name(def_id)
|
||||||
|
&& matches!(
|
||||||
|
name,
|
||||||
|
sym::IntoDiagnostic | sym::AddToDiagnostic | sym::DecorateLint
|
||||||
|
)
|
||||||
|
{
|
||||||
|
is_inside_appropriate_impl = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug!(?is_inside_appropriate_impl);
|
||||||
|
if !is_inside_appropriate_impl {
|
||||||
|
cx.emit_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, DiagOutOfImpl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
|
||||||
|
// with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
|
||||||
|
// `UNTRANSLATABLE_DIAGNOSTIC` lint.
|
||||||
|
if let Some((param_i, param_i_p_name)) = impl_into_diagnostic_message_param {
|
||||||
|
// Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
|
||||||
|
let arg_ty = call_tys[param_i];
|
||||||
|
let is_translatable = is_diag_message(arg_ty)
|
||||||
|
|| matches!(arg_ty.kind(), ty::Param(p) if p.name == param_i_p_name);
|
||||||
|
if !is_translatable {
|
||||||
|
cx.emit_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, UntranslatableDiag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,7 +504,7 @@ declare_tool_lint! {
|
||||||
report_in_external_macro: true
|
report_in_external_macro: true
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint_pass!(BadOptAccess => [ BAD_OPT_ACCESS ]);
|
declare_lint_pass!(BadOptAccess => [BAD_OPT_ACCESS]);
|
||||||
|
|
||||||
impl LateLintPass<'_> for BadOptAccess {
|
impl LateLintPass<'_> for BadOptAccess {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
|
|
|
@ -104,6 +104,7 @@ const SYNC_GUARD_SYMBOLS: [Symbol; 3] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
|
fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
|
||||||
if matches!(local.source, rustc_hir::LocalSource::AsyncFn) {
|
if matches!(local.source, rustc_hir::LocalSource::AsyncFn) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -724,6 +724,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id: Option<HirId>) {
|
fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id: Option<HirId>) {
|
||||||
let sess = self.sess;
|
let sess = self.sess;
|
||||||
for (attr_index, attr) in attrs.iter().enumerate() {
|
for (attr_index, attr) in attrs.iter().enumerate() {
|
||||||
|
|
|
@ -947,6 +947,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn report_unused_deps(&mut self, krate: &ast::Crate) {
|
fn report_unused_deps(&mut self, krate: &ast::Crate) {
|
||||||
// Make a point span rather than covering the whole file
|
// Make a point span rather than covering the whole file
|
||||||
let span = krate.spans.inner_span.shrink_to_lo();
|
let span = krate.spans.inner_span.shrink_to_lo();
|
||||||
|
|
|
@ -93,6 +93,7 @@ struct Collector<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Collector<'tcx> {
|
impl<'tcx> Collector<'tcx> {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn process_module(&mut self, module: &ForeignModule) {
|
fn process_module(&mut self, module: &ForeignModule) {
|
||||||
let ForeignModule { def_id, abi, ref foreign_items } = *module;
|
let ForeignModule { def_id, abi, ref foreign_items } = *module;
|
||||||
let def_id = def_id.expect_local();
|
let def_id = def_id.expect_local();
|
||||||
|
|
|
@ -17,6 +17,7 @@ use rustc_target::abi::call::FnAbi;
|
||||||
use rustc_target::abi::*;
|
use rustc_target::abi::*;
|
||||||
use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Target};
|
use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Target};
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::num::NonZero;
|
use std::num::NonZero;
|
||||||
|
@ -268,7 +269,7 @@ pub struct LayoutCx<'tcx, C> {
|
||||||
impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
|
impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||||
type TargetDataLayoutRef = &'tcx TargetDataLayout;
|
type TargetDataLayoutRef = &'tcx TargetDataLayout;
|
||||||
|
|
||||||
fn delayed_bug(&self, txt: String) {
|
fn delayed_bug(&self, txt: impl Into<Cow<'static, str>>) {
|
||||||
self.tcx.dcx().delayed_bug(txt);
|
self.tcx.dcx().delayed_bug(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
||||||
use crate::ty::{List, ParamEnv};
|
use crate::ty::{List, ParamEnv};
|
||||||
use hir::def::DefKind;
|
use hir::def::DefKind;
|
||||||
use rustc_data_structures::captures::Captures;
|
use rustc_data_structures::captures::Captures;
|
||||||
use rustc_errors::{DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan};
|
use rustc_errors::{DiagArgValue, ErrorGuaranteed, IntoDiagnosticArg, MultiSpan};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::LangItem;
|
use rustc_hir::LangItem;
|
||||||
|
@ -1543,7 +1543,7 @@ impl<'tcx> Ty<'tcx> {
|
||||||
pub fn new_error_with_message<S: Into<MultiSpan>>(
|
pub fn new_error_with_message<S: Into<MultiSpan>>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
span: S,
|
span: S,
|
||||||
msg: impl Into<DiagMessage>,
|
msg: impl Into<Cow<'static, str>>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let reported = tcx.dcx().span_delayed_bug(span, msg);
|
let reported = tcx.dcx().span_delayed_bug(span, msg);
|
||||||
Ty::new(tcx, Error(reported))
|
Ty::new(tcx, Error(reported))
|
||||||
|
|
|
@ -1074,6 +1074,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
/// of one item. Read the documentation of [`check_doc_inline`] for more information.
|
/// of one item. Read the documentation of [`check_doc_inline`] for more information.
|
||||||
///
|
///
|
||||||
/// [`check_doc_inline`]: Self::check_doc_inline
|
/// [`check_doc_inline`]: Self::check_doc_inline
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn check_doc_attrs(
|
fn check_doc_attrs(
|
||||||
&self,
|
&self,
|
||||||
attr: &Attribute,
|
attr: &Attribute,
|
||||||
|
@ -1756,6 +1757,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the `#[repr]` attributes on `item` are valid.
|
/// Checks if the `#[repr]` attributes on `item` are valid.
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn check_repr(
|
fn check_repr(
|
||||||
&self,
|
&self,
|
||||||
attrs: &[Attribute],
|
attrs: &[Attribute],
|
||||||
|
@ -2328,6 +2330,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||||
|
|
||||||
let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id);
|
let hir_sig = tcx.hir().fn_sig_by_hir_id(hir_id);
|
||||||
if let Some(hir_sig) = hir_sig {
|
if let Some(hir_sig) = hir_sig {
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)] // FIXME
|
||||||
match terr {
|
match terr {
|
||||||
TypeError::ArgumentMutability(idx) | TypeError::ArgumentSorts(_, idx) => {
|
TypeError::ArgumentMutability(idx) | TypeError::ArgumentSorts(_, idx) => {
|
||||||
if let Some(ty) = hir_sig.decl.inputs.get(idx) {
|
if let Some(ty) = hir_sig.decl.inputs.get(idx) {
|
||||||
|
|
|
@ -77,6 +77,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emits an error when an unsupported expression is found in a const context.
|
/// Emits an error when an unsupported expression is found in a const context.
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
|
fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
|
||||||
let Self { tcx, def_id, const_kind } = *self;
|
let Self { tcx, def_id, const_kind } = *self;
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ fn find_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
|
fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
|
||||||
if let Some((def_id, _)) = visitor.start_fn {
|
if let Some((def_id, _)) = visitor.start_fn {
|
||||||
Some((def_id.to_def_id(), EntryFnType::Start))
|
Some((def_id.to_def_id(), EntryFnType::Start))
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//! Contains infrastructure for configuring the compiler, including parsing
|
//! Contains infrastructure for configuring the compiler, including parsing
|
||||||
//! command-line options.
|
//! command-line options.
|
||||||
|
|
||||||
|
#![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
|
|
||||||
pub use crate::options::*;
|
pub use crate::options::*;
|
||||||
|
|
||||||
use crate::errors::FileWriteFail;
|
use crate::errors::FileWriteFail;
|
||||||
|
@ -2468,9 +2470,7 @@ pub fn parse_externs(
|
||||||
));
|
));
|
||||||
let adjusted_name = name.replace('-', "_");
|
let adjusted_name = name.replace('-', "_");
|
||||||
if is_ascii_ident(&adjusted_name) {
|
if is_ascii_ident(&adjusted_name) {
|
||||||
// FIXME: make this translatable
|
#[allow(rustc::diagnostic_outside_of_impl)] // FIXME
|
||||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
|
||||||
#[allow(rustc::untranslatable_diagnostic)]
|
|
||||||
error.help(format!(
|
error.help(format!(
|
||||||
"consider replacing the dashes with underscores: `{adjusted_name}`"
|
"consider replacing the dashes with underscores: `{adjusted_name}`"
|
||||||
));
|
));
|
||||||
|
|
|
@ -320,6 +320,7 @@ macro_rules! redirect_field {
|
||||||
type OptionSetter<O> = fn(&mut O, v: Option<&str>) -> bool;
|
type OptionSetter<O> = fn(&mut O, v: Option<&str>) -> bool;
|
||||||
type OptionDescrs<O> = &'static [(&'static str, OptionSetter<O>, &'static str, &'static str)];
|
type OptionDescrs<O> = &'static [(&'static str, OptionSetter<O>, &'static str, &'static str)];
|
||||||
|
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
fn build_options<O: Default>(
|
fn build_options<O: Default>(
|
||||||
early_dcx: &EarlyDiagCtxt,
|
early_dcx: &EarlyDiagCtxt,
|
||||||
matches: &getopts::Matches,
|
matches: &getopts::Matches,
|
||||||
|
|
|
@ -168,6 +168,7 @@ pub fn add_feature_diagnostics<G: EmissionGuarantee>(
|
||||||
/// This variant allows you to control whether it is a library or language feature.
|
/// This variant allows you to control whether it is a library or language feature.
|
||||||
/// Almost always, you want to use this for a language feature. If so, prefer
|
/// Almost always, you want to use this for a language feature. If so, prefer
|
||||||
/// `add_feature_diagnostics`.
|
/// `add_feature_diagnostics`.
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)] // FIXME
|
||||||
pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>(
|
pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>(
|
||||||
err: &mut Diag<'_, G>,
|
err: &mut Diag<'_, G>,
|
||||||
sess: &Session,
|
sess: &Session,
|
||||||
|
|
|
@ -61,6 +61,7 @@ impl SearchPath {
|
||||||
(PathKind::All, path)
|
(PathKind::All, path)
|
||||||
};
|
};
|
||||||
if path.is_empty() {
|
if path.is_empty() {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
early_dcx.early_fatal("empty search path given via `-L`");
|
early_dcx.early_fatal("empty search path given via `-L`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,7 @@ impl Session {
|
||||||
) -> Diag<'a> {
|
) -> Diag<'a> {
|
||||||
let mut err = self.dcx().create_err(err);
|
let mut err = self.dcx().create_err(err);
|
||||||
if err.code.is_none() {
|
if err.code.is_none() {
|
||||||
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
err.code(E0658);
|
err.code(E0658);
|
||||||
}
|
}
|
||||||
add_feature_diagnostics(&mut err, self, feature);
|
add_feature_diagnostics(&mut err, self, feature);
|
||||||
|
@ -1022,6 +1023,7 @@ fn default_emitter(
|
||||||
|
|
||||||
// JUSTIFICATION: literally session construction
|
// JUSTIFICATION: literally session construction
|
||||||
#[allow(rustc::bad_opt_access)]
|
#[allow(rustc::bad_opt_access)]
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
|
||||||
pub fn build_session(
|
pub fn build_session(
|
||||||
early_dcx: EarlyDiagCtxt,
|
early_dcx: EarlyDiagCtxt,
|
||||||
sopts: config::Options,
|
sopts: config::Options,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Compute the binary representation of a type
|
//! Compute the binary representation of a type
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use base_db::salsa::Cycle;
|
use base_db::salsa::Cycle;
|
||||||
|
@ -114,8 +115,8 @@ struct LayoutCx<'a> {
|
||||||
impl<'a> LayoutCalculator for LayoutCx<'a> {
|
impl<'a> LayoutCalculator for LayoutCx<'a> {
|
||||||
type TargetDataLayoutRef = &'a TargetDataLayout;
|
type TargetDataLayoutRef = &'a TargetDataLayout;
|
||||||
|
|
||||||
fn delayed_bug(&self, txt: String) {
|
fn delayed_bug(&self, txt: impl Into<Cow<'static, str>>) {
|
||||||
never!("{}", txt);
|
never!("{}", txt.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_data_layout(&self) -> &'a TargetDataLayout {
|
fn current_data_layout(&self) -> &'a TargetDataLayout {
|
||||||
|
|
|
@ -360,6 +360,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_diagnostic(level: DiagnosticLevel, span: Option<MultiSpan>) -> DiagInner {
|
fn build_diagnostic(level: DiagnosticLevel, span: Option<MultiSpan>) -> DiagInner {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)] // no translation needed for empty string
|
||||||
let mut diag = DiagInner::new(level, "");
|
let mut diag = DiagInner::new(level, "");
|
||||||
diag.messages.clear();
|
diag.messages.clear();
|
||||||
if let Some(span) = span {
|
if let Some(span) = span {
|
||||||
|
|
|
@ -14,8 +14,8 @@ extern crate rustc_session;
|
||||||
extern crate rustc_span;
|
extern crate rustc_span;
|
||||||
|
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
AddToDiagnostic, Diag, EmissionGuarantee, DiagCtxt, IntoDiagnostic, Level,
|
AddToDiagnostic, DecorateLint, Diag, DiagCtxt, DiagInner, DiagMessage, EmissionGuarantee,
|
||||||
SubdiagMessageOp,
|
IntoDiagnostic, Level, SubdiagMessageOp,
|
||||||
};
|
};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -78,6 +78,31 @@ impl AddToDiagnostic for TranslatableInAddToDiagnostic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct UntranslatableInDecorateLint;
|
||||||
|
|
||||||
|
impl<'a> DecorateLint<'a, ()> for UntranslatableInDecorateLint {
|
||||||
|
fn decorate_lint<'b, >(self, diag: &'b mut Diag<'a, ()>) {
|
||||||
|
diag.note("untranslatable diagnostic");
|
||||||
|
//~^ ERROR diagnostics should be created using translatable messages
|
||||||
|
}
|
||||||
|
|
||||||
|
fn msg(&self) -> DiagMessage {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TranslatableInDecorateLint;
|
||||||
|
|
||||||
|
impl<'a> DecorateLint<'a, ()> for TranslatableInDecorateLint {
|
||||||
|
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
|
||||||
|
diag.note(crate::fluent_generated::no_crate_note);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn msg(&self) -> DiagMessage {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) {
|
pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) {
|
||||||
let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
|
let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
|
||||||
//~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
|
//~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
|
||||||
|
@ -87,9 +112,11 @@ pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) {
|
||||||
//~^^ ERROR diagnostics should be created using translatable messages
|
//~^^ ERROR diagnostics should be created using translatable messages
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted.
|
// Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted for
|
||||||
|
// `diagnostic_outside_of_impl`.
|
||||||
|
|
||||||
#[rustc_lint_diagnostics]
|
#[rustc_lint_diagnostics]
|
||||||
pub fn skipped_because_of_annotation<'a>(dcx: &'a DiagCtxt) {
|
pub fn skipped_because_of_annotation<'a>(dcx: &'a DiagCtxt) {
|
||||||
|
#[allow(rustc::untranslatable_diagnostic)]
|
||||||
let _diag = dcx.struct_err("untranslatable diagnostic"); // okay!
|
let _diag = dcx.struct_err("untranslatable diagnostic"); // okay!
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,14 @@ error: diagnostics should be created using translatable messages
|
||||||
LL | diag.note("untranslatable diagnostic");
|
LL | diag.note("untranslatable diagnostic");
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
|
error: diagnostics should be created using translatable messages
|
||||||
|
--> $DIR/diagnostics.rs:85:14
|
||||||
|
|
|
||||||
|
LL | diag.note("untranslatable diagnostic");
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
|
error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
|
||||||
--> $DIR/diagnostics.rs:82:21
|
--> $DIR/diagnostics.rs:107:21
|
||||||
|
|
|
|
||||||
LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
|
LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -29,16 +35,16 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
|
error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
|
||||||
--> $DIR/diagnostics.rs:85:21
|
--> $DIR/diagnostics.rs:110:21
|
||||||
|
|
|
|
||||||
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: diagnostics should be created using translatable messages
|
error: diagnostics should be created using translatable messages
|
||||||
--> $DIR/diagnostics.rs:85:21
|
--> $DIR/diagnostics.rs:110:21
|
||||||
|
|
|
|
||||||
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue