Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
a5b1187
Region values: use an enum as opposed to two `Option`s
amandasystems May 27, 2026
936f0ce
Restore simpler Encode/Decode impls for u32 and (on 64bit systems) usize
bjorn3 Jun 2, 2026
381cea9
fix
bb1yd Jun 1, 2026
b5acf95
Render `impl` restriction
CoCo-Japan-pan Jun 2, 2026
5358c2f
Add tests for `impl` restriction rendering
CoCo-Japan-pan Jun 2, 2026
49f80b3
Remove unnecessary arm
mu001999 Jun 2, 2026
5521a56
Remove `skip_arg` attribute from `Diagnostic` and `Subdiagnostic` pro…
GuillaumeGomez May 28, 2026
551940e
Remove `#[skip_arg]` references from rustc-dev-guide
GuillaumeGomez May 28, 2026
579831c
Fix compilation error because of `potential_query_instability` in `di…
GuillaumeGomez Jun 2, 2026
62fbbec
Add test for undefined EII static error
bjorn3 Jun 2, 2026
57a4afc
Rollup merge of #157035 - amandasystems:region-values-either, r=jackh726
JonathanBrouwer Jun 2, 2026
3416f56
Rollup merge of #157182 - bjorn3:fix_perf_regression, r=petrochenkov
JonathanBrouwer Jun 2, 2026
4bb6e9c
Rollup merge of #157310 - CoCo-Japan-pan:render-impl-restriction, r=G…
JonathanBrouwer Jun 2, 2026
a408e19
Rollup merge of #157070 - GuillaumeGomez:rm-skip_arg, r=JonathanBrouwer
JonathanBrouwer Jun 2, 2026
17a6025
Rollup merge of #157235 - bb1yd:improve-colon-suggestion, r=mejrs
JonathanBrouwer Jun 2, 2026
c5a0b2c
Rollup merge of #157321 - mu001999-contrib:nit, r=JonathanBrouwer
JonathanBrouwer Jun 2, 2026
d874962
Rollup merge of #157324 - bjorn3:eii_error_test, r=jdonszelmann
JonathanBrouwer Jun 2, 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
108 changes: 59 additions & 49 deletions compiler/rustc_borrowck/src/region_infer/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_index::Idx;
use rustc_index::bit_set::SparseBitMatrix;
use rustc_index::interval::{IntervalSet, SparseIntervalMatrix};
use rustc_middle::bug;
use rustc_middle::mir::{BasicBlock, Location};
use rustc_middle::ty::{self, RegionVid};
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
Expand Down Expand Up @@ -35,22 +36,26 @@ pub(crate) enum RegionElement<'tcx> {
PlaceholderRegion(ty::PlaceholderRegion<'tcx>),
}

/// Either a mapping of which points a region is live at (for regular bodies),
/// or which regions are live in the body somewhere (for promoteds, which do
/// not care about where they are live, only that they are).
#[derive(Clone)] // FIXME(#146079)
enum LiveRegions {
/// region `'r` is live at locations `L`.
AtPoints(SparseIntervalMatrix<RegionVid, PointIndex>),
/// Region `'r` is live in function body.
InBody(FxHashSet<RegionVid>),
}

/// Records the CFG locations where each region is live. When we initially compute liveness, we use
/// an interval matrix storing liveness ranges for each region-vid.
#[derive(Clone)] // FIXME(#146079)
pub(crate) struct LivenessValues {
/// The map from locations to points.
location_map: Rc<DenseLocationMap>,

/// Which regions are live. This is exclusive with the fine-grained tracking in `points`, and
/// currently only used for validating promoteds (which don't care about more precise tracking).
live_regions: Option<FxHashSet<RegionVid>>,

/// For each region: the points where it is live.
///
/// This is not initialized for promoteds, because we don't care *where* within a promoted a
/// region is live, only that it is.
points: Option<SparseIntervalMatrix<RegionVid, PointIndex>>,
/// Where a region is live.
live_regions: LiveRegions,

/// When using `-Zpolonius=next`, the set of loans that are live at a given point in the CFG.
live_loans: Option<LiveLoans>,
Expand All @@ -60,8 +65,9 @@ impl LivenessValues {
/// Create an empty map of regions to locations where they're live.
pub(crate) fn with_specific_points(location_map: Rc<DenseLocationMap>) -> Self {
LivenessValues {
live_regions: None,
points: Some(SparseIntervalMatrix::new(location_map.num_points())),
live_regions: LiveRegions::AtPoints(SparseIntervalMatrix::new(
location_map.num_points(),
)),
location_map,
live_loans: None,
}
Expand All @@ -73,8 +79,7 @@ impl LivenessValues {
/// which regions are live.
pub(crate) fn without_specific_points(location_map: Rc<DenseLocationMap>) -> Self {
LivenessValues {
live_regions: Some(Default::default()),
points: None,
live_regions: LiveRegions::InBody(Default::default()),
location_map,
live_loans: None,
}
Expand All @@ -83,51 +88,70 @@ impl LivenessValues {
/// Returns the liveness matrix of points where each region is live. Panics if the liveness
/// values have been created without any per-point data (that is, for promoteds).
pub(crate) fn points(&self) -> &SparseIntervalMatrix<RegionVid, PointIndex> {
self.points
.as_ref()
.expect("this `LivenessValues` wasn't created using `with_specific_points`")
if let LiveRegions::AtPoints(points) = &self.live_regions {
points
} else {
bug!("this `LivenessValues` wasn't created using `with_specific_points`")
}
}

/// Iterate through each region that has a value in this set.
pub(crate) fn regions(&self) -> impl Iterator<Item = RegionVid> {
self.points.as_ref().expect("use with_specific_points").rows()
self.points().rows()
}

/// Iterate through each region that has a value in this set.
// We are passing query instability implications to the caller.
#[rustc_lint_query_instability]
#[allow(rustc::potential_query_instability)]
pub(crate) fn live_regions_unordered(&self) -> impl Iterator<Item = RegionVid> {
self.live_regions.as_ref().unwrap().iter().copied()
if let LiveRegions::InBody(live_regions) = &self.live_regions {
live_regions.iter().copied()
} else {
bug!("this `LivenessValues` wasn't created using `without_specific_points`")
}
}

/// Records `region` as being live at the given `location`.
pub(crate) fn add_location(&mut self, region: RegionVid, location: Location) {
let point = self.location_map.point_from_location(location);
debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location);
if let Some(points) = &mut self.points {
points.insert(region, point);
} else if self.location_map.point_in_range(point) {
self.live_regions.as_mut().unwrap().insert(region);
}
match &mut self.live_regions {
LiveRegions::AtPoints(points) => {
points.insert(region, point);
}

LiveRegions::InBody(live_regions) if self.location_map.point_in_range(point) => {
live_regions.insert(region);
}

LiveRegions::InBody(_) => (),
};
}

/// Records `region` as being live at all the given `points`.
pub(crate) fn add_points(&mut self, region: RegionVid, points: &IntervalSet<PointIndex>) {
debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points);
if let Some(this) = &mut self.points {
this.union_row(region, points);
} else if points.iter().any(|point| self.location_map.point_in_range(point)) {
self.live_regions.as_mut().unwrap().insert(region);
}
match &mut self.live_regions {
LiveRegions::AtPoints(these_points) => {
these_points.union_row(region, points);
}
LiveRegions::InBody(live_regions)
if points.iter().any(|point| self.location_map.point_in_range(point)) =>
{
live_regions.insert(region);
}
LiveRegions::InBody(_) => (),
};
}

/// Records `region` as being live at all the control-flow points.
pub(crate) fn add_all_points(&mut self, region: RegionVid) {
if let Some(points) = &mut self.points {
points.insert_all_into_row(region);
} else {
self.live_regions.as_mut().unwrap().insert(region);
match &mut self.live_regions {
LiveRegions::AtPoints(points) => points.insert_all_into_row(region),
LiveRegions::InBody(live_regions) => {
live_regions.insert(region);
}
}
}

Expand All @@ -142,23 +166,12 @@ impl LivenessValues {
/// [`point`][rustc_mir_dataflow::points::PointIndex].
#[inline]
pub(crate) fn is_live_at_point(&self, region: RegionVid, point: PointIndex) -> bool {
if let Some(points) = &self.points {
points.row(region).is_some_and(|r| r.contains(point))
} else {
unreachable!(
"Should be using LivenessValues::with_specific_points to ask whether live at a location"
)
}
self.points().row(region).is_some_and(|r| r.contains(point))
}

/// Returns an iterator of all the points where `region` is live.
fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> {
let Some(points) = &self.points else {
unreachable!(
"Should be using LivenessValues::with_specific_points to ask whether live at a location"
)
};
points
self.points()
.row(region)
.into_iter()
.flat_map(|set| set.iter())
Expand Down Expand Up @@ -328,10 +341,7 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
/// elements for the region `from` from `values` and add them to
/// the region `to` in `self`.
pub(crate) fn merge_liveness(&mut self, to: N, from: RegionVid, values: &LivenessValues) {
let Some(value_points) = &values.points else {
panic!("LivenessValues must track specific points for use in merge_liveness");
};
if let Some(set) = value_points.row(from) {
if let Some(set) = values.points().row(from) {
self.points.union_row(to, set);
}
}
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,14 +844,13 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
// current number of evaluated terminators is a power of 2. The latter gives us a cheap
// way to implement exponential backoff.
let span = ecx.cur_span();
let mut warn =
ecx.tcx.dcx().create_warn(LongRunningWarn { span, item_span: ecx.tcx.span });
// We store a unique number in `force_duplicate` to evade `-Z deduplicate-diagnostics`.
// `new_steps` is guaranteed to be unique because `ecx.machine.num_evaluated_steps` is
// always increasing.
ecx.tcx.dcx().emit_warn(LongRunningWarn {
span,
item_span: ecx.tcx.span,
force_duplicate: new_steps,
});
warn.arg("force_duplicate", new_steps);
warn.emit();
}
}

Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_const_eval/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,6 @@ pub(crate) struct LongRunningWarn {
pub span: Span,
#[help("the constant being evaluated")]
pub item_span: Span,
// Used for evading `-Z deduplicate-diagnostics`.
pub force_duplicate: usize,
}

#[derive(Subdiagnostic)]
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut path = None;
let mut err = self.dcx().create_err(errors::InvalidCallee {
span: callee_expr.span,
ty: callee_ty,
found: match &unit_variant {
Some((_, kind, path)) => format!("{kind} `{path}`"),
None => format!("`{}`", self.tcx.short_string(callee_ty, &mut path)),
Expand Down Expand Up @@ -949,7 +948,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

if let Some(span) = self.tcx.hir_res_span(def) {
let callee_ty = callee_ty.to_string();
let label = match (unit_variant, inner_callee_path) {
(Some((_, kind, path)), _) => {
err.arg("kind", kind);
Expand All @@ -959,6 +957,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(_, Some(hir::QPath::Resolved(_, path))) => {
self.tcx.sess.source_map().span_to_snippet(path.span).ok().map(|p| {
err.arg("func", p);
err.arg("ty", callee_ty);
msg!("`{$func}` defined here returns `{$ty}`")
})
}
Expand All @@ -968,14 +967,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// type definitions themselves, but rather variables *of* that type.
Res::Local(hir_id) => {
err.arg("local_name", self.tcx.hir_name(hir_id));
err.arg("ty", callee_ty);
Some(msg!("`{$local_name}` has type `{$ty}`"))
}
Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
err.arg("path", self.tcx.def_path_str(def_id));
Some(msg!("`{$path}` defined here"))
}
_ => {
err.arg("path", callee_ty);
err.arg("path", callee_ty.to_string());
Some(msg!("`{$path}` defined here"))
}
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,9 @@ pub(crate) struct SlicingSuggestion {

#[derive(Diagnostic)]
#[diag("expected function, found {$found}", code = E0618)]
pub(crate) struct InvalidCallee<'tcx> {
pub(crate) struct InvalidCallee {
#[primary_span]
pub span: Span,
pub ty: Ty<'tcx>,
pub found: String,
}

Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1562,17 +1562,16 @@ pub(crate) enum NonCamelCaseTypeSub {
pub(crate) struct NonSnakeCaseDiag<'a> {
pub sort: &'a str,
pub name: &'a str,
pub sc: String,
#[subdiagnostic]
pub sub: NonSnakeCaseDiagSub,
}

pub(crate) enum NonSnakeCaseDiagSub {
Label { span: Span },
Help,
Help { sc: String },
RenameOrConvertSuggestion { span: Span, suggestion: Ident },
ConvertSuggestion { span: Span, suggestion: String },
SuggestionAndNote { span: Span },
SuggestionAndNote { sc: String, span: Span },
}

impl Subdiagnostic for NonSnakeCaseDiagSub {
Expand All @@ -1581,7 +1580,8 @@ impl Subdiagnostic for NonSnakeCaseDiagSub {
NonSnakeCaseDiagSub::Label { span } => {
diag.span_label(span, msg!("should have a snake_case name"));
}
NonSnakeCaseDiagSub::Help => {
NonSnakeCaseDiagSub::Help { sc } => {
diag.arg("sc", sc);
diag.help(msg!("convert the identifier to snake case: `{$sc}`"));
}
NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
Expand All @@ -1600,7 +1600,8 @@ impl Subdiagnostic for NonSnakeCaseDiagSub {
Applicability::MaybeIncorrect,
);
}
NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
NonSnakeCaseDiagSub::SuggestionAndNote { sc, span } => {
diag.arg("sc", sc);
diag.note(msg!("`{$sc}` cannot be used as a raw identifier"));
diag.span_suggestion(
span,
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_lint/src/nonstandard_style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,18 +311,18 @@ impl NonSnakeCase {
suggestion: sc_ident,
}
} else {
NonSnakeCaseDiagSub::SuggestionAndNote { span }
NonSnakeCaseDiagSub::SuggestionAndNote { sc, span }
}
} else {
NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion: sc.clone() }
NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion: sc }
}
} else {
NonSnakeCaseDiagSub::Help
NonSnakeCaseDiagSub::Help { sc }
}
} else {
NonSnakeCaseDiagSub::Label { span }
};
cx.emit_span_lint(NON_SNAKE_CASE, span, NonSnakeCaseDiag { sort, name, sc, sub });
cx.emit_span_lint(NON_SNAKE_CASE, span, NonSnakeCaseDiag { sort, name, sub });
}
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,5 @@ struct OpaqueHiddenInferredBoundLint<'tcx> {
struct AddBound<'tcx> {
#[primary_span]
suggest_span: Span,
#[skip_arg]
trait_ref: TraitPredPrintModifiersAndPath<'tcx>,
}
2 changes: 1 addition & 1 deletion compiler/rustc_macros/src/diagnostics/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<'a> DiagnosticDerive<'a> {
let Some(message) = builder.primary_message() else {
return DiagnosticDeriveError::ErrorHandled.to_compile_error();
};
let message = message.diag_message(Some(variant));
let message = message.diag_message();

let init = quote! {
let mut diag = rustc_errors::Diag::new(
Expand Down
Loading
Loading