Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8b83d4b
Adds recursion limit into FindParamInClause
spirali Feb 18, 2026
e5250ec
tools: remote-test-server: Add UEFI run support
Ayush1325 Mar 1, 2026
affe609
tests: codegen-llvm: iter-repeat-n-trivial-drop: Allow non-zero lower…
Gelbpunkt Mar 2, 2026
13ddff5
Adapt codegen test to accept operand bundles
TimNN Mar 2, 2026
6d6493a
tweak r-a default settings
WaffleLapkin Nov 3, 2025
390f683
std: move non-path functions into dedicated module in PAL
joboet Mar 2, 2026
866975f
std: move SOLID error converting out of `pal::os`
joboet Mar 2, 2026
d31aecf
std: reorganize some WASI helpers
joboet Mar 4, 2026
fcddf7f
Propagate certainty
spirali Mar 5, 2026
58652d5
Fix LegacyKeyValueFormat report from docker build: ohos
homersimpsons Mar 7, 2026
592246e
Added comments
spirali Mar 7, 2026
85c4af7
Rustfmt now support use closures on edition 2018
spastorino Jul 2, 2025
e636647
Move some ui tests
reddevilmidzy Mar 9, 2026
00980f4
Test for armv7 `get_unchecked(...)` inlining
Jamesbarford Feb 19, 2026
4019a92
Add new `rustc_errors::DiagDecorator` type
GuillaumeGomez Mar 7, 2026
c45bf4a
Remove `TyCtxt::node_span_lint` usage from `rustc_lint`
GuillaumeGomez Mar 6, 2026
01aff0d
Remove `TyCtxt::node_span_lint` usage from `rustc_middle`
GuillaumeGomez Mar 6, 2026
0d974a2
Remove `TyCtxt::node_span_lint` usage from `rustc_mir_build`
GuillaumeGomez Mar 6, 2026
3a64713
Remove `TyCtxt::node_span_lint` usage from `rustc_mir_transform`
GuillaumeGomez Mar 6, 2026
4e2a519
Remove `TyCtxt::node_span_lint` usage from `rustc_trait_selection`
GuillaumeGomez Mar 6, 2026
344344b
Remove `TyCtxt::node_span_lint` usage from `librustdoc`
GuillaumeGomez Mar 6, 2026
d31a17f
Use `DiagDecorator` instead of `derive(Diagnostic)` in `compiler/rust…
GuillaumeGomez Mar 8, 2026
a5bd6be
Rollup merge of #152847 - Jamesbarford:chore/get_unchecked-inline-tes…
JonathanBrouwer Mar 9, 2026
2f5d672
Rollup merge of #153290 - Gelbpunkt:iter-repeat-n-trivial-drop-lower-…
JonathanBrouwer Mar 9, 2026
b8e01ed
Rollup merge of #153413 - joboet:organize-pal-os, r=Mark-Simulacrum
JonathanBrouwer Mar 9, 2026
9c09ff3
Rollup merge of #139692 - spastorino:do-not-rustfmt-ignore, r=Mark-Si…
JonathanBrouwer Mar 9, 2026
fad370c
Rollup merge of #152800 - spirali:fix-FindParamInClause, r=lcnr
JonathanBrouwer Mar 9, 2026
8b12e0a
Rollup merge of #153244 - Ayush1325:uefi-run-test, r=Mark-Simulacrum
JonathanBrouwer Mar 9, 2026
662798e
Rollup merge of #153305 - TimNN:bundle-assert, r=Mark-Simulacrum
JonathanBrouwer Mar 9, 2026
3fdbbfb
Rollup merge of #153340 - WaffleLapkin:ra-settings-tweaks, r=Mark-Sim…
JonathanBrouwer Mar 9, 2026
d4630f1
Rollup merge of #153509 - GuillaumeGomez:migrate-diag2, r=JonathanBro…
JonathanBrouwer Mar 9, 2026
4ff5147
Rollup merge of #153527 - homersimpsons:chore/fix-LegacyKeyValueForma…
JonathanBrouwer Mar 9, 2026
2d9fde7
Rollup merge of #153594 - reddevilmidzy:ui-refactor, r=JohnTitor,Kivooeo
JonathanBrouwer Mar 9, 2026
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
11 changes: 11 additions & 0 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ impl<'a> Diagnostic<'a, ()>
}
}

/// Type used to emit diagnostic through a closure instead of implementing the `Diagnostic` trait.
pub struct DiagDecorator<F: FnOnce(&mut Diag<'_, ()>)>(pub F);

impl<'a, F: FnOnce(&mut Diag<'_, ()>)> Diagnostic<'a, ()> for DiagDecorator<F> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
let mut diag = Diag::new(dcx, level, "");
(self.0)(&mut diag);
diag
}
}

/// Trait implemented by error types. This should not be implemented manually. Instead, use
/// `#[derive(Subdiagnostic)]` -- see [rustc_macros::Subdiagnostic].
#[rustc_diagnostic_item = "Subdiagnostic"]
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ pub use anstyle::{
pub use codes::*;
pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
pub use diagnostic::{
BugAbort, Diag, DiagInner, DiagLocation, DiagStyledString, Diagnostic, EmissionGuarantee,
FatalAbort, StringPart, Subdiag, Subdiagnostic,
BugAbort, Diag, DiagDecorator, DiagInner, DiagLocation, DiagStyledString, Diagnostic,
EmissionGuarantee, FatalAbort, StringPart, Subdiag, Subdiagnostic,
};
pub use diagnostic_impls::{
DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
Expand Down
87 changes: 48 additions & 39 deletions compiler/rustc_lint/src/default_could_be_derived.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, Diag};
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, Level};
use rustc_hir as hir;
use rustc_middle::ty;
use rustc_middle::ty::TyCtxt;
Expand Down Expand Up @@ -147,50 +147,59 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {

let hir_id = cx.tcx.local_def_id_to_hir_id(impl_id);
let span = cx.tcx.hir_span_with_body(hir_id);
cx.tcx.node_span_lint(DEFAULT_OVERRIDES_DEFAULT_FIELDS, hir_id, span, |diag| {
mk_lint(cx.tcx, diag, type_def_id, orig_fields, fields, span);
});
cx.tcx.emit_node_span_lint(
DEFAULT_OVERRIDES_DEFAULT_FIELDS,
hir_id,
span,
WrongDefaultImpl { tcx: cx.tcx, type_def_id, orig_fields, fields, impl_span: span },
);
}
}

