collect existentials and placeholders
This commit is contained in:
parent
2f79f73821
commit
960ebaf899
5 changed files with 76 additions and 20 deletions
|
@ -1,9 +1,6 @@
|
||||||
<<<<<<< HEAD
|
|
||||||
#![deny(rustc::untranslatable_diagnostic)]
|
#![deny(rustc::untranslatable_diagnostic)]
|
||||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||||
=======
|
|
||||||
use crate::BorrowckInferCtxt;
|
use crate::BorrowckInferCtxt;
|
||||||
>>>>>>> 2464f768a17 (collect region contexts during mir renumbering)
|
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||||
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
use rustc_middle::mir::visit::{MutVisitor, TyContext};
|
||||||
|
|
|
@ -64,7 +64,7 @@ use crate::{
|
||||||
region_infer::TypeTest,
|
region_infer::TypeTest,
|
||||||
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
|
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
|
||||||
universal_regions::{DefiningTy, UniversalRegions},
|
universal_regions::{DefiningTy, UniversalRegions},
|
||||||
Upvar,
|
BorrowckInferCtxt, Upvar,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! span_mirbug {
|
macro_rules! span_mirbug {
|
||||||
|
@ -123,7 +123,7 @@ mod relate_tys;
|
||||||
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
|
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
|
||||||
/// - `elements` -- MIR region map
|
/// - `elements` -- MIR region map
|
||||||
pub(crate) fn type_check<'mir, 'tcx>(
|
pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &BorrowckInferCtxt<'_, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
promoted: &IndexVec<Promoted, Body<'tcx>>,
|
promoted: &IndexVec<Promoted, Body<'tcx>>,
|
||||||
|
@ -845,7 +845,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||||
/// way, it accrues region constraints -- these can later be used by
|
/// way, it accrues region constraints -- these can later be used by
|
||||||
/// NLL region checking.
|
/// NLL region checking.
|
||||||
struct TypeChecker<'a, 'tcx> {
|
struct TypeChecker<'a, 'tcx> {
|
||||||
infcx: &'a InferCtxt<'tcx>,
|
infcx: &'a BorrowckInferCtxt<'a, 'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
last_span: Span,
|
last_span: Span,
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
|
@ -998,7 +998,7 @@ impl Locations {
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
infcx: &'a InferCtxt<'tcx>,
|
infcx: &'a BorrowckInferCtxt<'a, 'tcx>,
|
||||||
body: &'a Body<'tcx>,
|
body: &'a Body<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
||||||
|
|
|
@ -4,11 +4,12 @@ use rustc_infer::traits::PredicateObligations;
|
||||||
use rustc_middle::mir::ConstraintCategory;
|
use rustc_middle::mir::ConstraintCategory;
|
||||||
use rustc_middle::ty::relate::TypeRelation;
|
use rustc_middle::ty::relate::TypeRelation;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use rustc_span::Span;
|
use rustc_span::{Span, Symbol};
|
||||||
use rustc_trait_selection::traits::query::Fallible;
|
use rustc_trait_selection::traits::query::Fallible;
|
||||||
|
|
||||||
use crate::constraints::OutlivesConstraint;
|
use crate::constraints::OutlivesConstraint;
|
||||||
use crate::diagnostics::UniverseInfo;
|
use crate::diagnostics::UniverseInfo;
|
||||||
|
use crate::renumber::RegionCtxt;
|
||||||
use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker};
|
use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker};
|
||||||
|
|
||||||
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
@ -100,23 +101,69 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
|
||||||
universe
|
universe
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> {
|
#[instrument(skip(self), level = "debug")]
|
||||||
|
fn next_existential_region_var(
|
||||||
|
&mut self,
|
||||||
|
from_forall: bool,
|
||||||
|
_name: Option<Symbol>,
|
||||||
|
) -> ty::Region<'tcx> {
|
||||||
let origin = NllRegionVariableOrigin::Existential { from_forall };
|
let origin = NllRegionVariableOrigin::Existential { from_forall };
|
||||||
self.type_checker.infcx.next_nll_region_var(origin)
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
let reg_var = self.type_checker.infcx.next_nll_region_var(origin);
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
let reg_var =
|
||||||
|
self.type_checker.infcx.next_nll_region_var(origin, RegionCtxt::Existential(_name));
|
||||||
|
|
||||||
|
reg_var
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
|
fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
|
||||||
self.type_checker
|
let reg = self
|
||||||
|
.type_checker
|
||||||
.borrowck_context
|
.borrowck_context
|
||||||
.constraints
|
.constraints
|
||||||
.placeholder_region(self.type_checker.infcx, placeholder)
|
.placeholder_region(self.type_checker.infcx, placeholder);
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
let name = match placeholder.name {
|
||||||
|
ty::BoundRegionKind::BrAnon(_) => Symbol::intern("anon"),
|
||||||
|
ty::BoundRegionKind::BrNamed(_, name) => name,
|
||||||
|
ty::BoundRegionKind::BrEnv => Symbol::intern("env"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let reg_var = reg
|
||||||
|
.try_get_var()
|
||||||
|
.unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
|
||||||
|
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
|
||||||
|
let prev = var_to_origin.insert(reg_var, RegionCtxt::Placeholder(name));
|
||||||
|
assert!(matches!(prev, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
|
fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> {
|
||||||
self.type_checker.infcx.next_nll_region_var_in_universe(
|
let reg = self.type_checker.infcx.next_nll_region_var_in_universe(
|
||||||
NllRegionVariableOrigin::Existential { from_forall: false },
|
NllRegionVariableOrigin::Existential { from_forall: false },
|
||||||
universe,
|
universe,
|
||||||
)
|
);
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
let reg_var = reg
|
||||||
|
.try_get_var()
|
||||||
|
.unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg));
|
||||||
|
let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut();
|
||||||
|
let prev = var_to_origin.insert(reg_var, RegionCtxt::Existential(None));
|
||||||
|
assert!(matches!(prev, None));
|
||||||
|
}
|
||||||
|
|
||||||
|
reg
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_outlives(
|
fn push_outlives(
|
||||||
|
|
|
@ -27,7 +27,7 @@ use rustc_middle::ty::fold::TypeFoldable;
|
||||||
use rustc_middle::ty::relate::TypeRelation;
|
use rustc_middle::ty::relate::TypeRelation;
|
||||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
|
||||||
use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt};
|
use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::{Span, Symbol};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
|
@ -318,7 +318,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
|
|
||||||
// Screen out `'a: 'a` cases.
|
// Screen out `'a: 'a` cases.
|
||||||
let ty::OutlivesPredicate(k1, r2) = r_c.0;
|
let ty::OutlivesPredicate(k1, r2) = r_c.0;
|
||||||
if k1 != r2.into() { Some(r_c) } else { None }
|
if k1 != r2.into() {
|
||||||
|
Some(r_c)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -683,7 +687,11 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
|
||||||
self.infcx.create_next_universe()
|
self.infcx.create_next_universe()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> {
|
fn next_existential_region_var(
|
||||||
|
&mut self,
|
||||||
|
from_forall: bool,
|
||||||
|
_name: Option<Symbol>,
|
||||||
|
) -> ty::Region<'tcx> {
|
||||||
let origin = NllRegionVariableOrigin::Existential { from_forall };
|
let origin = NllRegionVariableOrigin::Existential { from_forall };
|
||||||
self.infcx.next_nll_region_var(origin)
|
self.infcx.next_nll_region_var(origin)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ use rustc_middle::ty::error::TypeError;
|
||||||
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||||
use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable};
|
use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable};
|
||||||
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
|
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
|
||||||
use rustc_span::Span;
|
use rustc_span::{Span, Symbol};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
@ -100,7 +100,11 @@ pub trait TypeRelatingDelegate<'tcx> {
|
||||||
/// we will invoke this method to instantiate `'a` with an
|
/// we will invoke this method to instantiate `'a` with an
|
||||||
/// inference variable (though `'b` would be instantiated first,
|
/// inference variable (though `'b` would be instantiated first,
|
||||||
/// as a placeholder).
|
/// as a placeholder).
|
||||||
fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx>;
|
fn next_existential_region_var(
|
||||||
|
&mut self,
|
||||||
|
was_placeholder: bool,
|
||||||
|
name: Option<Symbol>,
|
||||||
|
) -> ty::Region<'tcx>;
|
||||||
|
|
||||||
/// Creates a new region variable representing a
|
/// Creates a new region variable representing a
|
||||||
/// higher-ranked region that is instantiated universally.
|
/// higher-ranked region that is instantiated universally.
|
||||||
|
@ -188,7 +192,7 @@ where
|
||||||
let placeholder = ty::PlaceholderRegion { universe, name: br.kind };
|
let placeholder = ty::PlaceholderRegion { universe, name: br.kind };
|
||||||
delegate.next_placeholder_region(placeholder)
|
delegate.next_placeholder_region(placeholder)
|
||||||
} else {
|
} else {
|
||||||
delegate.next_existential_region_var(true)
|
delegate.next_existential_region_var(true, br.kind.get_name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue