Skip to content

Commit 17ac2fc

Browse files
committed
change HIR typeck unification handling approach
1 parent 831e291 commit 17ac2fc

File tree

25 files changed

+168
-128
lines changed

25 files changed

+168
-128
lines changed

compiler/rustc_borrowck/src/lib.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ fn do_mir_borrowck<'tcx>(
300300
def: LocalDefId,
301301
) -> PropagatedBorrowCheckResults<'tcx> {
302302
let tcx = root_cx.tcx;
303-
let infcx = BorrowckInferCtxt::new(tcx, def);
303+
let infcx = BorrowckInferCtxt::new(tcx, def, root_cx.root_def_id());
304304
let (input_body, promoted) = tcx.mir_promoted(def);
305305
let input_body: &Body<'_> = &input_body.borrow();
306306
let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
@@ -590,20 +590,26 @@ fn get_flow_results<'a, 'tcx>(
590590

591591
pub(crate) struct BorrowckInferCtxt<'tcx> {
592592
pub(crate) infcx: InferCtxt<'tcx>,
593-
pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>,
593+
pub(crate) root_def_id: LocalDefId,
594594
pub(crate) param_env: ParamEnv<'tcx>,
595+
pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>,
595596
}
596597

597598
impl<'tcx> BorrowckInferCtxt<'tcx> {
598-
pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
599+
pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, root_def_id: LocalDefId) -> Self {
599600
let typing_mode = if tcx.use_typing_mode_borrowck() {
600601
TypingMode::borrowck(tcx, def_id)
601602
} else {
602603
TypingMode::analysis_in_body(tcx, def_id)
603604
};
604605
let infcx = tcx.infer_ctxt().build(typing_mode);
605606
let param_env = tcx.param_env(def_id);
606-
BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()), param_env }
607+
BorrowckInferCtxt {
608+
infcx,
609+
root_def_id,
610+
reg_var_to_origin: RefCell::new(Default::default()),
611+
param_env,
612+
}
607613
}
608614

609615
pub(crate) fn next_region_var<F>(

compiler/rustc_borrowck/src/root_cx.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
3838
}
3939
}
4040

41+
pub(super) fn root_def_id(&self) -> LocalDefId {
42+
self.root_def_id
43+
}
44+
4145
/// Collect all defining uses of opaque types inside of this typeck root. This
4246
/// expects the hidden type to be mapped to the definition parameters of the opaque
4347
/// and errors if we end up with distinct hidden types.

compiler/rustc_borrowck/src/type_check/canonical.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ where
3939
let old_universe = infcx.universe();
4040

