Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle member constraints directly in the mir type checker #134501

Merged
merged 2 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
more directly handle member constraints
  • Loading branch information
lcnr committed Dec 20, 2024
commit 674c6577a7a3a966ea85d5c8c1ba025b698d5b34
46 changes: 25 additions & 21 deletions compiler/rustc_borrowck/src/member_constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ use std::ops::Index;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexMap;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::infer::MemberConstraint;
use rustc_middle::ty::{self, Ty};
use rustc_span::Span;
use tracing::debug;
use tracing::instrument;

/// Compactly stores a set of `R0 member of [R1...Rn]` constraints,
/// indexed by the region `R0`.
Expand Down Expand Up @@ -70,37 +69,42 @@ impl Default for MemberConstraintSet<'_, ty::RegionVid> {
}

impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
pub(crate) fn is_empty(&self) -> bool {
self.constraints.is_empty()
}

/// Pushes a member constraint into the set.
///
/// The input member constraint `m_c` is in the form produced by
/// the `rustc_middle::infer` code.
///
/// The `to_region_vid` callback fn is used to convert the regions
/// within into `RegionVid` format -- it typically consults the
/// `UniversalRegions` data structure that is known to the caller
/// (but which this code is unaware of).
pub(crate) fn push_constraint(
#[instrument(level = "debug", skip(self))]
pub(crate) fn add_member_constraint(
&mut self,
m_c: &MemberConstraint<'tcx>,
mut to_region_vid: impl FnMut(ty::Region<'tcx>) -> ty::RegionVid,
key: ty::OpaqueTypeKey<'tcx>,
hidden_ty: Ty<'tcx>,
definition_span: Span,
member_region_vid: ty::RegionVid,
choice_regions: &[ty::RegionVid],
) {
debug!("push_constraint(m_c={:?})", m_c);
let member_region_vid: ty::RegionVid = to_region_vid(m_c.member_region);
let next_constraint = self.first_constraints.get(&member_region_vid).cloned();
let start_index = self.choice_regions.len();
let end_index = start_index + m_c.choice_regions.len();
debug!("push_constraint: member_region_vid={:?}", member_region_vid);
self.choice_regions.extend(choice_regions);
let end_index = self.choice_regions.len();
let constraint_index = self.constraints.push(NllMemberConstraint {
next_constraint,
member_region_vid,
definition_span: m_c.definition_span,
hidden_ty: m_c.hidden_ty,
key: m_c.key,
definition_span,
hidden_ty,
key,
start_index,
end_index,
});
self.first_constraints.insert(member_region_vid, constraint_index);
self.choice_regions.extend(m_c.choice_regions.iter().map(|&r| to_region_vid(r)));
}

// TODO: removed in the next commit
pub(crate) fn push_constraint(
&mut self,
_: &rustc_middle::infer::MemberConstraint<'tcx>,
_: impl FnMut(ty::Region<'tcx>) -> ty::RegionVid,
) {
}
}

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// Given a universal region in scope on the MIR, returns the
/// corresponding index.
///
/// (Panics if `r` is not a registered universal region.)
/// Panics if `r` is not a registered universal region, most notably
/// if it is a placeholder. Handling placeholders requires access to the
/// `MirTypeckRegionConstraints`.
pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
self.universal_regions().to_region_vid(r)
}
Expand Down
61 changes: 12 additions & 49 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::source_map::Spanned;
use rustc_span::{DUMMY_SP, Span, sym};
use rustc_trait_selection::traits::query::type_op::custom::{
CustomTypeOp, scrape_region_constraints,
};
use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
use tracing::{debug, instrument, trace};

Expand Down Expand Up @@ -89,6 +87,7 @@ mod constraint_conversion;
pub(crate) mod free_region_relations;
mod input_output;
pub(crate) mod liveness;
mod opaque_types;
mod relate_tys;

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

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

let opaque_type_values = infcx
.take_opaque_types()
.into_iter()
.map(|(opaque_type_key, decl)| {
let _: Result<_, ErrorGuaranteed> = typeck.fully_perform_op(
Locations::All(body.span),
ConstraintCategory::OpaqueType,
CustomTypeOp::new(
|ocx| {
ocx.infcx.register_member_constraints(
opaque_type_key,
decl.hidden_type.ty,
decl.hidden_type.span,
);
Ok(())
},
"opaque_type_map",
),
);
let hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
if hidden_type.has_non_region_infer() {
infcx.dcx().span_bug(
decl.hidden_type.span,
format!("could not resolve {:#?}", hidden_type.ty.kind()),
);
}

// Convert all regions to nll vars.
let (opaque_type_key, hidden_type) =
fold_regions(infcx.tcx, (opaque_type_key, hidden_type), |region, _| {
match region.kind() {
ty::ReVar(_) => region,
ty::RePlaceholder(placeholder) => {
typeck.constraints.placeholder_region(infcx, placeholder)
}
_ => ty::Region::new_var(
infcx.tcx,
typeck.universal_regions.to_region_vid(region),
),
}
});

(opaque_type_key, hidden_type)
})
.collect();
let opaque_type_values =
opaque_types::take_opaques_and_register_member_constraints(&mut typeck);

MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
}
Expand Down Expand Up @@ -955,6 +910,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.body
}

fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> RegionVid {
if let ty::RePlaceholder(placeholder) = r.kind() {
self.constraints.placeholder_region(self.infcx, placeholder).as_var()
} else {
self.universal_regions.to_region_vid(r)
}
}

fn unsized_feature_enabled(&self) -> bool {
let features = self.tcx().features();
features.unsized_locals() || features.unsized_fn_params()
Expand Down
Loading