Skip to content

Commit 9bd5f33

Browse files
committed
Auto merge of #134501 - lcnr:member-constraints-yeet, r=oli-obk
handle member constraints directly in the mir type checker cleaner, faster, easier to change going forward :> fixes #109654 r? `@oli-obk` `@compiler-errors`
2 parents 54dcff1 + 9792cf0 commit 9bd5f33

File tree

15 files changed

+392
-499
lines changed

15 files changed

+392
-499
lines changed

compiler/rustc_borrowck/src/member_constraints.rs

+24-28
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ use std::ops::Index;
44
use rustc_data_structures::captures::Captures;
55
use rustc_data_structures::fx::FxIndexMap;
66
use rustc_index::{IndexSlice, IndexVec};
7-
use rustc_middle::infer::MemberConstraint;
87
use rustc_middle::ty::{self, Ty};
98
use rustc_span::Span;
10-
use tracing::debug;
9+
use tracing::instrument;
1110

1211
/// Compactly stores a set of `R0 member of [R1...Rn]` constraints,
1312
/// indexed by the region `R0`.
@@ -23,7 +22,7 @@ where
2322
/// Stores the data about each `R0 member of [R1..Rn]` constraint.
2423
/// These are organized into a linked list, so each constraint
2524
/// contains the index of the next constraint with the same `R0`.
26-
constraints: IndexVec<NllMemberConstraintIndex, NllMemberConstraint<'tcx>>,
25+
constraints: IndexVec<NllMemberConstraintIndex, MemberConstraint<'tcx>>,
2726

2827
/// Stores the `R1..Rn` regions for *all* sets. For any given
2928
/// constraint, we keep two indices so that we can pull out a
@@ -33,7 +32,7 @@ where
3332

3433
/// Represents a `R0 member of [R1..Rn]` constraint
3534
#[derive(Debug)]
36-
pub(crate) struct NllMemberConstraint<'tcx> {
35+
pub(crate) struct MemberConstraint<'tcx> {
3736
next_constraint: Option<NllMemberConstraintIndex>,
3837

3938
/// The span where the hidden type was instantiated.
@@ -70,37 +69,34 @@ impl Default for MemberConstraintSet<'_, ty::RegionVid> {
7069
}
7170

7271
impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
72+
pub(crate) fn is_empty(&self) -> bool {
73+
self.constraints.is_empty()
74+
}
75+
7376
/// Pushes a member constraint into the set.
74-
///
75-
/// The input member constraint `m_c` is in the form produced by
76-
/// the `rustc_middle::infer` code.
77-
///
78-
/// The `to_region_vid` callback fn is used to convert the regions
79-
/// within into `RegionVid` format -- it typically consults the
80-
/// `UniversalRegions` data structure that is known to the caller
81-
/// (but which this code is unaware of).
82-
pub(crate) fn push_constraint(
77+
#[instrument(level = "debug", skip(self))]
78+
pub(crate) fn add_member_constraint(
8379
&mut self,
84-
m_c: &MemberConstraint<'tcx>,
85-
mut to_region_vid: impl FnMut(ty::Region<'tcx>) -> ty::RegionVid,
80+
key: ty::OpaqueTypeKey<'tcx>,
81+
hidden_ty: Ty<'tcx>,
82+
definition_span: Span,
83+
member_region_vid: ty::RegionVid,
84+
choice_regions: &[ty::RegionVid],
8685
) {
87-
debug!("push_constraint(m_c={:?})", m_c);
88-
let member_region_vid: ty::RegionVid = to_region_vid(m_c.member_region);
8986
let next_constraint = self.first_constraints.get(&member_region_vid).cloned();
9087
let start_index = self.choice_regions.len();
91-
let end_index = start_index + m_c.choice_regions.len();
92-
debug!("push_constraint: member_region_vid={:?}", member_region_vid);
93-
let constraint_index = self.constraints.push(NllMemberConstraint {
88+
self.choice_regions.extend(choice_regions);
89+
let end_index = self.choice_regions.len();
90+
let constraint_index = self.constraints.push(MemberConstraint {
9491
next_constraint,
9592
member_region_vid,
96-
definition_span: m_c.definition_span,
97-
hidden_ty: m_c.hidden_ty,
98-
key: m_c.key,
93+
definition_span,
94+
hidden_ty,
95+
key,
9996
start_index,
10097
end_index,
10198
});
10299
self.first_constraints.insert(member_region_vid, constraint_index);
103-
self.choice_regions.extend(m_c.choice_regions.iter().map(|&r| to_region_vid(r)));
104100
}
105101
}
106102

@@ -182,7 +178,7 @@ where
182178
/// R0 member of [R1..Rn]
183179
/// ```
184180
pub(crate) fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] {
185-
let NllMemberConstraint { start_index, end_index, .. } = &self.constraints[pci];
181+
let MemberConstraint { start_index, end_index, .. } = &self.constraints[pci];
186182
&self.choice_regions[*start_index..*end_index]
187183
}
188184
}
@@ -191,9 +187,9 @@ impl<'tcx, R> Index<NllMemberConstraintIndex> for MemberConstraintSet<'tcx, R>
191187
where
192188
R: Copy + Eq,
193189
{
194-
type Output = NllMemberConstraint<'tcx>;
190+
type Output = MemberConstraint<'tcx>;
195191

196-
fn index(&self, i: NllMemberConstraintIndex) -> &NllMemberConstraint<'tcx> {
192+
fn index(&self, i: NllMemberConstraintIndex) -> &MemberConstraint<'tcx> {
197193
&self.constraints[i]
198194
}
199195
}
@@ -215,7 +211,7 @@ where
215211
/// target_list: A -> B -> C -> D -> E -> F -> (None)
216212
/// ```
217213
fn append_list(
218-
constraints: &mut IndexSlice<NllMemberConstraintIndex, NllMemberConstraint<'_>>,
214+
constraints: &mut IndexSlice<NllMemberConstraintIndex, MemberConstraint<'_>>,
219215
target_list: NllMemberConstraintIndex,
220216
source_list: NllMemberConstraintIndex,
221217
) {

compiler/rustc_borrowck/src/region_infer/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
571571
/// Given a universal region in scope on the MIR, returns the
572572
/// corresponding index.
573573
///
574-
/// (Panics if `r` is not a registered universal region.)
574+
/// Panics if `r` is not a registered universal region, most notably
575+
/// if it is a placeholder. Handling placeholders requires access to the
576+
/// `MirTypeckRegionConstraints`.
575577
pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
576578
self.universal_regions().to_region_vid(r)
577579
}

compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

+3-18
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
7777

7878
#[instrument(skip(self), level = "debug")]
7979
pub(super) fn convert_all(&mut self, query_constraints: &QueryRegionConstraints<'tcx>) {
80-
let QueryRegionConstraints { outlives, member_constraints } = query_constraints;
81-
82-
// Annoying: to invoke `self.to_region_vid`, we need access to
83-
// `self.constraints`, but we also want to be mutating
84-
// `self.member_constraints`. For now, just swap out the value
85-
// we want and replace at the end.
86-
let mut tmp = std::mem::take(&mut self.constraints.member_constraints);
87-
for member_constraint in member_constraints {
88-
tmp.push_constraint(member_constraint, |r| self.to_region_vid(r));
89-
}
90-
self.constraints.member_constraints = tmp;
80+
let QueryRegionConstraints { outlives } = query_constraints;
9181

9282
for &(predicate, constraint_category) in outlives {
9383
self.convert(predicate, constraint_category);
@@ -295,13 +285,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
295285

296286
match result {
297287
Ok(TypeOpOutput { output: ty, constraints, .. }) => {
298-
if let Some(constraints) = constraints {
299-
assert!(
300-
constraints.member_constraints.is_empty(),
301-
"no member constraints expected from normalizing: {:#?}",
302-
constraints.member_constraints
303-
);
304-
next_outlives_predicates.extend(constraints.outlives.iter().copied());
288+
if let Some(QueryRegionConstraints { outlives }) = constraints {
289+
next_outlives_predicates.extend(outlives.iter().copied());
305290
}
306291
ty
307292
}

compiler/rustc_borrowck/src/type_check/mod.rs

+12-49
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ use rustc_mir_dataflow::points::DenseLocationMap;
4040
use rustc_span::def_id::CRATE_DEF_ID;
4141
use rustc_span::source_map::Spanned;
4242
use rustc_span::{DUMMY_SP, Span, sym};
43-
use rustc_trait_selection::traits::query::type_op::custom::{
44-
CustomTypeOp, scrape_region_constraints,
45-
};
43+
use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
4644
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
4745
use tracing::{debug, instrument, trace};
4846

@@ -89,6 +87,7 @@ mod constraint_conversion;
8987
pub(crate) mod free_region_relations;
9088
mod input_output;
9189
pub(crate) mod liveness;
90+
mod opaque_types;
9291
mod relate_tys;
9392

9493
/// Type checks the given `mir` in the context of the inference
@@ -179,52 +178,8 @@ pub(crate) fn type_check<'a, 'tcx>(
179178

180179
liveness::generate(&mut typeck, body, &elements, flow_inits, move_data);
181180

182-
let opaque_type_values = infcx
183-
.take_opaque_types()
184-
.into_iter()
185-
.map(|(opaque_type_key, decl)| {
186-
let _: Result<_, ErrorGuaranteed> = typeck.fully_perform_op(
187-
Locations::All(body.span),
188-
ConstraintCategory::OpaqueType,
189-
CustomTypeOp::new(
190-
|ocx| {
191-
ocx.infcx.register_member_constraints(
192-
opaque_type_key,
193-
decl.hidden_type.ty,
194-
decl.hidden_type.span,
195-
);
196-
Ok(())
197-
},
198-
"opaque_type_map",
199-
),
200-
);
201-
let hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
202-
trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
203-
if hidden_type.has_non_region_infer() {
204-
infcx.dcx().span_bug(
205-
decl.hidden_type.span,
206-
format!("could not resolve {:#?}", hidden_type.ty.kind()),
207-
);
208-
}
209-
210-
// Convert all regions to nll vars.
211-
let (opaque_type_key, hidden_type) =
212-
fold_regions(infcx.tcx, (opaque_type_key, hidden_type), |region, _| {
213-
match region.kind() {
214-
ty::ReVar(_) => region,
215-
ty::RePlaceholder(placeholder) => {
216-
typeck.constraints.placeholder_region(infcx, placeholder)
217-
}
218-
_ => ty::Region::new_var(
219-
infcx.tcx,
220-
typeck.universal_regions.to_region_vid(region),
221-
),
222-
}
223-
});
224-
225-
(opaque_type_key, hidden_type)
226-
})
227-
.collect();
181+
let opaque_type_values =
182+
opaque_types::take_opaques_and_register_member_constraints(&mut typeck);
228183

229184
MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
230185
}
@@ -955,6 +910,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
955910
self.body
956911
}
957912

913+
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> RegionVid {
914+
if let ty::RePlaceholder(placeholder) = r.kind() {
915+
self.constraints.placeholder_region(self.infcx, placeholder).as_var()
916+
} else {
917+
self.universal_regions.to_region_vid(r)
918+
}
919+
}
920+
958921
fn unsized_feature_enabled(&self) -> bool {
959922
let features = self.tcx().features();
960923
features.unsized_locals() || features.unsized_fn_params()

0 commit comments

Comments
 (0)