Skip to content

Commit

Permalink
Auto merge of rust-lang#138357 - lcnr:goodbye-TypeVerifier-rarw, r=<try>
Browse files Browse the repository at this point in the history
merge `TypeChecker` and `TypeVerifier`

Stacked on top of rust-lang#138354. Best reviewed commit by commit.

r? `@compiler-errors`
  • Loading branch information
bors committed Mar 11, 2025
2 parents ebf0cf7 + a5eb387 commit 93da1b8
Show file tree
Hide file tree
Showing 6 changed files with 1,146 additions and 1,275 deletions.
54 changes: 26 additions & 28 deletions compiler/rustc_borrowck/src/type_check/input_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ use crate::universal_regions::DefiningTy;
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
/// Check explicit closure signature annotation,
/// e.g., `|x: FxIndexMap<_, &'static u32>| ...`.
#[instrument(skip(self, body), level = "debug")]
pub(super) fn check_signature_annotation(&mut self, body: &Body<'tcx>) {
let mir_def_id = body.source.def_id().expect_local();
#[instrument(skip(self), level = "debug")]
pub(super) fn check_signature_annotation(&mut self) {
let mir_def_id = self.body.source.def_id().expect_local();

if !self.tcx().is_closure_like(mir_def_id.to_def_id()) {
return;
Expand All @@ -38,9 +38,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// (e.g., the `_` in the code above) with fresh variables.
// Then replace the bound items in the fn sig with fresh variables,
// so that they represent the view from "inside" the closure.
let user_provided_sig = self.instantiate_canonical(body.span, &user_provided_poly_sig);
let user_provided_sig = self.instantiate_canonical(self.body.span, &user_provided_poly_sig);
let mut user_provided_sig = self.infcx.instantiate_binder_with_fresh_vars(
body.span,
self.body.span,
BoundRegionConversionTime::FnCall,
user_provided_sig,
);
Expand All @@ -66,12 +66,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Ty::new_tup(self.tcx(), user_provided_sig.inputs()),
args.tupled_upvars_ty(),
args.coroutine_captures_by_ref_ty(),
self.infcx.next_region_var(RegionVariableOrigin::MiscVariable(body.span), || {
RegionCtxt::Unknown
}),
self.infcx
.next_region_var(RegionVariableOrigin::MiscVariable(self.body.span), || {
RegionCtxt::Unknown
}),
);

let next_ty_var = || self.infcx.next_ty_var(body.span);
let next_ty_var = || self.infcx.next_ty_var(self.body.span);
let output_ty = Ty::new_coroutine(
self.tcx(),
self.tcx().coroutine_for_closure(mir_def_id),
Expand Down Expand Up @@ -107,9 +108,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
for (&user_ty, arg_decl) in user_provided_sig.inputs().iter().zip_eq(
// In MIR, closure args begin with an implicit `self`.
// Also, coroutines have a resume type which may be implicitly `()`.
body.args_iter()
self.body
.args_iter()
.skip(1 + if is_coroutine_with_implicit_resume_ty { 1 } else { 0 })
.map(|local| &body.local_decls[local]),
.map(|local| &self.body.local_decls[local]),
) {
self.ascribe_user_type_skip_wf(
arg_decl.ty,
Expand All @@ -119,20 +121,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}

// If the user explicitly annotated the output type, enforce it.
let output_decl = &body.local_decls[RETURN_PLACE];
let output_decl = &self.body.local_decls[RETURN_PLACE];
self.ascribe_user_type_skip_wf(
output_decl.ty,
ty::UserType::new(ty::UserTypeKind::Ty(user_provided_sig.output())),
output_decl.source_info.span,
);
}

#[instrument(skip(self, body), level = "debug")]
pub(super) fn equate_inputs_and_outputs(
&mut self,
body: &Body<'tcx>,
normalized_inputs_and_output: &[Ty<'tcx>],
) {
#[instrument(skip(self), level = "debug")]
pub(super) fn equate_inputs_and_outputs(&mut self, normalized_inputs_and_output: &[Ty<'tcx>]) {
let (&normalized_output_ty, normalized_input_tys) =
normalized_inputs_and_output.split_last().unwrap();

Expand All @@ -141,36 +139,36 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

// Equate expected input tys with those in the MIR.
for (argument_index, &normalized_input_ty) in normalized_input_tys.iter().enumerate() {
if argument_index + 1 >= body.local_decls.len() {
if argument_index + 1 >= self.body.local_decls.len() {
self.tcx()
.dcx()
.span_bug(body.span, "found more normalized_input_ty than local_decls");
.span_bug(self.body.span, "found more normalized_input_ty than local_decls");
}

// In MIR, argument N is stored in local N+1.
let local = Local::from_usize(argument_index + 1);

let mir_input_ty = body.local_decls[local].ty;
let mir_input_ty = self.body.local_decls[local].ty;

let mir_input_span = body.local_decls[local].source_info.span;
let mir_input_span = self.body.local_decls[local].source_info.span;
self.equate_normalized_input_or_output(
normalized_input_ty,
mir_input_ty,
mir_input_span,
);
}

if let Some(mir_yield_ty) = body.yield_ty() {
let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
if let Some(mir_yield_ty) = self.body.yield_ty() {
let yield_span = self.body.local_decls[RETURN_PLACE].source_info.span;
self.equate_normalized_input_or_output(
self.universal_regions.yield_ty.unwrap(),
mir_yield_ty,
yield_span,
);
}

if let Some(mir_resume_ty) = body.resume_ty() {
let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
if let Some(mir_resume_ty) = self.body.resume_ty() {
let yield_span = self.body.local_decls[RETURN_PLACE].source_info.span;
self.equate_normalized_input_or_output(
self.universal_regions.resume_ty.unwrap(),
mir_resume_ty,
Expand All @@ -179,8 +177,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}

// Return types are a bit more complex. They may contain opaque `impl Trait` types.
let mir_output_ty = body.local_decls[RETURN_PLACE].ty;
let output_span = body.local_decls[RETURN_PLACE].source_info.span;
let mir_output_ty = self.body.local_decls[RETURN_PLACE].ty;
let output_span = self.body.local_decls[RETURN_PLACE].source_info.span;
self.equate_normalized_input_or_output(normalized_output_ty, mir_output_ty, output_span);
}

Expand Down
20 changes: 6 additions & 14 deletions compiler/rustc_borrowck/src/type_check/liveness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ mod trace;
/// performed before
pub(super) fn generate<'a, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>,
location_map: &DenseLocationMap,
flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>,
Expand All @@ -51,23 +50,16 @@ pub(super) fn generate<'a, 'tcx>(
// We do record these regions in the polonius context, since they're used to differentiate
// relevant and boring locals, which is a key distinction used later in diagnostics.
if typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() {
let (_, boring_locals) = compute_relevant_live_locals(typeck.tcx(), &free_regions, body);
let (_, boring_locals) =
compute_relevant_live_locals(typeck.tcx(), &free_regions, typeck.body);
typeck.polonius_liveness.as_mut().unwrap().boring_nll_locals =
boring_locals.into_iter().collect();
free_regions = typeck.universal_regions.universal_regions_iter().collect();
}
let (relevant_live_locals, boring_locals) =
compute_relevant_live_locals(typeck.tcx(), &free_regions, body);

trace::trace(
typeck,
body,
location_map,
flow_inits,
move_data,
relevant_live_locals,
boring_locals,
);
compute_relevant_live_locals(typeck.tcx(), &free_regions, typeck.body);

trace::trace(typeck, location_map, flow_inits, move_data, relevant_live_locals, boring_locals);

// Mark regions that should be live where they appear within rvalues or within a call: like
// args, regions, and types.
Expand All @@ -76,7 +68,7 @@ pub(super) fn generate<'a, 'tcx>(
&mut typeck.constraints.liveness_constraints,
&typeck.universal_regions,
&mut typeck.polonius_liveness,
body,
typeck.body,
);
}

Expand Down
42 changes: 21 additions & 21 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,15 @@ use crate::type_check::{NormalizeLocation, TypeChecker};
/// this respects `#[may_dangle]` annotations).
pub(super) fn trace<'a, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>,
location_map: &DenseLocationMap,
flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>,
relevant_live_locals: Vec<Local>,
boring_locals: Vec<Local>,
) {
let local_use_map = &LocalUseMap::build(&relevant_live_locals, location_map, body);
let local_use_map = &LocalUseMap::build(&relevant_live_locals, location_map, typeck.body);
let cx = LivenessContext {
typeck,
body,
flow_inits,
location_map,
local_use_map,
Expand All @@ -69,14 +67,13 @@ pub(super) fn trace<'a, 'tcx>(
/// Contextual state for the type-liveness coroutine.
struct LivenessContext<'a, 'typeck, 'b, 'tcx> {
/// Current type-checker, giving us our inference context etc.
///
/// This also stores the body we're currently analyzing.
typeck: &'a mut TypeChecker<'typeck, 'tcx>,

/// Defines the `PointIndex` mapping
location_map: &'a DenseLocationMap,

/// MIR we are analyzing.
body: &'a Body<'tcx>,

/// Mapping to/from the various indices used for initialization tracking.
move_data: &'a MoveData<'tcx>,

Expand Down Expand Up @@ -139,7 +136,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
self.compute_use_live_points_for(local);
self.compute_drop_live_points_for(local);

let local_ty = self.cx.body.local_decls[local].ty;
let local_ty = self.cx.body().local_decls[local].ty;

if !self.use_live_at.is_empty() {
self.cx.add_use_live_facts_for(local_ty, &self.use_live_at);
Expand All @@ -164,16 +161,16 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
/// and can therefore safely be dropped.
fn dropck_boring_locals(&mut self, boring_locals: Vec<Local>) {
for local in boring_locals {
let local_ty = self.cx.body.local_decls[local].ty;
let local_span = self.cx.body.local_decls[local].source_info.span;
let local_ty = self.cx.body().local_decls[local].ty;
let local_span = self.cx.body().local_decls[local].source_info.span;
let drop_data = self.cx.drop_data.entry(local_ty).or_insert_with({
let typeck = &self.cx.typeck;
move || LivenessContext::compute_drop_data(typeck, local_ty, local_span)
});

drop_data.dropck_result.report_overflows(
self.cx.typeck.infcx.tcx,
self.cx.body.local_decls[local].source_info.span,
self.cx.typeck.body.local_decls[local].source_info.span,
local_ty,
);
}
Expand Down Expand Up @@ -202,7 +199,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
.var_dropped_at
.iter()
.filter_map(|&(local, location_index)| {
let local_ty = self.cx.body.local_decls[local].ty;
let local_ty = self.cx.body().local_decls[local].ty;
if relevant_live_locals.contains(&local) || !local_ty.has_free_regions() {
return None;
}
Expand Down Expand Up @@ -278,9 +275,9 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {

let block = self.cx.location_map.to_location(block_start).block;
self.stack.extend(
self.cx.body.basic_blocks.predecessors()[block]
self.cx.body().basic_blocks.predecessors()[block]
.iter()
.map(|&pred_bb| self.cx.body.terminator_loc(pred_bb))
.map(|&pred_bb| self.cx.body().terminator_loc(pred_bb))
.map(|pred_loc| self.cx.location_map.point_from_location(pred_loc)),
);
}
Expand All @@ -305,7 +302,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
// Find the drops where `local` is initialized.
for drop_point in self.cx.local_use_map.drops(local) {
let location = self.cx.location_map.to_location(drop_point);
debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,);
debug_assert_eq!(self.cx.body().terminator_loc(location.block), location,);

if self.cx.initialized_at_terminator(location.block, mpi)
&& self.drop_live_at.insert(drop_point)
Expand Down Expand Up @@ -351,7 +348,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
// block. One of them may be either a definition or use
// live point.
let term_location = self.cx.location_map.to_location(term_point);
debug_assert_eq!(self.cx.body.terminator_loc(term_location.block), term_location,);
debug_assert_eq!(self.cx.body().terminator_loc(term_location.block), term_location,);
let block = term_location.block;
let entry_point = self.cx.location_map.entry_point(term_location.block);
for p in (entry_point..term_point).rev() {
Expand All @@ -376,7 +373,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
}
}

let body = self.cx.body;
let body = self.cx.typeck.body;
for &pred_block in body.basic_blocks.predecessors()[block].iter() {
debug!("compute_drop_live_points_for_block: pred_block = {:?}", pred_block,);

Expand All @@ -403,7 +400,7 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
continue;
}

let pred_term_loc = self.cx.body.terminator_loc(pred_block);
let pred_term_loc = self.cx.body().terminator_loc(pred_block);
let pred_term_point = self.cx.location_map.point_from_location(pred_term_loc);

// If the terminator of this predecessor either *assigns*
Expand Down Expand Up @@ -463,6 +460,9 @@ impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
}

impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
fn body(&self) -> &Body<'tcx> {
self.typeck.body
}
/// Returns `true` if the local variable (or some part of it) is initialized at the current
/// cursor position. Callers should call one of the `seek` methods immediately before to point
/// the cursor to the desired location.
Expand All @@ -481,7 +481,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
/// DROP of some local variable will have an effect -- note that
/// drops, as they may unwind, are always terminators.
fn initialized_at_terminator(&mut self, block: BasicBlock, mpi: MovePathIndex) -> bool {
self.flow_inits.seek_before_primary_effect(self.body.terminator_loc(block));
self.flow_inits.seek_before_primary_effect(self.body().terminator_loc(block));
self.initialized_at_curr_loc(mpi)
}

Expand All @@ -491,7 +491,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
/// **Warning:** Does not account for the result of `Call`
/// instructions.
fn initialized_at_exit(&mut self, block: BasicBlock, mpi: MovePathIndex) -> bool {
self.flow_inits.seek_after_primary_effect(self.body.terminator_loc(block));
self.flow_inits.seek_after_primary_effect(self.body().terminator_loc(block));
self.initialized_at_curr_loc(mpi)
}

Expand Down Expand Up @@ -526,7 +526,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
values::pretty_print_points(self.location_map, live_at.iter()),
);

let local_span = self.body.local_decls()[dropped_local].source_info.span;
let local_span = self.body().local_decls()[dropped_local].source_info.span;
let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({
let typeck = &self.typeck;
move || Self::compute_drop_data(typeck, dropped_ty, local_span)
Expand All @@ -544,7 +544,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {

drop_data.dropck_result.report_overflows(
self.typeck.infcx.tcx,
self.body.source_info(*drop_locations.first().unwrap()).span,
self.typeck.body.source_info(*drop_locations.first().unwrap()).span,
dropped_ty,
);

Expand Down
Loading

0 comments on commit 93da1b8

Please sign in to comment.