4141
let TypeOpOutput { output, constraints: query_constraints, error_info } =
42-
op.fully_perform(infcx, locations.span(body))?;
42+
op.fully_perform(infcx, infcx.root_def_id, locations.span(body))?;
4343
if cfg!(debug_assertions) {
4444
let data = infcx.take_and_reset_region_constraints();
4545
if !data.is_empty() {
@@ -54,7 +54,6 @@ where
5454
infcx,
5555
universal_regions,
5656
region_bound_pairs,
57-
infcx.param_env,
5857
known_type_outlives_obligations,
5958
locations,
6059
locations.span(body),

compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use rustc_data_structures::fx::FxHashSet;
22
use rustc_hir::def_id::LocalDefId;
3+
use rustc_infer::infer::SubregionOrigin;
34
use rustc_infer::infer::canonical::QueryRegionConstraints;
45
use rustc_infer::infer::outlives::env::RegionBoundPairs;
56
use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
67
use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
7-
use rustc_infer::infer::{InferCtxt, SubregionOrigin};
88
use rustc_infer::traits::query::type_op::DeeplyNormalize;
99
use rustc_middle::bug;
1010
use rustc_middle::ty::{
@@ -18,10 +18,12 @@ use crate::constraints::OutlivesConstraint;
1818
use crate::region_infer::TypeTest;
1919
use crate::type_check::{Locations, MirTypeckRegionConstraints};
2020
use crate::universal_regions::UniversalRegions;
21-
use crate::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
21+
use crate::{
22+
BorrowckInferCtxt, ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory,
23+
};
2224

2325
pub(crate) struct ConstraintConversion<'a, 'tcx> {
24-
infcx: &'a InferCtxt<'tcx>,
26+
infcx: &'a BorrowckInferCtxt<'tcx>,
2527
universal_regions: &'a UniversalRegions<'tcx>,
2628
/// Each RBP `GK: 'a` is assumed to be true. These encode
2729
/// relationships like `T: 'a` that are added via implicit bounds
@@ -34,7 +36,6 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
3436
/// logic expecting to see (e.g.) `ReStatic`, and if we supplied
3537
/// our special inference variable there, we would mess that up.
3638
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
37-
param_env: ty::ParamEnv<'tcx>,
3839
known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>],
3940
locations: Locations,
4041
span: Span,
@@ -45,10 +46,9 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
4546

4647
impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
4748
pub(crate) fn new(
48-
infcx: &'a InferCtxt<'tcx>,
49+
infcx: &'a BorrowckInferCtxt<'tcx>,
4950
universal_regions: &'a UniversalRegions<'tcx>,
5051
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
51-
param_env: ty::ParamEnv<'tcx>,
5252
known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>],
5353
locations: Locations,
5454
span: Span,
@@ -59,7 +59,6 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
5959
infcx,
6060
universal_regions,
6161
region_bound_pairs,
62-
param_env,
6362
known_type_outlives_obligations,
6463
locations,
6564
span,
@@ -286,8 +285,11 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
286285
ConstraintCategory<'tcx>,
287286
)>,
288287
) -> Ty<'tcx> {
289-
match self.param_env.and(DeeplyNormalize { value: ty }).fully_perform(self.infcx, self.span)
290-
{
288+
match self.infcx.param_env.and(DeeplyNormalize { value: ty }).fully_perform(
289+
self.infcx,
290+
self.infcx.root_def_id,
291+
self.span,
292+
) {
291293
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
292294
// FIXME(higher_ranked_auto): What should we do with the assumptions here?
293295
if let Some(QueryRegionConstraints { outlives, assumptions: _ }) = constraints {

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use rustc_data_structures::frozen::Frozen;
22
use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder};
33
use rustc_hir::def::DefKind;
44
use rustc_infer::infer::canonical::QueryRegionConstraints;
5+
use rustc_infer::infer::outlives;
56
use rustc_infer::infer::outlives::env::RegionBoundPairs;
67
use rustc_infer::infer::region_constraints::GenericKind;
7-
use rustc_infer::infer::{InferCtxt, outlives};
88
use rustc_infer::traits::query::type_op::DeeplyNormalize;
99
use rustc_middle::mir::ConstraintCategory;
1010
use rustc_middle::traits::query::OutlivesBound;
@@ -14,6 +14,7 @@ use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
1414
use tracing::{debug, instrument};
1515
use type_op::TypeOpOutput;
1616

17+
use crate::BorrowckInferCtxt;
1718
use crate::type_check::{Locations, MirTypeckRegionConstraints, constraint_conversion};
1819
use crate::universal_regions::UniversalRegions;
1920

@@ -47,14 +48,12 @@ pub(crate) struct CreateResult<'tcx> {
4748
}
4849

4950
pub(crate) fn create<'tcx>(
50-
infcx: &InferCtxt<'tcx>,
51-
param_env: ty::ParamEnv<'tcx>,
51+
infcx: &BorrowckInferCtxt<'tcx>,
5252
universal_regions: UniversalRegions<'tcx>,
5353
constraints: &mut MirTypeckRegionConstraints<'tcx>,
5454
) -> CreateResult<'tcx> {
5555
UniversalRegionRelationsBuilder {
5656
infcx,
57-
param_env,
5857
constraints,
5958
universal_regions,
6059
region_bound_pairs: Default::default(),
@@ -177,8 +176,7 @@ impl UniversalRegionRelations<'_> {
177176
}
178177

179178
struct UniversalRegionRelationsBuilder<'a, 'tcx> {
180-
infcx: &'a InferCtxt<'tcx>,
181-
param_env: ty::ParamEnv<'tcx>,
179+
infcx: &'a BorrowckInferCtxt<'tcx>,
182180
universal_regions: UniversalRegions<'tcx>,
183181
constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
184182

@@ -205,7 +203,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
205203

206204
// Insert the `'a: 'b` we know from the predicates.
207205
// This does not consider the type-outlives.
208-
let param_env = self.param_env;
206+
let param_env = self.infcx.param_env;
209207
self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
210208

211209
// - outlives is reflexive, so `'r: 'r` for every region `'r`
@@ -263,7 +261,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
263261
let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } =
264262
param_env
265263
.and(DeeplyNormalize { value: ty })
266-
.fully_perform(self.infcx, span)
264+
.fully_perform(self.infcx, self.infcx.root_def_id, span)
267265
.unwrap_or_else(|guar| TypeOpOutput {
268266
output: Ty::new_error(self.infcx.tcx, guar),
269267
constraints: None,
@@ -298,8 +296,9 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
298296
// Add implied bounds from impl header.
299297
if matches!(tcx.def_kind(defining_ty_def_id), DefKind::AssocFn | DefKind::AssocConst) {
300298
for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) {
301-
let result: Result<_, ErrorGuaranteed> =
302-
param_env.and(DeeplyNormalize { value: ty }).fully_perform(self.infcx, span);
299+
let result: Result<_, ErrorGuaranteed> = param_env
300+
.and(DeeplyNormalize { value: ty })
301+
.fully_perform(self.infcx, self.infcx.root_def_id, span);
303302
let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else {
304303
continue;
305304
};
@@ -318,7 +317,6 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
318317
self.infcx,
319318
&self.universal_regions,
320319
&self.region_bound_pairs,
321-
param_env,
322320
&known_type_outlives_obligations,
323321
Locations::All(span),
324322
span,
@@ -353,10 +351,11 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
353351
output: normalized_outlives,
354352
constraints: constraints_normalize,
355353
error_info: _,
356-
}) = self
357-
.param_env
358-
.and(DeeplyNormalize { value: outlives })
359-
.fully_perform(self.infcx, span)
354+
}) = self.infcx.param_env.and(DeeplyNormalize { value: outlives }).fully_perform(
355+
self.infcx,
356+
self.infcx.root_def_id,
357+
span,
358+
)
360359
else {
361360
self.infcx.dcx().delayed_bug(format!("could not normalize {outlives:?}"));
362361
return;
@@ -381,9 +380,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
381380
span: Span,
382381
) -> Option<&'tcx QueryRegionConstraints<'tcx>> {
383382
let TypeOpOutput { output: bounds, constraints, .. } = self
383+
.infcx
384384
.param_env
385385
.and(type_op::ImpliedOutlivesBounds { ty })
386-
.fully_perform(self.infcx, span)
386+
.fully_perform(self.infcx, self.infcx.root_def_id, span)
387387
.map_err(|_: ErrorGuaranteed| debug!("failed to compute implied bounds {:?}", ty))
388388
.ok()?;
389389
debug!(?bounds, ?constraints);

compiler/rustc_borrowck/src/type_check/liveness/trace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> {
640640

641641
let op = typeck.infcx.param_env.and(DropckOutlives { dropped_ty });
642642

643-
match op.fully_perform(typeck.infcx, DUMMY_SP) {
643+
match op.fully_perform(typeck.infcx, typeck.root_cx.root_def_id(), DUMMY_SP) {
644644
Ok(TypeOpOutput { output, constraints, .. }) => {
645645
DropData { dropck_result: output, region_constraint_data: constraints }
646646
}

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pub(crate) fn type_check<'tcx>(
120120
region_bound_pairs,
121121
normalized_inputs_and_output,
122122
known_type_outlives_obligations,
123-
} = free_region_relations::create(infcx, infcx.param_env, universal_regions, &mut constraints);
123+
} = free_region_relations::create(infcx, universal_regions, &mut constraints);
124124

125125
let pre_obligations = infcx.take_registered_region_obligations();
126126
assert!(
@@ -408,7 +408,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
408408
self.infcx,
409409
self.universal_regions,
410410
self.region_bound_pairs,
411-
self.infcx.param_env,
412411
self.known_type_outlives_obligations,
413412
locations,
414413
locations.span(self.body),
@@ -2458,12 +2457,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24582457
args: GenericArgsRef<'tcx>,
24592458
locations: Locations,
24602459
) -> ty::InstantiatedPredicates<'tcx> {
2460+
let root_def_id = self.root_cx.root_def_id();
24612461
if let Some(closure_requirements) = &self.root_cx.closure_requirements(def_id) {
24622462
constraint_conversion::ConstraintConversion::new(
24632463
self.infcx,
24642464
self.universal_regions,
24652465
self.region_bound_pairs,
2466-
self.infcx.param_env,
24672466
self.known_type_outlives_obligations,
24682467
locations,
24692468
self.body.span, // irrelevant; will be overridden.
@@ -2473,9 +2472,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
24732472
.apply_closure_requirements(closure_requirements, def_id, args);
24742473
}
24752474

2476-
// Now equate closure args to regions inherited from `typeck_root_def_id`. Fixes #98589.
2477-
let typeck_root_def_id = tcx.typeck_root_def_id(self.body.source.def_id());
2478-
let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id);
2475+
// Now equate closure args to regions inherited from `root_def_id`. Fixes #98589.
2476+
let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, root_def_id);
24792477

24802478
let parent_args = match tcx.def_kind(def_id) {
24812479
// We don't want to dispatch on 3 different kind of closures here, so take
@@ -2550,17 +2548,14 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {
25502548
fn fully_perform(
25512549
mut self,
25522550
infcx: &InferCtxt<'tcx>,
2551+
root_def_id: LocalDefId,
25532552
span: Span,
25542553
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
2555-
let (mut output, region_constraints) = scrape_region_constraints(
2556-
infcx,
2557-
|ocx| {
2554+
let (mut output, region_constraints) =
2555+
scrape_region_constraints(infcx, root_def_id, "InstantiateOpaqueType", span, |ocx| {
25582556
ocx.register_obligations(self.obligations.clone());
25592557
Ok(())
2560-
},
2561-
"InstantiateOpaqueType",
2562-
span,
2563-
)?;
2558+
})?;
25642559
self.region_constraints = Some(region_constraints);
25652560
output.error_info = Some(self);
25662561
Ok(output)

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,3 +2053,29 @@ pub(super) fn check_coroutine_obligations(
20532053

20542054
Ok(())
20552055
}
2056+
2057+
pub(super) fn check_potentially_region_dependent_goals<'tcx>(
2058+
tcx: TyCtxt<'tcx>,
2059+
def_id: LocalDefId,
2060+
) -> Result<(), ErrorGuaranteed> {
2061+
if !tcx.next_trait_solver_globally() {
2062+
return Ok(());
2063+
}
2064+
let typeck_results = tcx.typeck(def_id);
2065+
let param_env = tcx.param_env(def_id);
2066+
2067+
// We use `TypingMode::Borrowck` as we want to use the opaque types computed by HIR typeck.
2068+
let typing_mode = TypingMode::borrowck(tcx, def_id);
2069+
let infcx = tcx.infer_ctxt().ignoring_regions().build(typing_mode);
2070+
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
2071+
for (predicate, cause) in &typeck_results.potentially_region_dependent_goals {
2072+
let predicate = fold_regions(tcx, *predicate, |_, _| {
2073+
infcx.next_region_var(RegionVariableOrigin::Misc(cause.span))
2074+
});
2075+
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate));
2076+
}
2077+
2078+
let errors = ocx.select_all_or_error();
2079+
debug!(?errors);
2080+
if errors.is_empty() { Ok(()) } else { Err(infcx.err_ctxt().report_fulfillment_errors(errors)) }
2081+
}

compiler/rustc_hir_analysis/src/check/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ pub(super) fn provide(providers: &mut Providers) {
109109
collect_return_position_impl_trait_in_trait_tys,
110110
compare_impl_item: compare_impl_item::compare_impl_item,
111111
check_coroutine_obligations: check::check_coroutine_obligations,
112+
check_potentially_region_dependent_goals: check::check_potentially_region_dependent_goals,
112113
check_type_wf: wfcheck::check_type_wf,
113114
check_well_formed: wfcheck::check_well_formed,
114115
..*providers

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use rustc_hir_analysis::check::{check_abi, check_custom_abi};
5353
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
5454
use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc};
5555
use rustc_middle::query::Providers;
56-
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
56+
use rustc_middle::ty::{self, Ty, TyCtxt};
5757
use rustc_middle::{bug, span_bug};
5858
use rustc_session::config;
5959
use rustc_span::Span;
@@ -259,21 +259,6 @@ fn typeck_with_inspect<'tcx>(
259259

260260
let typeck_results = fcx.resolve_type_vars_in_body(body);
261261

262-
// Handle potentially region dependent goals, see `InferCtxt::in_hir_typeck`.
263-
if let None = fcx.infcx.tainted_by_errors() {
264-
for obligation in fcx.take_hir_typeck_potentially_region_dependent_goals() {
265-
let obligation = fcx.resolve_vars_if_possible(obligation);
266-
if obligation.has_non_region_infer() {
267-
bug!("unexpected inference variable after writeback: {obligation:?}");
268-
}
269-
fcx.register_predicate(obligation);
270-
}
271-
fcx.select_obligations_where_possible(|_| {});
272-
if let None = fcx.infcx.tainted_by_errors() {
273-
fcx.report_ambiguity_errors();
274-
}
275-
}
276-
277262
fcx.detect_opaque_types_added_during_writeback();
278263

279264
// Consistency check our TypeckResults instance can hold all ItemLocalIds

0 commit comments

Comments
 (0)