Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9014fda
Update link in suggestion for pinning self
Trivaxy Jan 1, 2026
2484cfe
ptr::replace: make calls on ZST null ptr not UB
RalfJung Nov 21, 2025
b13d69f
delete some very old trivial `Box` tests
cyrgani Feb 19, 2026
fe29f03
rustc_public: `pub(crate)` the fields that shouldn't be exposed
makai410 Feb 20, 2026
b608343
implement debuginfo for unsafe binders
makai410 Feb 23, 2026
93b9973
rustc_expand: improve diagnostics for non-repeatable metavars
Unique-Usman Feb 15, 2026
d60e15f
Rename `pass_by_value` lint as `disallowed_pass_by_ref`.
nnethercote Feb 23, 2026
327f778
Migrate `rustc_privacy` to use `TyCtxt::emit_diag_node_span_lint`
GuillaumeGomez Feb 24, 2026
c53fbcd
Migrate `rustc_pattern_analysis` to use `TyCtxt::emit_diag_node_span_…
GuillaumeGomez Feb 24, 2026
b55f6e3
Migrate `rustc_lint` to use `TyCtxt::emit_diag_node_span_lint`
GuillaumeGomez Feb 24, 2026
d926c1b
Migrate `rustc_mir_build` to use `TyCtxt::emit_diag_node_span_lint`
GuillaumeGomez Feb 24, 2026
480aa4d
Migrate `rustc_mir_transform` to use `TyCtxt::emit_diag_node_span_lint`
GuillaumeGomez Feb 24, 2026
f02ce96
Migrate `rustc_monomorphize` to use `TyCtxt::emit_diag_node_span_lint`
GuillaumeGomez Feb 24, 2026
8f63c00
Migrate `rustc_passes` to use `TyCtxt::emit_diag_node_span_lint`
GuillaumeGomez Feb 24, 2026
1c6c0f7
Migrate `rustc_trait_selection` to use `TyCtxt::emit_diag_node_span_l…
GuillaumeGomez Feb 24, 2026
2bb3b01
Replace `TyCtxt::emit_node_span_lint` with `emit_diag_node_span_lint`
GuillaumeGomez Feb 24, 2026
8fa1fca
Apply new change from `lint_level` into `diag_lint_level`
GuillaumeGomez Feb 24, 2026
6d50ef1
Rollup merge of #149169 - RalfJung:replace-zst-null-ptr, r=Mark-Simul…
GuillaumeGomez Feb 24, 2026
336ef7e
Rollup merge of #150562 - Trivaxy:poll-doc-patch, r=me
GuillaumeGomez Feb 24, 2026
0e14061
Rollup merge of #152679 - Unique-Usman:ua/decmacrounrepeatable, r=est…
GuillaumeGomez Feb 24, 2026
c39abd4
Rollup merge of #153017 - makai410:di-unsafe-binder, r=wesleywiser
GuillaumeGomez Feb 24, 2026
17f9a9e
Rollup merge of #152868 - cyrgani:no-trivial-box-tests, r=Kivooeo
GuillaumeGomez Feb 24, 2026
0e8482a
Rollup merge of #152922 - makai410:rpub/priv-field, r=celinval
GuillaumeGomez Feb 24, 2026
2d465b9
Rollup merge of #153029 - nnethercote:disallowed-pass-by-ref, r=Urgau
GuillaumeGomez Feb 24, 2026
fea905f
Rollup merge of #153051 - GuillaumeGomez:migrate-diag, r=JonathanBrouwer
GuillaumeGomez Feb 24, 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
6 changes: 4 additions & 2 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -757,9 +757,11 @@ macro_rules! common_visitor_and_walkers {
) -> V::Result;
}

// this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier
// This is only used by the MutVisitor. We include this symmetry here to make writing other
// functions easier.
$(${ignore($lt)}
#[expect(unused, rustc::pass_by_value)]
#[cfg_attr(not(bootstrap), expect(unused, rustc::disallowed_pass_by_ref))]
#[cfg_attr(bootstrap, expect(unused, rustc::pass_by_value))]
#[inline]
)?
fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, span: &$($lt)? $($mut)? Span) -> V::Result {
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2698,12 +2698,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {

let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);

tcx.emit_diag_node_span_lint(
UNUSED_MUT,
lint_root,
span,
VarNeedNotMut { span: mut_span },
)
tcx.emit_node_span_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
}
}
}
Expand Down
53 changes: 51 additions & 2 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,7 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
},
ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
ty::Pat(base, _) => return type_di_node(cx, base),
// FIXME(unsafe_binders): impl debug info
ty::UnsafeBinder(_) => unimplemented!(),
ty::UnsafeBinder(_) => build_unsafe_binder_type_di_node(cx, t, unique_type_id),
ty::Alias(..)
| ty::Param(_)
| ty::Bound(..)
Expand Down Expand Up @@ -1488,6 +1487,56 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
.di_node
}