fn mk_lint(
tcx: TyCtxt<'_>,
diag: &mut Diag<'_, ()>,
struct WrongDefaultImpl<'a, 'hir, 'tcx> {
tcx: TyCtxt<'tcx>,
type_def_id: DefId,
orig_fields: FxHashMap<Symbol, &hir::FieldDef<'_>>,
fields: &[hir::ExprField<'_>],
orig_fields: FxHashMap<Symbol, &'a hir::FieldDef<'hir>>,
fields: &'a [hir::ExprField<'hir>],
impl_span: Span,
) {
diag.primary_message("`Default` impl doesn't use the declared default field values");

// For each field in the struct expression
// - if the field in the type has a default value, it should be removed
// - elif the field is an expression that could be a default value, it should be used as the
// field's default value (FIXME: not done).
// - else, we wouldn't touch this field, it would remain in the manual impl
let mut removed_all_fields = true;
for field in fields {
if orig_fields.get(&field.ident.name).and_then(|f| f.default).is_some() {
diag.span_label(field.expr.span, "this field has a default value");
} else {
removed_all_fields = false;
}

impl<'a, 'b, 'hir, 'tcx> Diagnostic<'a, ()> for WrongDefaultImpl<'b, 'hir, 'tcx> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
let Self { tcx, type_def_id, orig_fields, fields, impl_span } = self;
let mut diag =
Diag::new(dcx, level, "`Default` impl doesn't use the declared default field values");

// For each field in the struct expression
// - if the field in the type has a default value, it should be removed
// - elif the field is an expression that could be a default value, it should be used as the
// field's default value (FIXME: not done).
// - else, we wouldn't touch this field, it would remain in the manual impl
let mut removed_all_fields = true;
for field in fields {
if orig_fields.get(&field.ident.name).and_then(|f| f.default).is_some() {
diag.span_label(field.expr.span, "this field has a default value");
} else {
removed_all_fields = false;
}
}
}

if removed_all_fields {
let msg = "to avoid divergence in behavior between `Struct { .. }` and \
`<Struct as Default>::default()`, derive the `Default`";
diag.multipart_suggestion(
msg,
vec![
(tcx.def_span(type_def_id).shrink_to_lo(), "#[derive(Default)] ".to_string()),
(impl_span, String::new()),
],
Applicability::MachineApplicable,
);
} else {
let msg = "use the default values in the `impl` with `Struct { mandatory_field, .. }` to \
avoid them diverging over time";
diag.help(msg);
if removed_all_fields {
diag.multipart_suggestion(
"to avoid divergence in behavior between `Struct { .. }` and \
`<Struct as Default>::default()`, derive the `Default`",
vec![
(tcx.def_span(type_def_id).shrink_to_lo(), "#[derive(Default)] ".to_string()),
(impl_span, String::new()),
],
Applicability::MachineApplicable,
);
} else {
diag.help(
"use the default values in the `impl` with `Struct { mandatory_field, .. }` to \
avoid them diverging over time",
);
}
diag
}
}
27 changes: 18 additions & 9 deletions compiler/rustc_lint/src/transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,15 +357,24 @@ fn check_unnecessary_transmute<'tcx>(
_ => return,
};

