Auto merge of #125410 - fmease:adj-lint-diag-api, r=nnethercote
[perf] Delay the construction of early lint diag structs
Attacks some of the perf regressions from https://github.com/rust-lang/rust/pull/124417#issuecomment-2123700666.
See individual commits for details. The first three commits are not strictly necessary.
However, the 2nd one (06bc4fc671
, *Remove `LintDiagnostic::msg`*) makes the main change way nicer to implement.
It's also pretty sweet on its own if I may say so myself.
This commit is contained in:
commit
b582f807fa
50 changed files with 598 additions and 749 deletions
|
@ -2,7 +2,7 @@ use std::cmp;
|
|||
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_errors::{Diag, DiagMessage, MultiSpan};
|
||||
use rustc_errors::{Diag, MultiSpan};
|
||||
use rustc_hir::{HirId, ItemLocalId};
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_session::lint::{
|
||||
|
@ -270,7 +270,6 @@ pub fn lint_level(
|
|||
level: Level,
|
||||
src: LintLevelSource,
|
||||
span: Option<MultiSpan>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
) {
|
||||
// Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
|
||||
|
@ -282,7 +281,6 @@ pub fn lint_level(
|
|||
level: Level,
|
||||
src: LintLevelSource,
|
||||
span: Option<MultiSpan>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)>,
|
||||
) {
|
||||
// Check for future incompatibility lints and issue a stronger warning.
|
||||
|
@ -351,10 +349,6 @@ pub fn lint_level(
|
|||
}
|
||||
}
|
||||
|
||||
// Delay evaluating and setting the primary message until after we've
|
||||
// suppressed the lint due to macros.
|
||||
err.primary_message(msg);
|
||||
|
||||
err.is_lint(lint.name_lower(), has_future_breakage);
|
||||
|
||||
// Lint diagnostics that are covered by the expect level will not be emitted outside
|
||||
|
@ -419,7 +413,7 @@ pub fn lint_level(
|
|||
explain_lint_level_source(lint, level, src, &mut err);
|
||||
err.emit()
|
||||
}
|
||||
lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate))
|
||||
lint_level_impl(sess, lint, level, src, span, Box::new(decorate))
|
||||
}
|
||||
|
||||
/// Returns whether `span` originates in a foreign crate's external macro.
|
||||
|
|
|
@ -157,6 +157,13 @@ pub struct Deprecated {
|
|||
|
||||
impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated {
|
||||
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
|
||||
diag.primary_message(match &self.since_kind {
|
||||
DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated,
|
||||
DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future,
|
||||
DeprecatedSinceKind::InVersion(_) => {
|
||||
crate::fluent_generated::middle_deprecated_in_version
|
||||
}
|
||||
});
|
||||
diag.arg("kind", self.kind);
|
||||
diag.arg("path", self.path);
|
||||
if let DeprecatedSinceKind::InVersion(version) = self.since_kind {
|
||||
|
@ -172,16 +179,6 @@ impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecate
|
|||
diag.subdiagnostic(diag.dcx, sub);
|
||||
}
|
||||
}
|
||||
|
||||
fn msg(&self) -> rustc_errors::DiagMessage {
|
||||
match &self.since_kind {
|
||||
DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated,
|
||||
DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future,
|
||||
DeprecatedSinceKind::InVersion(_) => {
|
||||
crate::fluent_generated::middle_deprecated_in_version
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind {
|
||||
|
@ -598,7 +595,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
unmarked: impl FnOnce(Span, DefId),
|
||||
) -> bool {
|
||||
let soft_handler = |lint, span, msg: String| {
|
||||
self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {})
|
||||
self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
|
||||
lint.primary_message(msg);
|
||||
})
|
||||
};
|
||||
let eval_result =
|
||||
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
|
||||
|
|
|
@ -113,8 +113,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
||||
self.local_def_id_to_hir_id(local_def_id),
|
||||
self.def_span(ct.def),
|
||||
"cannot use constants which depend on generic parameters in types",
|
||||
|_| {},
|
||||
|lint| { lint.primary_message("cannot use constants which depend on generic parameters in types"); },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,7 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, RwLock, Work
|
|||
#[cfg(parallel_compiler)]
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::{
|
||||
Applicability, Diag, DiagCtxt, DiagMessage, ErrorGuaranteed, LintDiagnostic, MultiSpan,
|
||||
};
|
||||
use rustc_errors::{Applicability, Diag, DiagCtxt, ErrorGuaranteed, LintDiagnostic, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
|
@ -2471,10 +2469,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
span: impl Into<MultiSpan>,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
) {
|
||||
let msg = decorator.msg();
|
||||
let (level, src) = self.lint_level_at_node(lint, hir_id);
|
||||
lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| {
|
||||
decorator.decorate_lint(diag);
|
||||
lint_level(self.sess, lint, level, src, Some(span.into()), |lint| {
|
||||
decorator.decorate_lint(lint);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2488,11 +2485,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
lint: &'static Lint,
|
||||
hir_id: HirId,
|
||||
span: impl Into<MultiSpan>,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
) {
|
||||
let (level, src) = self.lint_level_at_node(lint, hir_id);
|
||||
lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
|
||||
lint_level(self.sess, lint, level, src, Some(span.into()), decorate);
|
||||
}
|
||||
|
||||
/// Find the crate root and the appropriate span where `use` and outer attributes can be
|
||||
|
@ -2543,8 +2539,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
id: HirId,
|
||||
decorator: impl for<'a> LintDiagnostic<'a, ()>,
|
||||
) {
|
||||
self.node_lint(lint, id, decorator.msg(), |diag| {
|
||||
decorator.decorate_lint(diag);
|
||||
self.node_lint(lint, id, |lint| {
|
||||
decorator.decorate_lint(lint);
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2557,11 +2553,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
self,
|
||||
lint: &'static Lint,
|
||||
id: HirId,
|
||||
msg: impl Into<DiagMessage>,
|
||||
decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>),
|
||||
) {
|
||||
let (level, src) = self.lint_level_at_node(lint, id);
|
||||
lint_level(self.sess, lint, level, src, None, msg, decorate);
|
||||
lint_level(self.sess, lint, level, src, None, decorate);
|
||||
}
|
||||
|
||||
pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> {
|
||||
|
|
|
@ -3314,7 +3314,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
|
|||
///
|
||||
/// The implementation uses similar import discovery logic to that of 'use' suggestions.
|
||||
///
|
||||
/// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`].
|
||||
/// See also [`with_no_trimmed_paths!`].
|
||||
// this is pub to be able to intra-doc-link it
|
||||
pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> {
|
||||
// Trimming paths is expensive and not optimized, since we expect it to only be used for error
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue