1
Fork 0

Revert "Auto merge of #92007 - oli-obk:lazy_tait2, r=nikomatsakis"

This reverts commit e7cc3bddbe, reversing
changes made to 734368a200.
This commit is contained in:
Oli Scherer 2022-02-11 07:18:06 +00:00
parent 2d8b8f3593
commit d54195db22
359 changed files with 2448 additions and 3311 deletions

View file

@ -124,9 +124,8 @@ fn mir_borrowck<'tcx>(
) -> &'tcx BorrowCheckResult<'tcx> {
let (input_body, promoted) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(hir_owner).enter(|infcx| {
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| {
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.borrow();
do_mir_borrowck(&infcx, input_body, promoted, false).0
@ -141,7 +140,7 @@ fn mir_borrowck<'tcx>(
/// If `return_body_with_facts` is true, then return the body with non-erased
/// region ids on which the borrow checking was performed together with Polonius
/// facts.
#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")]
#[instrument(skip(infcx, input_body, input_promoted), level = "debug")]
fn do_mir_borrowck<'a, 'tcx>(
infcx: &InferCtxt<'a, 'tcx>,
input_body: &Body<'tcx>,

View file

@ -1,6 +1,7 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::vec_map::VecMap;
use rustc_hir::OpaqueTyOrigin;
use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
use rustc_infer::infer::InferCtxt;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
@ -53,44 +54,27 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn infer_opaque_types(
&self,
infcx: &InferCtxt<'_, 'tcx>,
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (Ty<'tcx>, Span, OpaqueTyOrigin)>,
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>,
span: Span,
) -> VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>> {
opaque_ty_decls
.into_iter()
.map(|(opaque_type_key, (concrete_type, decl_span, origin))| {
.filter_map(|(opaque_type_key, decl)| {
let substs = opaque_type_key.substs;
// FIXME: why are the spans in decl_span often DUMMY_SP?
let span = decl_span.substitute_dummy(span);
let concrete_type = decl.concrete_ty;
debug!(?concrete_type, ?substs);
let mut subst_regions = vec![self.universal_regions.fr_static];
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
if let ty::RePlaceholder(..) = region {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
return region;
}
let vid = self.to_region_vid(region);
trace!(?vid);
let scc = self.constraint_sccs.scc(vid);
trace!(?scc);
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
}) {
Some(region) => {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
region
}
None => {
subst_regions.push(vid);
infcx.tcx.sess.delay_span_bug(
span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
}
}
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(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
})
});
subst_regions.sort();
@ -116,14 +100,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
span,
);
(
check_opaque_type_parameter_valid(
infcx.tcx,
opaque_type_key,
if check_opaque_type_parameter_valid(infcx.tcx, opaque_type_key, origin, span) {
remapped_type
} else {
infcx.tcx.ty_error()
},
OpaqueTypeDecl { concrete_ty: remapped_type, ..decl },
)
.then_some((opaque_type_key, remapped_type))
})
.collect()
}
@ -167,10 +149,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
fn check_opaque_type_parameter_valid(
tcx: TyCtxt<'_>,
opaque_type_key: OpaqueTypeKey<'_>,
origin: OpaqueTyOrigin,
span: Span,
decl: OpaqueTypeDecl<'_>,
) -> bool {
match origin {
match decl.origin {
// No need to check return position impl trait (RPIT)
// because for type and const parameters they are correct
// by construction: we convert
@ -196,6 +177,7 @@ fn check_opaque_type_parameter_valid(
// Check these
OpaqueTyOrigin::TyAlias => {}
}
let span = decl.definition_span;
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
for (i, arg) in opaque_type_key.substs.iter().enumerate() {

View file

@ -147,9 +147,9 @@ 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;
if let Err(terr) = self.eq_types(
normalized_output_ty,
if let Err(terr) = self.eq_opaque_type_and_type(
mir_output_ty,
normalized_output_ty,
Locations::All(output_span),
ConstraintCategory::BoringNoLocation,
) {
@ -169,9 +169,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let user_provided_output_ty = user_provided_sig.output();
let user_provided_output_ty =
self.normalize(user_provided_output_ty, Locations::All(output_span));
if let Err(err) = self.eq_types(
user_provided_output_ty,
if let Err(err) = self.eq_opaque_type_and_type(
mir_output_ty,
user_provided_output_ty,
Locations::All(output_span),
ConstraintCategory::BoringNoLocation,
) {

View file

@ -5,7 +5,6 @@ use std::{fmt, iter, mem};
use either::Either;
use hir::OpaqueTyOrigin;
use rustc_data_structures::frozen::Frozen;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::vec_map::VecMap;
@ -16,6 +15,7 @@ use rustc_hir::def_id::LocalDefId;
use rustc_hir::lang_items::LangItem;
use rustc_index::vec::{Idx, IndexVec};
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{
@ -41,7 +41,7 @@ use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::query::type_op;
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
use rustc_trait_selection::traits::query::Fallible;
use rustc_trait_selection::traits::{self, ObligationCause};
use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligations};
use rustc_const_eval::transform::{
check_consts::ConstCx, promote_consts::is_const_fn_in_array_repeat_expression,
@ -75,7 +75,7 @@ macro_rules! span_mirbug {
$context.last_span,
&format!(
"broken MIR in {:?} ({:?}): {}",
$context.body().source.def_id(),
$context.body.source.def_id(),
$elem,
format_args!($($message)*),
),
@ -190,44 +190,59 @@ pub(crate) fn type_check<'mir, 'tcx>(
liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
translate_outlives_facts(&mut cx);
let opaque_type_values =
infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
let opaque_type_values = mem::take(&mut infcx.inner.borrow_mut().opaque_types);
opaque_type_values
.into_iter()
.map(|(opaque_type_key, decl)| {
cx.fully_perform_op(
Locations::All(body.span),
ConstraintCategory::OpaqueType,
CustomTypeOp::new(
|infcx| {
infcx.register_member_constraints(
param_env,
opaque_type_key,
decl.hidden_type.ty,
decl.hidden_type.span,
);
Ok(InferOk { value: (), obligations: vec![] })
},
|| "opaque_type_map".to_string(),
),
)
.unwrap();
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type.ty);
.filter_map(|(opaque_type_key, mut decl)| {
decl.concrete_ty = infcx.resolve_vars_if_possible(decl.concrete_ty);
trace!(
"finalized opaque type {:?} to {:#?}",
opaque_type_key,
hidden_type.kind()
decl.concrete_ty.kind()
);
if hidden_type.has_infer_types_or_consts() {
if decl.concrete_ty.has_infer_types_or_consts() {
infcx.tcx.sess.delay_span_bug(
decl.hidden_type.span,
&format!("could not resolve {:#?}", hidden_type.kind()),
body.span,
&format!("could not resolve {:#?}", decl.concrete_ty.kind()),
);
hidden_type = infcx.tcx.ty_error();
decl.concrete_ty = infcx.tcx.ty_error();
}
let concrete_is_opaque = if let ty::Opaque(def_id, _) = decl.concrete_ty.kind()
{
*def_id == opaque_type_key.def_id
} else {
false
};
(opaque_type_key, (hidden_type, decl.hidden_type.span, decl.origin))
if concrete_is_opaque {
// We're using an opaque `impl Trait` type without
// 'revealing' it. For example, code like this:
//
// type Foo = impl Debug;
// fn foo1() -> Foo { ... }
// fn foo2() -> Foo { foo1() }
//
// In `foo2`, we're not revealing the type of `Foo` - we're
// just treating it as the opaque type.
//
// When this occurs, we do *not* want to try to equate
// the concrete type with the underlying defining type
// of the opaque type - this will always fail, since
// the defining type of an opaque type is always
// some other type (e.g. not itself)
// Essentially, none of the normal obligations apply here -
// we're just passing around some unknown opaque type,
// without actually looking at the underlying type it
// gets 'revealed' into
debug!(
"eq_opaque_type_and_type: non-defining use of {:?}",
opaque_type_key.def_id,
);
None
} else {
Some((opaque_type_key, decl))
}
})
.collect()
},
@ -259,7 +274,7 @@ fn type_check_internal<'a, 'tcx, R>(
borrowck_context,
);
let errors_reported = {
let mut verifier = TypeVerifier::new(&mut checker, promoted);
let mut verifier = TypeVerifier::new(&mut checker, body, promoted);
verifier.visit_body(&body);
verifier.errors_reported
};
@ -316,6 +331,7 @@ enum FieldAccessError {
/// is a problem.
struct TypeVerifier<'a, 'b, 'tcx> {
cx: &'a mut TypeChecker<'b, 'tcx>,
body: &'b Body<'tcx>,
promoted: &'b IndexVec<Promoted, Body<'tcx>>,
last_span: Span,
errors_reported: bool,
@ -451,7 +467,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
self.super_rvalue(rvalue, location);
let rval_ty = rvalue.ty(self.body(), self.tcx());
let rval_ty = rvalue.ty(self.body, self.tcx());
self.sanitize_type(rvalue, rval_ty);
}
@ -510,13 +526,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
fn new(
cx: &'a mut TypeChecker<'b, 'tcx>,
body: &'b Body<'tcx>,
promoted: &'b IndexVec<Promoted, Body<'tcx>>,
) -> Self {
TypeVerifier { promoted, last_span: cx.body.span, cx, errors_reported: false }
}
fn body(&self) -> &Body<'tcx> {
self.cx.body
TypeVerifier { body, promoted, cx, last_span: body.span, errors_reported: false }
}
fn tcx(&self) -> TyCtxt<'tcx> {
@ -541,7 +554,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
) -> PlaceTy<'tcx> {
debug!("sanitize_place: {:?}", place);
let mut place_ty = PlaceTy::from_ty(self.body().local_decls[place.local].ty);
let mut place_ty = PlaceTy::from_ty(self.body.local_decls[place.local].ty);
for elem in place.projection.iter() {
if place_ty.variant_index.is_none() {
@ -586,7 +599,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
// checker on the promoted MIR, then transfer the constraints back to
// the main MIR, changing the locations to the provided location.
let parent_body = mem::replace(&mut self.cx.body, promoted_body);
let parent_body = mem::replace(&mut self.body, promoted_body);
// Use new sets of constraints and closure bounds so that we can
// modify their locations.
@ -622,7 +635,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
self.cx.typeck_mir(promoted_body);
}
self.cx.body = parent_body;
self.body = parent_body;
// Merge the outlives constraints back in, at the given location.
swap_constraints(self);
@ -684,7 +697,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
}))
}
ProjectionElem::Index(i) => {
let index_ty = Place::from(i).ty(self.body(), tcx).ty;
let index_ty = Place::from(i).ty(self.body, tcx).ty;
if index_ty != tcx.types.usize {
PlaceTy::from_ty(span_mirbug_and_err!(self, i, "index by non-usize {:?}", i))
} else {
@ -893,7 +906,7 @@ struct BorrowCheckContext<'a, 'tcx> {
crate struct MirTypeckResults<'tcx> {
crate constraints: MirTypeckRegionConstraints<'tcx>,
crate universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, (Ty<'tcx>, Span, OpaqueTyOrigin)>,
crate opaque_type_values: VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>,
}
/// A collection of region constraints that must be satisfied for the
@ -1043,19 +1056,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
checker
}
fn body(&self) -> &Body<'tcx> {
self.body
}
fn unsized_feature_enabled(&self) -> bool {
let features = self.tcx().features();
features.unsized_locals || features.unsized_fn_params
}
/// Equate the inferred type and the annotated type for user type annotations
#[instrument(skip(self), level = "debug")]
fn check_user_type_annotations(&mut self) {
debug!(?self.user_type_annotations);
debug!(
"check_user_type_annotations: user_type_annotations={:?}",
self.user_type_annotations
);
for user_annotation in self.user_type_annotations {
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
let inferred_ty = self.normalize(inferred_ty, Locations::All(span));
@ -1196,6 +1207,131 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Ok(())
}
/// Equates a type `anon_ty` that may contain opaque types whose
/// values are to be inferred by the MIR.
///
/// The type `revealed_ty` contains the same type as `anon_ty`, but with the
/// hidden types for impl traits revealed.
///
/// # Example
///
/// Consider a piece of code like
///
/// ```rust
/// type Foo<U> = impl Debug;
///
/// fn foo<T: Debug>(t: T) -> Box<Foo<T>> {
/// Box::new((t, 22_u32))
/// }
/// ```
///
/// Here, the function signature would be something like
/// `fn(T) -> Box<impl Debug>`. The MIR return slot would have
/// the type with the opaque type revealed, so `Box<(T, u32)>`.
///
/// In terms of our function parameters:
///
/// * `anon_ty` would be `Box<Foo<T>>` where `Foo<T>` is an opaque type
/// scoped to this function (note that it is parameterized by the
/// generics of `foo`). Note that `anon_ty` is not just the opaque type,
/// but the entire return type (which may contain opaque types within it).
/// * `revealed_ty` would be `Box<(T, u32)>`
#[instrument(skip(self), level = "debug")]
fn eq_opaque_type_and_type(
&mut self,
revealed_ty: Ty<'tcx>,
anon_ty: Ty<'tcx>,
locations: Locations,
category: ConstraintCategory,
) -> Fallible<()> {
// Fast path for the common case.
if !anon_ty.has_opaque_types() {
if let Err(terr) = self.eq_types(anon_ty, revealed_ty, locations, category) {
span_mirbug!(
self,
locations,
"eq_opaque_type_and_type: `{:?}=={:?}` failed with `{:?}`",
revealed_ty,
anon_ty,
terr
);
}
return Ok(());
}
let param_env = self.param_env;
let body = self.body;
let mir_def_id = body.source.def_id().expect_local();
debug!(?mir_def_id);
self.fully_perform_op(
locations,
category,
CustomTypeOp::new(
|infcx| {
let mut obligations = ObligationAccumulator::default();
let dummy_body_id = hir::CRATE_HIR_ID;
// Replace the opaque types defined by this function with
// inference variables, creating a map. In our example above,
// this would transform the type `Box<Foo<T>>` (where `Foo` is an opaque type)
// to `Box<?T>`, returning an `opaque_type_map` mapping `{Foo<T> -> ?T}`.
// (Note that the key of the map is both the def-id of `Foo` along with
// any generic parameters.)
let output_ty = obligations.add(infcx.instantiate_opaque_types(
dummy_body_id,
param_env,
anon_ty,
locations.span(body),
));
debug!(?output_ty, ?revealed_ty);
// Make sure that the inferred types are well-formed. I'm
// not entirely sure this is needed (the HIR type check
// didn't do this) but it seems sensible to prevent opaque
// types hiding ill-formed types.
obligations.obligations.push(traits::Obligation::new(
ObligationCause::dummy(),
param_env,
ty::Binder::dummy(ty::PredicateKind::WellFormed(revealed_ty.into()))
.to_predicate(infcx.tcx),
));
obligations.add(
infcx
.at(&ObligationCause::dummy(), param_env)
.eq(output_ty, revealed_ty)?,
);
debug!("equated");
Ok(InferOk { value: (), obligations: obligations.into_vec() })
},
|| "input_output".to_string(),
),
)?;
// Finally, if we instantiated the anon types successfully, we
// have to solve any bounds (e.g., `-> impl Iterator` needs to
// prove that `T: Iterator` where `T` is the type we
// instantiated it with).
let opaque_type_map = self.infcx.inner.borrow().opaque_types.clone();
for (opaque_type_key, opaque_decl) in opaque_type_map {
self.fully_perform_op(
locations,
ConstraintCategory::OpaqueType,
CustomTypeOp::new(
|infcx| {
infcx.constrain_opaque_type(opaque_type_key, &opaque_decl);
Ok(InferOk { value: (), obligations: vec![] })
},
|| "opaque_type_map".to_string(),
),
)?;
}
Ok(())
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
@ -2637,3 +2773,20 @@ impl NormalizeLocation for Location {
Locations::Single(self)
}
}
#[derive(Debug, Default)]
struct ObligationAccumulator<'tcx> {
obligations: PredicateObligations<'tcx>,
}
impl<'tcx> ObligationAccumulator<'tcx> {
fn add<T>(&mut self, value: InferOk<'tcx, T>) -> T {
let InferOk { value, obligations } = value;
self.obligations.extend(obligations);
value
}
fn into_vec(self) -> PredicateObligations<'tcx> {
self.obligations
}
}

View file

@ -1,15 +1,13 @@
use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
use rustc_infer::infer::{InferOk, NllRegionVariableOrigin};
use rustc_infer::traits::ObligationCause;
use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::{self, Const, Ty};
use rustc_span::Span;
use rustc_trait_selection::traits::query::Fallible;
use crate::constraints::OutlivesConstraint;
use crate::diagnostics::UniverseInfo;
use crate::type_check::{CustomTypeOp, Locations, TypeChecker};
use crate::type_check::{Locations, TypeChecker};
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
/// Adds sufficient constraints to ensure that `a R b` where `R` depends on `v`:
@ -65,10 +63,6 @@ impl<'me, 'bccx, 'tcx> NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {
}
impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
fn span(&self) -> Span {
self.locations.span(self.type_checker.body)
}
fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.type_checker.param_env
}
@ -123,9 +117,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
// We don't have to worry about the equality of consts during borrow checking
// as consts always have a static lifetime.
// FIXME(oli-obk): is this really true? We can at least have HKL and with
// inline consts we may have further lifetimes that may be unsound to treat as
// 'static.
fn const_equate(&mut self, _a: &'tcx Const<'tcx>, _b: &'tcx Const<'tcx>) {}
fn normalization() -> NormalizationStrategy {
@ -135,33 +126,4 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
fn forbid_inference_vars() -> bool {
true
}
fn register_opaque_type(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected: bool) {
let param_env = self.param_env();
let span = self.span();
let def_id = self.type_checker.body.source.def_id().expect_local();
let body_id = self.type_checker.tcx().hir().local_def_id_to_hir_id(def_id);
let cause = ObligationCause::misc(span, body_id);
self.type_checker
.fully_perform_op(
self.locations,
self.category,
CustomTypeOp::new(
|infcx| {
Ok(InferOk {
value: (),
obligations: vec![infcx.opaque_ty_obligation(
a,
b,
a_is_expected,
param_env,
cause,
)],
})
},
|| "register_opaque_type".to_string(),
),
)
.unwrap();
}
}

View file

@ -728,7 +728,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
self.tcx.fold_regions(value, &mut false, |_region, _depth| self.next_nll_region_var(origin))
}
#[instrument(level = "debug", skip(self, indices))]
fn replace_bound_regions_with_nll_infer_vars<T>(
&self,
origin: NllRegionVariableOrigin,
@ -739,15 +738,22 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
where
T: TypeFoldable<'tcx>,
{
debug!(
"replace_bound_regions_with_nll_infer_vars(value={:?}, all_outlive_scope={:?})",
value, all_outlive_scope,
);
let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| {
debug!(?br);
debug!("replace_bound_regions_with_nll_infer_vars: br={:?}", br);
let liberated_region = self.tcx.mk_region(ty::ReFree(ty::FreeRegion {
scope: all_outlive_scope.to_def_id(),
bound_region: br.kind,
}));
let region_vid = self.next_nll_region_var(origin);
indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid());
debug!(?liberated_region, ?region_vid);
debug!(
"replace_bound_regions_with_nll_infer_vars: liberated_region={:?} => {:?}",
liberated_region, region_vid
);
region_vid
});
value
@ -762,7 +768,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
/// entries for them and store them in the indices map. This code iterates over the complete
/// set of late-bound regions and checks for any that we have not yet seen, adding them to the
/// inputs vector.
#[instrument(skip(self, indices))]
fn replace_late_bound_regions_with_nll_infer_vars(
&self,
mir_def_id: LocalDefId,
@ -774,7 +779,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
debug!("replace_late_bound_regions_with_nll_infer_vars: r={:?}", r);
if !indices.indices.contains_key(&r) {
let region_vid = self.next_nll_region_var(FR);
debug!(?region_vid);
indices.insert_late_bound_region(r, region_vid.to_region_vid());
}
});