/// Creates the debuginfo node for `unsafe<'a> T` binder types.
///
/// We treat an unsafe binder like a struct with a single field named `inner`
/// rather than delegating to the inner type's DI node directly. This way the
/// debugger shows the binder's own type name, and the wrapped value is still
/// accessible through the `inner` field.
fn build_unsafe_binder_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
binder_type: Ty<'tcx>,
unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> {
let ty::UnsafeBinder(inner) = binder_type.kind() else {
bug!(
"Only ty::UnsafeBinder is valid for build_unsafe_binder_type_di_node. Found {:?} instead.",
binder_type
)
};
let inner_type = inner.skip_binder();
let inner_type_di_node = type_di_node(cx, inner_type);

let type_name = compute_debuginfo_type_name(cx.tcx, binder_type, true);
type_map::build_type_with_children(
cx,
type_map::stub(
cx,
Stub::Struct,
unique_type_id,
&type_name,
None,
cx.size_and_align_of(binder_type),
NO_SCOPE_METADATA,
DIFlags::FlagZero,
),
|cx, unsafe_binder_type_di_node| {
let inner_layout = cx.layout_of(inner_type);
smallvec![build_field_di_node(
cx,
unsafe_binder_type_di_node,
"inner",
inner_layout,
Size::ZERO,
DIFlags::FlagZero,
inner_type_di_node,
None,
)]
},
NO_GENERICS,
)
}