cx.tcx.node_span_lint(UNNECESSARY_TRANSMUTES, expr.hir_id, expr.span, |diag| {
diag.primary_message("unnecessary transmute");
if let Some(sugg) = sugg {
diag.multipart_suggestion("replace this with", sugg, Applicability::MachineApplicable);
}
if let Some(help) = help {
diag.help(help);
}
});
cx.tcx.emit_node_span_lint(
UNNECESSARY_TRANSMUTES,
expr.hir_id,
expr.span,
rustc_errors::DiagDecorator(|diag| {
diag.primary_message("unnecessary transmute");
if let Some(sugg) = sugg {
diag.multipart_suggestion(
"replace this with",
sugg,
Applicability::MachineApplicable,
);
}
if let Some(help) = help {
diag.help(help);
}
}),
);
}

#[derive(Diagnostic)]
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_middle/src/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,9 +564,14 @@ 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, |lint| {
lint.primary_message(msg);
})
self.emit_node_span_lint(
lint,
id.unwrap_or(hir::CRATE_HIR_ID),
span,
rustc_errors::DiagDecorator(|lint| {
lint.primary_message(msg);
}),
);
};
let eval_result =
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,15 @@ impl<'tcx> TyCtxt<'tcx> {
let mir_body = self.mir_for_ctfe(cid.instance.def_id());
if mir_body.is_polymorphic {
let Some(local_def_id) = ct.def.as_local() else { return };
self.node_span_lint(
self.emit_node_span_lint(
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
self.local_def_id_to_hir_id(local_def_id),
self.def_span(ct.def),
|lint| {
rustc_errors::DiagDecorator(|lint| {
lint.primary_message(
"cannot use constants which depend on generic parameters in types",
);
},
}),
)
}
}
Expand Down
13 changes: 9 additions & 4 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use rustc_hir::lang_items::LangItem;
use rustc_hir::limit::Limit;
use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr};
use rustc_index::IndexVec;
use rustc_macros::Diagnostic;
use rustc_session::Session;
use rustc_session::config::CrateType;
use rustc_session::cstore::{CrateStoreDyn, Untracked};
Expand Down Expand Up @@ -1685,6 +1686,12 @@ impl<'tcx> TyCtxt<'tcx> {
}

pub fn report_unused_features(self) {
#[derive(Diagnostic)]
#[diag("feature `{$feature}` is declared but not used")]
struct UnusedFeature {
feature: Symbol,
}

// Collect first to avoid holding the lock while linting.
let used_features = self.sess.used_features.lock();
let unused_features = self
Expand All @@ -1703,13 +1710,11 @@ impl<'tcx> TyCtxt<'tcx> {
.collect::<Vec<_>>();

for (feature, span) in unused_features {
self.node_span_lint(
self.emit_node_span_lint(
rustc_session::lint::builtin::UNUSED_FEATURES,
CRATE_HIR_ID,
span,
|lint| {
lint.primary_message(format!("feature `{}` is declared but not used", feature));
},
UnusedFeature { feature },
);
}
}
Expand Down
13 changes: 9 additions & 4 deletions compiler/rustc_mir_build/src/thir/pattern/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,15 @@ impl<'a> PatMigration<'a> {
self.format_subdiagnostics(&mut err);
err.emit();
} else {
tcx.node_span_lint(lint::builtin::RUST_2024_INCOMPATIBLE_PAT, pat_id, spans, |diag| {
diag.primary_message(primary_message);
self.format_subdiagnostics(diag);
});
tcx.emit_node_span_lint(
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
pat_id,
spans,
rustc_errors::DiagDecorator(|diag| {
diag.primary_message(primary_message);
self.format_subdiagnostics(diag);
}),
);
}
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir_transform/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>(
caller_def_id: DefId,
callee_only: &[&'a str],
) {
tcx.node_span_lint(
tcx.emit_node_span_lint(
lint::builtin::INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES,
tcx.local_def_id_to_hir_id(caller_def_id.as_local().unwrap()),
call_span,
|lint| {
rustc_errors::DiagDecorator(|lint| {
let callee = tcx.def_path_str(callee_def_id);
let caller = tcx.def_path_str(caller_def_id);

Expand All @@ -46,7 +46,7 @@ pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>(
format!("#[target_feature(enable = \"{feats}\")]\n"),
lint::Applicability::MaybeIncorrect,
);
},
}),
);
}

Expand Down
Loading
Loading