Infer opaque type regions in borrow checking
We want type checking for function bodies to ignore/erase regions. As such, we need to infer the regions in opaque types in borrow check instead.
This commit is contained in:
parent
75ac0cca36
commit
d9b9f00109
@ -282,9 +282,11 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
|
||||
let (closure_region_requirements, nll_errors) =
|
||||
regioncx.solve(infcx, &body, def_id, polonius_output.clone());
|
||||
|
||||
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values, body.span);
|
||||
|
||||
NllOutput {
|
||||
regioncx,
|
||||
opaque_type_values,
|
||||
opaque_type_values: remapped_opaque_tys,
|
||||
polonius_output,
|
||||
opt_closure_req: closure_region_requirements,
|
||||
nll_errors,
|
||||
|
@ -36,6 +36,7 @@ use crate::borrow_check::{
|
||||
|
||||
mod dump_mir;
|
||||
mod graphviz;
|
||||
mod opaque_types;
|
||||
|
||||
pub mod values;
|
||||
|
||||
|
72
src/librustc_mir/borrow_check/region_infer/opaque_types.rs
Normal file
72
src/librustc_mir/borrow_check/region_infer/opaque_types.rs
Normal file
@ -0,0 +1,72 @@
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::ty;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_span::Span;
|
||||
|
||||
use super::RegionInferenceContext;
|
||||
|
||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
/// Resolve any opaque types that were encountered while borrow checking
|
||||
/// this item. This is then used to get the type in the `type_of` query.
|
||||
pub(in crate::borrow_check) fn infer_opaque_types(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
opaque_ty_decls: FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>>,
|
||||
span: Span,
|
||||
) -> FxHashMap<DefId, ty::ResolvedOpaqueTy<'tcx>> {
|
||||
opaque_ty_decls
|
||||
.into_iter()
|
||||
.map(|(opaque_def_id, ty::ResolvedOpaqueTy { concrete_type, substs })| {
|
||||
debug!(
|
||||
"infer_opaque_types(concrete_type = {:?}, substs = {:?})",
|
||||
concrete_type, substs
|
||||
);
|
||||
|
||||
// Map back to "concrete" regions so that errors in
|
||||
// `infer_opaque_definition_from_instantiation` can show
|
||||
// sensible region names.
|
||||
let universal_concrete_type =
|
||||
infcx.tcx.fold_regions(&concrete_type, &mut false, |region, _| match region {
|
||||
&ty::ReVar(vid) => {
|
||||
let universal_bound = self.universal_upper_bound(vid);
|
||||
self.definitions[universal_bound]
|
||||
.external_name
|
||||
.filter(|_| self.eval_equal(universal_bound, vid))
|
||||
.unwrap_or(infcx.tcx.lifetimes.re_empty)
|
||||
}
|
||||
concrete => concrete,
|
||||
});
|
||||
let universal_substs =
|
||||
infcx.tcx.fold_regions(&substs, &mut false, |region, _| match region {
|
||||
ty::ReVar(vid) => {
|
||||
self.definitions[*vid].external_name.unwrap_or_else(|| {
|
||||
infcx.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
"opaque type with non-universal region substs",
|
||||
);
|
||||
infcx.tcx.lifetimes.re_static
|
||||
})
|
||||
}
|
||||
concrete => concrete,
|
||||
});
|
||||
|
||||
debug!(
|
||||
"infer_opaque_types(universal_concrete_type = {:?}, universal_substs = {:?})",
|
||||
universal_concrete_type, universal_substs
|
||||
);
|
||||
|
||||
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
|
||||
opaque_def_id,
|
||||
universal_substs,
|
||||
universal_concrete_type,
|
||||
span,
|
||||
);
|
||||
(
|
||||
opaque_def_id,
|
||||
ty::ResolvedOpaqueTy { concrete_type: remapped_type, substs: universal_substs },
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
@ -1267,8 +1267,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
.at(&ObligationCause::dummy(), param_env)
|
||||
.eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?,
|
||||
);
|
||||
opaque_type_values
|
||||
.push((opaque_def_id, ty::ResolvedOpaqueTy { ..*opaque_defn_ty }));
|
||||
opaque_type_values.push((
|
||||
opaque_def_id,
|
||||
ty::ResolvedOpaqueTy {
|
||||
concrete_type: renumbered_opaque_defn_ty,
|
||||
substs: opaque_decl.substs,
|
||||
},
|
||||
));
|
||||
} else {
|
||||
// We're using an opaque `impl Trait` type without
|
||||
// 'revealing' it. For example, code like this:
|
||||
|
Loading…
Reference in New Issue
Block a user