/// Get the global variable for the vtable.
///
/// When using global variables, we may have created an addrspacecast to get a pointer to the
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,19 @@ fn push_debuginfo_type_name<'tcx>(
push_closure_or_coroutine_name(tcx, def_id, args, qualified, output, visited);
}
}
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binders)"),
ty::UnsafeBinder(inner) => {
if cpp_like_debuginfo {
output.push_str("unsafe$<");
} else {
output.push_str("unsafe ");
}

push_debuginfo_type_name(tcx, inner.skip_binder(), qualified, output, visited);

if cpp_like_debuginfo {
push_close_angle_bracket(cpp_like_debuginfo, output);
}
}
ty::Param(_)
| ty::Error(_)
| ty::Infer(_)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub(crate) fn from_target_feature_attr(
// For "neon" specifically, we emit an FCW instead of a hard error.
// See <https://github.com/rust-lang/rust/issues/134375>.
if tcx.sess.target.arch == Arch::AArch64 && name.as_str() == "neon" {
tcx.emit_diag_node_span_lint(
tcx.emit_node_span_lint(
AARCH64_SOFTFLOAT_NEON,
tcx.local_def_id_to_hir_id(did),
feature_span,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,5 @@ pub(super) fn lint<'tcx, L>(
{
let (span, frames) = get_span_and_frames(tcx, &machine.stack);

tcx.emit_diag_node_span_lint(lint, machine.best_lint_scope(*tcx), span, decorator(frames));
tcx.emit_node_span_lint(lint, machine.best_lint_scope(*tcx), span, decorator(frames));
}
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
.level
.is_error();
let span = ecx.cur_span();
ecx.tcx.emit_diag_node_span_lint(
ecx.tcx.emit_node_span_lint(
rustc_session::lint::builtin::LONG_RUNNING_CONST_EVAL,
hir_id,
span,
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,16 @@ impl<'cx> MacroExpanderResult<'cx> {
// Emit the SEMICOLON_IN_EXPRESSIONS_FROM_MACROS deprecation lint.
let is_local = true;

let parser = ParserAnyMacro::from_tts(cx, tts, site_span, arm_span, is_local, macro_ident);
let parser = ParserAnyMacro::from_tts(
cx,
tts,
site_span,
arm_span,
is_local,
macro_ident,
vec![],
vec![],
);
ExpandResult::Ready(Box::new(parser))
}
}
Expand Down
52 changes: 51 additions & 1 deletion compiler/rustc_expand/src/mbe/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,13 @@ impl<'dcx> CollectTrackerAndEmitter<'dcx, '_> {

pub(super) fn emit_frag_parse_err(
mut e: Diag<'_>,
parser: &Parser<'_>,
parser: &mut Parser<'_>,
orig_parser: &mut Parser<'_>,
site_span: Span,
arm_span: Span,
kind: AstFragmentKind,
bindings: Vec<Ident>,
matched_rule_bindings: Vec<Ident>,
) -> ErrorGuaranteed {
// FIXME(davidtwco): avoid depending on the error message text
if parser.token == token::Eof
Expand Down Expand Up @@ -285,6 +287,54 @@ pub(super) fn emit_frag_parse_err(
},
_ => annotate_err_with_kind(&mut e, kind, site_span),
};

let matched_rule_bindings_names: Vec<_> =
matched_rule_bindings.iter().map(|bind| bind.name).collect();
let bindings_name: Vec<_> = bindings.iter().map(|bind| bind.name).collect();
if parser.token.kind == token::Dollar {
parser.bump();
if let token::Ident(name, _) = parser.token.kind {
if let Some(matched_name) = rustc_span::edit_distance::find_best_match_for_name(
&matched_rule_bindings_names[..],
name,
None,
) {
e.span_suggestion_verbose(
parser.token.span,
"there is a macro metavariable with similar name",
format!("{matched_name}"),
Applicability::MaybeIncorrect,
);
} else if bindings_name.contains(&name) {
e.span_label(
parser.token.span,
format!(
"there is an macro metavariable with this name in another macro matcher"
),
);
} else if let Some(matched_name) =
rustc_span::edit_distance::find_best_match_for_name(&bindings_name[..], name, None)
{
e.span_suggestion_verbose(
parser.token.span,
"there is a macro metavariable with a similar name in another macro matcher",
format!("{matched_name}"),
Applicability::MaybeIncorrect,
);
} else {
let msg = matched_rule_bindings_names
.iter()
.map(|sym| format!("${}", sym))
.collect::<Vec<_>>()
.join(", ");

e.span_label(parser.token.span, format!("macro metavariable not found"));
if !matched_rule_bindings_names.is_empty() {
e.note(format!("available metavariable names are: {msg}"));
}
}
}
}
e.emit()
}

Expand Down
46 changes: 43 additions & 3 deletions compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub(crate) struct ParserAnyMacro<'a> {
arm_span: Span,
/// Whether or not this macro is defined in the current crate
is_local: bool,
bindings: Vec<Ident>,
matched_rule_bindings: Vec<Ident>,
}

impl<'a> ParserAnyMacro<'a> {
Expand All @@ -67,13 +69,22 @@ impl<'a> ParserAnyMacro<'a> {
arm_span,
is_trailing_mac,
is_local,
bindings,
matched_rule_bindings,
} = *self;
let snapshot = &mut parser.create_snapshot_for_diagnostic();
let fragment = match parse_ast_fragment(parser, kind) {
Ok(f) => f,
Err(err) => {
let guar = diagnostics::emit_frag_parse_err(
err, parser, snapshot, site_span, arm_span, kind,
err,
parser,
snapshot,
site_span,
arm_span,
kind,
bindings,
matched_rule_bindings,
);
return kind.dummy(site_span, guar);
}
Expand Down Expand Up @@ -108,6 +119,9 @@ impl<'a> ParserAnyMacro<'a> {
arm_span: Span,
is_local: bool,
macro_ident: Ident,
// bindings and lhs is for diagnostics
bindings: Vec<Ident>,
matched_rule_bindings: Vec<Ident>,
) -> Self {
Self {
parser: Parser::new(&cx.sess.psess, tts, None),
Expand All @@ -121,6 +135,8 @@ impl<'a> ParserAnyMacro<'a> {
is_trailing_mac: cx.current_expansion.is_trailing_mac,
arm_span,
is_local,
bindings,
matched_rule_bindings,
}
}
}
Expand Down Expand Up @@ -359,7 +375,7 @@ fn expand_macro<'cx>(

match try_success_result {
Ok((rule_index, rule, named_matches)) => {
let MacroRule::Func { rhs, .. } = rule else {
let MacroRule::Func { lhs, rhs, .. } = rule else {
panic!("try_match_macro returned non-func rule");
};
let mbe::TokenTree::Delimited(rhs_span, _, rhs) = rhs else {
Expand Down Expand Up @@ -387,8 +403,32 @@ fn expand_macro<'cx>(
cx.resolver.record_macro_rule_usage(node_id, rule_index);
}

let mut bindings = vec![];
for rule in rules {
let MacroRule::Func { lhs, .. } = rule else { continue };
for param in lhs {
let MatcherLoc::MetaVarDecl { bind, .. } = param else { continue };
bindings.push(*bind);
}
}

let mut matched_rule_bindings = vec![];
for param in lhs {
let MatcherLoc::MetaVarDecl { bind, .. } = param else { continue };
matched_rule_bindings.push(*bind);
}

// Let the context choose how to interpret the result. Weird, but useful for X-macros.
Box::new(ParserAnyMacro::from_tts(cx, tts, sp, arm_span, is_local, name))
Box::new(ParserAnyMacro::from_tts(
cx,
tts,
sp,
arm_span,
is_local,
name,
bindings,
matched_rule_bindings,
))
}
Err(CanRetry::No(guar)) => {
debug!("Will not retry matching as an error was emitted already");
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,7 @@ fn check_impl_items_against_trait<'tcx>(
}

if self_is_guaranteed_unsize_self && tcx.generics_require_sized_self(ty_trait_item.def_id) {
tcx.emit_diag_node_span_lint(
tcx.emit_node_span_lint(
rustc_lint_defs::builtin::DEAD_CODE,
tcx.local_def_id_to_hir_id(ty_impl_item.def_id.expect_local()),
tcx.def_span(ty_impl_item.def_id),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ fn report_mismatched_rpitit_signature<'tcx>(
with_no_trimmed_paths!(with_types_for_signature!(format!("{return_ty}")));

let span = unmatched_bound.unwrap_or(span);
tcx.emit_diag_node_span_lint(
tcx.emit_node_span_lint(
if is_internal { REFINING_IMPL_TRAIT_INTERNAL } else { REFINING_IMPL_TRAIT_REACHABLE },
tcx.local_def_id_to_hir_id(impl_m_def_id.expect_local()),
span,
Expand Down Expand Up @@ -442,7 +442,7 @@ fn report_mismatched_rpitit_captures<'tcx>(
.sort_by_cached_key(|arg| !matches!(arg.kind(), ty::GenericArgKind::Lifetime(_)));
let suggestion = format!("use<{}>", trait_captured_args.iter().join(", "));

tcx.emit_diag_node_span_lint(
tcx.emit_node_span_lint(
if is_internal { REFINING_IMPL_TRAIT_INTERNAL } else { REFINING_IMPL_TRAIT_REACHABLE },
tcx.local_def_id_to_hir_id(impl_opaque_def_id),
use_bound_span,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ fn lint_item_shadowing_supertrait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_def_i
errors::SupertraitItemShadowee::Several { traits: traits.into(), spans: spans.into() }
};

tcx.emit_diag_node_span_lint(
tcx.emit_node_span_lint(
SHADOWING_SUPERTRAIT_ITEMS,
tcx.local_def_id_to_hir_id(trait_item_def_id),
tcx.def_span(trait_item_def_id),
Expand Down Expand Up @@ -2458,7 +2458,7 @@ fn lint_redundant_lifetimes<'tcx>(
&& outlives_env.free_region_map().sub_free_regions(tcx, victim, candidate)
{
shadowed.insert(victim);
tcx.emit_diag_node_span_lint(
tcx.emit_node_span_lint(
rustc_lint_defs::builtin::REDUNDANT_LIFETIMES,
tcx.local_def_id_to_hir_id(def_id.expect_local()),
tcx.def_span(def_id),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,13 +497,13 @@ fn lint_uncovered_ty_params<'tcx>(
let name = tcx.item_ident(param_def_id);

match local_ty {
Some(local_type) => tcx.emit_diag_node_span_lint(
Some(local_type) => tcx.emit_node_span_lint(
UNCOVERED_PARAM_IN_PROJECTION,
hir_id,
span,
errors::TyParamFirstLocalLint { span, note: (), param: name, local_type },
),
None => tcx.emit_diag_node_span_lint(
None => tcx.emit_node_span_lint(
UNCOVERED_PARAM_IN_PROJECTION,
hir_id,
span,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// FIXME(mgca): Ideally we would generalize the name of this lint to sth. like
// `unused_associated_item_bindings` since this can now also trigger on *const*
// projections / assoc *const* bindings.
tcx.emit_diag_node_span_lint(
tcx.emit_node_span_lint(
UNUSED_ASSOCIATED_TYPE_BOUNDS,
hir_id,
span,
Expand Down
Loading
Loading