Auto merge of #54858 - nikomatsakis:universes-refactor-2, r=scalexm
second round of refactorings for universes A second round of (what I believe to be) "no functional change" refactorings, taken from my universes branch. r? @scalexm
This commit is contained in:
commit
5a52983d69
30 changed files with 525 additions and 490 deletions
|
|
@ -1297,7 +1297,7 @@ impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind {
|
|||
});
|
||||
|
||||
impl_stable_hash_for!(
|
||||
impl<'tcx, R> for struct infer::canonical::QueryResult<'tcx, R> {
|
||||
impl<'tcx, R> for struct infer::canonical::QueryResponse<'tcx, R> {
|
||||
var_values, region_constraints, certainty, value
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
use infer::canonical::{
|
||||
Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized,
|
||||
SmallCanonicalVarValues,
|
||||
OriginalQueryValues,
|
||||
};
|
||||
use infer::InferCtxt;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
|
@ -48,7 +48,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
pub fn canonicalize_query<V>(
|
||||
&self,
|
||||
value: &V,
|
||||
var_values: &mut SmallCanonicalVarValues<'tcx>
|
||||
query_state: &mut OriginalQueryValues<'tcx>,
|
||||
) -> Canonicalized<'gcx, V>
|
||||
where
|
||||
V: TypeFoldable<'tcx> + Lift<'gcx>,
|
||||
|
|
@ -63,11 +63,8 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
value,
|
||||
Some(self),
|
||||
self.tcx,
|
||||
CanonicalizeRegionMode {
|
||||
static_region: true,
|
||||
other_free_regions: true,
|
||||
},
|
||||
var_values,
|
||||
&CanonicalizeAllFreeRegions,
|
||||
query_state,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -96,23 +93,17 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// out the [chapter in the rustc guide][c].
|
||||
///
|
||||
/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
|
||||
pub fn canonicalize_response<V>(
|
||||
&self,
|
||||
value: &V,
|
||||
) -> Canonicalized<'gcx, V>
|
||||
pub fn canonicalize_response<V>(&self, value: &V) -> Canonicalized<'gcx, V>
|
||||
where
|
||||
V: TypeFoldable<'tcx> + Lift<'gcx>,
|
||||
{
|
||||
let mut var_values = SmallVec::new();
|
||||
let mut query_state = OriginalQueryValues::default();
|
||||
Canonicalizer::canonicalize(
|
||||
value,
|
||||
Some(self),
|
||||
self.tcx,
|
||||
CanonicalizeRegionMode {
|
||||
static_region: false,
|
||||
other_free_regions: false,
|
||||
},
|
||||
&mut var_values
|
||||
&CanonicalizeQueryResponse,
|
||||
&mut query_state,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +119,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
pub fn canonicalize_hr_query_hack<V>(
|
||||
&self,
|
||||
value: &V,
|
||||
var_values: &mut SmallCanonicalVarValues<'tcx>
|
||||
query_state: &mut OriginalQueryValues<'tcx>,
|
||||
) -> Canonicalized<'gcx, V>
|
||||
where
|
||||
V: TypeFoldable<'tcx> + Lift<'gcx>,
|
||||
|
|
@ -143,27 +134,87 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
value,
|
||||
Some(self),
|
||||
self.tcx,
|
||||
CanonicalizeRegionMode {
|
||||
static_region: false,
|
||||
other_free_regions: true,
|
||||
},
|
||||
var_values
|
||||
&CanonicalizeFreeRegionsOtherThanStatic,
|
||||
query_state,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// If this flag is true, then all free regions will be replaced with
|
||||
/// a canonical var. This is used to make queries as generic as
|
||||
/// possible. For example, the query `F: Foo<'static>` would be
|
||||
/// canonicalized to `F: Foo<'0>`.
|
||||
struct CanonicalizeRegionMode {
|
||||
static_region: bool,
|
||||
other_free_regions: bool,
|
||||
/// Controls how we canonicalize "free regions" that are not inference
|
||||
/// variables. This depends on what we are canonicalizing *for* --
|
||||
/// e.g., if we are canonicalizing to create a query, we want to
|
||||
/// replace those with inference variables, since we want to make a
|
||||
/// maximally general query. But if we are canonicalizing a *query
|
||||
/// response*, then we don't typically replace free regions, as they
|
||||
/// must have been introduced from other parts of the system.
|
||||
trait CanonicalizeRegionMode {
|
||||
fn canonicalize_free_region(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx>;
|
||||
|
||||
fn any(&self) -> bool;
|
||||
}
|
||||
|
||||
impl CanonicalizeRegionMode {
|
||||
struct CanonicalizeQueryResponse;
|
||||
|
||||
impl CanonicalizeRegionMode for CanonicalizeQueryResponse {
|
||||
fn canonicalize_free_region(
|
||||
&self,
|
||||
_canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
match r {
|
||||
ty::ReFree(_) | ty::ReEmpty | ty::ReErased | ty::ReStatic | ty::ReEarlyBound(..) => r,
|
||||
_ => {
|
||||
// Other than `'static` or `'empty`, the query
|
||||
// response should be executing in a fully
|
||||
// canonicalized environment, so there shouldn't be
|
||||
// any other region names it can come up.
|
||||
bug!("unexpected region in query response: `{:?}`", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn any(&self) -> bool {
|
||||
self.static_region || self.other_free_regions
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct CanonicalizeAllFreeRegions;
|
||||
|
||||
impl CanonicalizeRegionMode for CanonicalizeAllFreeRegions {
|
||||
fn canonicalize_free_region(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
canonicalizer.canonical_var_for_region(r)
|
||||
}
|
||||
|
||||
fn any(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
struct CanonicalizeFreeRegionsOtherThanStatic;
|
||||
|
||||
impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic {
|
||||
fn canonicalize_free_region(
|
||||
&self,
|
||||
canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
if let ty::ReStatic = r {
|
||||
r
|
||||
} else {
|
||||
canonicalizer.canonical_var_for_region(r)
|
||||
}
|
||||
}
|
||||
|
||||
fn any(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -171,11 +222,11 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
|||
infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>,
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
variables: SmallVec<[CanonicalVarInfo; 8]>,
|
||||
var_values: &'cx mut SmallCanonicalVarValues<'tcx>,
|
||||
query_state: &'cx mut OriginalQueryValues<'tcx>,
|
||||
// Note that indices is only used once `var_values` is big enough to be
|
||||
// heap-allocated.
|
||||
indices: FxHashMap<Kind<'tcx>, CanonicalVar>,
|
||||
canonicalize_region_mode: CanonicalizeRegionMode,
|
||||
canonicalize_region_mode: &'cx dyn CanonicalizeRegionMode,
|
||||
needs_canonical_flags: TypeFlags,
|
||||
}
|
||||
|
||||
|
|
@ -192,51 +243,25 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
|
|||
}
|
||||
|
||||
ty::ReVar(vid) => {
|
||||
let r = self
|
||||
.infcx
|
||||
let r = self.infcx
|
||||
.unwrap()
|
||||
.borrow_region_constraints()
|
||||
.opportunistic_resolve_var(self.tcx, vid);
|
||||
let info = CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Region,
|
||||
};
|
||||
debug!(
|
||||
"canonical: region var found with vid {:?}, \
|
||||
opportunistically resolved to {:?}",
|
||||
vid, r
|
||||
);
|
||||
let cvar = self.canonical_var(info, r.into());
|
||||
self.tcx().mk_region(ty::ReCanonical(cvar))
|
||||
self.canonical_var_for_region(r)
|
||||
}
|
||||
|
||||
ty::ReStatic => {
|
||||
if self.canonicalize_region_mode.static_region {
|
||||
let info = CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Region,
|
||||
};
|
||||
let cvar = self.canonical_var(info, r.into());
|
||||
self.tcx().mk_region(ty::ReCanonical(cvar))
|
||||
} else {
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
ty::ReEarlyBound(..)
|
||||
ty::ReStatic
|
||||
| ty::ReEarlyBound(..)
|
||||
| ty::ReFree(_)
|
||||
| ty::ReScope(_)
|
||||
| ty::RePlaceholder(..)
|
||||
| ty::ReEmpty
|
||||
| ty::ReErased => {
|
||||
if self.canonicalize_region_mode.other_free_regions {
|
||||
let info = CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Region,
|
||||
};
|
||||
let cvar = self.canonical_var(info, r.into());
|
||||
self.tcx().mk_region(ty::ReCanonical(cvar))
|
||||
} else {
|
||||
r
|
||||
}
|
||||
}
|
||||
| ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r),
|
||||
|
||||
ty::ReClosureBound(..) | ty::ReCanonical(_) => {
|
||||
bug!("canonical region encountered during canonicalization")
|
||||
|
|
@ -302,10 +327,10 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
/// `canonicalize_query` and `canonicalize_response`.
|
||||
fn canonicalize<V>(
|
||||
value: &V,
|
||||
infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>,
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
canonicalize_region_mode: CanonicalizeRegionMode,
|
||||
var_values: &'cx mut SmallCanonicalVarValues<'tcx>
|
||||
infcx: Option<&InferCtxt<'_, 'gcx, 'tcx>>,
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalize_region_mode: &dyn CanonicalizeRegionMode,
|
||||
query_state: &mut OriginalQueryValues<'tcx>,
|
||||
) -> Canonicalized<'gcx, V>
|
||||
where
|
||||
V: TypeFoldable<'tcx> + Lift<'gcx>,
|
||||
|
|
@ -340,7 +365,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
canonicalize_region_mode,
|
||||
needs_canonical_flags,
|
||||
variables: SmallVec::new(),
|
||||
var_values,
|
||||
query_state,
|
||||
indices: FxHashMap::default(),
|
||||
};
|
||||
let out_value = value.fold_with(&mut canonicalizer);
|
||||
|
|
@ -371,11 +396,13 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> CanonicalVar {
|
||||
let Canonicalizer {
|
||||
variables,
|
||||
var_values,
|
||||
query_state,
|
||||
indices,
|
||||
..
|
||||
} = self;
|
||||
|
||||
let var_values = &mut query_state.var_values;
|
||||
|
||||
// This code is hot. `variables` and `var_values` are usually small
|
||||
// (fewer than 8 elements ~95% of the time). They are SmallVec's to
|
||||
// avoid allocations in those cases. We also don't use `indices` to
|
||||
|
|
@ -398,28 +425,34 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
// fill up `indices` to facilitate subsequent lookups.
|
||||
if var_values.spilled() {
|
||||
assert!(indices.is_empty());
|
||||
*indices =
|
||||
var_values.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &kind)| (kind, CanonicalVar::new(i)))
|
||||
.collect();
|
||||
*indices = var_values
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &kind)| (kind, CanonicalVar::new(i)))
|
||||
.collect();
|
||||
}
|
||||
// The cv is the index of the appended element.
|
||||
CanonicalVar::new(var_values.len() - 1)
|
||||
}
|
||||
} else {
|
||||
// `var_values` is large. Do a hashmap search via `indices`.
|
||||
*indices
|
||||
.entry(kind)
|
||||
.or_insert_with(|| {
|
||||
variables.push(info);
|
||||
var_values.push(kind);
|
||||
assert_eq!(variables.len(), var_values.len());
|
||||
CanonicalVar::new(variables.len() - 1)
|
||||
})
|
||||
*indices.entry(kind).or_insert_with(|| {
|
||||
variables.push(info);
|
||||
var_values.push(kind);
|
||||
assert_eq!(variables.len(), var_values.len());
|
||||
CanonicalVar::new(variables.len() - 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn canonical_var_for_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
let info = CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Region,
|
||||
};
|
||||
let cvar = self.canonical_var(info, r.into());
|
||||
self.tcx().mk_region(ty::ReCanonical(cvar))
|
||||
}
|
||||
|
||||
/// Given a type variable `ty_var` of the given kind, first check
|
||||
/// if `ty_var` is bound to anything; if so, canonicalize
|
||||
/// *that*. Otherwise, create a new canonical variable for
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ use ty::{self, CanonicalVar, Lift, Region, List, TyCtxt};
|
|||
|
||||
mod canonicalizer;
|
||||
|
||||
pub mod query_result;
|
||||
pub mod query_response;
|
||||
|
||||
mod substitute;
|
||||
|
||||
|
|
@ -75,9 +75,16 @@ pub struct CanonicalVarValues<'tcx> {
|
|||
pub var_values: IndexVec<CanonicalVar, Kind<'tcx>>,
|
||||
}
|
||||
|
||||
/// Like CanonicalVarValues, but for use in places where a SmallVec is
|
||||
/// appropriate.
|
||||
pub type SmallCanonicalVarValues<'tcx> = SmallVec<[Kind<'tcx>; 8]>;
|
||||
/// When we canonicalize a value to form a query, we wind up replacing
|
||||
/// various parts of it with canonical variables. This struct stores
|
||||
/// those replaced bits to remember for when we process the query
|
||||
/// result.
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
|
||||
pub struct OriginalQueryValues<'tcx> {
|
||||
/// This is equivalent to `CanonicalVarValues`, but using a
|
||||
/// `SmallVec` yields a significant performance win.
|
||||
pub var_values: SmallVec<[Kind<'tcx>; 8]>,
|
||||
}
|
||||
|
||||
/// Information about a canonical variable that is included with the
|
||||
/// canonical value. This is sufficient information for code to create
|
||||
|
|
@ -118,10 +125,10 @@ pub enum CanonicalTyVarKind {
|
|||
}
|
||||
|
||||
/// After we execute a query with a canonicalized key, we get back a
|
||||
/// `Canonical<QueryResult<..>>`. You can use
|
||||
/// `Canonical<QueryResponse<..>>`. You can use
|
||||
/// `instantiate_query_result` to access the data in this result.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct QueryResult<'tcx, R> {
|
||||
pub struct QueryResponse<'tcx, R> {
|
||||
pub var_values: CanonicalVarValues<'tcx>,
|
||||
pub region_constraints: Vec<QueryRegionConstraint<'tcx>>,
|
||||
pub certainty: Certainty,
|
||||
|
|
@ -130,8 +137,8 @@ pub struct QueryResult<'tcx, R> {
|
|||
|
||||
pub type Canonicalized<'gcx, V> = Canonical<'gcx, <V as Lift<'gcx>>::Lifted>;
|
||||
|
||||
pub type CanonicalizedQueryResult<'gcx, T> =
|
||||
Lrc<Canonical<'gcx, QueryResult<'gcx, <T as Lift<'gcx>>::Lifted>>>;
|
||||
pub type CanonicalizedQueryResponse<'gcx, T> =
|
||||
Lrc<Canonical<'gcx, QueryResponse<'gcx, <T as Lift<'gcx>>::Lifted>>>;
|
||||
|
||||
/// Indicates whether or not we were able to prove the query to be
|
||||
/// true.
|
||||
|
|
@ -168,7 +175,7 @@ impl Certainty {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, R> QueryResult<'tcx, R> {
|
||||
impl<'tcx, R> QueryResponse<'tcx, R> {
|
||||
pub fn is_proven(&self) -> bool {
|
||||
self.certainty.is_proven()
|
||||
}
|
||||
|
|
@ -178,7 +185,7 @@ impl<'tcx, R> QueryResult<'tcx, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, R> Canonical<'tcx, QueryResult<'tcx, R>> {
|
||||
impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> {
|
||||
pub fn is_proven(&self) -> bool {
|
||||
self.value.is_proven()
|
||||
}
|
||||
|
|
@ -225,12 +232,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// inference variables and applies it to the canonical value.
|
||||
/// Returns both the instantiated result *and* the substitution S.
|
||||
///
|
||||
/// This is useful at the start of a query: it basically brings
|
||||
/// the canonical value "into scope" within your new infcx. At the
|
||||
/// end of processing, the substitution S (once canonicalized)
|
||||
/// then represents the values that you computed for each of the
|
||||
/// canonical inputs to your query.
|
||||
pub fn instantiate_canonical_with_fresh_inference_vars<T>(
|
||||
/// This is only meant to be invoked as part of constructing an
|
||||
/// inference context at the start of a query (see
|
||||
/// `InferCtxtBuilder::enter_with_canonical`). It basically
|
||||
/// brings the canonical value "into scope" within your new infcx.
|
||||
///
|
||||
/// At the end of processing, the substitution S (once
|
||||
/// canonicalized) then represents the values that you computed
|
||||
/// for each of the canonical inputs to your query.
|
||||
|
||||
pub(in infer) fn instantiate_canonical_with_fresh_inference_vars<T>(
|
||||
&self,
|
||||
span: Span,
|
||||
canonical: &Canonical<'tcx, T>,
|
||||
|
|
@ -238,6 +249,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
assert_eq!(self.universe(), ty::UniverseIndex::ROOT, "infcx not newly created");
|
||||
assert_eq!(self.type_variables.borrow().num_vars(), 0, "infcx not newly created");
|
||||
|
||||
let canonical_inference_vars =
|
||||
self.fresh_inference_vars_for_canonical_vars(span, canonical.variables);
|
||||
let result = canonical.substitute(self.tcx, &canonical_inference_vars);
|
||||
|
|
@ -344,14 +358,14 @@ BraceStructTypeFoldableImpl! {
|
|||
}
|
||||
|
||||
BraceStructTypeFoldableImpl! {
|
||||
impl<'tcx, R> TypeFoldable<'tcx> for QueryResult<'tcx, R> {
|
||||
impl<'tcx, R> TypeFoldable<'tcx> for QueryResponse<'tcx, R> {
|
||||
var_values, region_constraints, certainty, value
|
||||
} where R: TypeFoldable<'tcx>,
|
||||
}
|
||||
|
||||
BraceStructLiftImpl! {
|
||||
impl<'a, 'tcx, R> Lift<'tcx> for QueryResult<'a, R> {
|
||||
type Lifted = QueryResult<'tcx, R::Lifted>;
|
||||
impl<'a, 'tcx, R> Lift<'tcx> for QueryResponse<'a, R> {
|
||||
type Lifted = QueryResponse<'tcx, R::Lifted>;
|
||||
var_values, region_constraints, certainty, value
|
||||
} where R: Lift<'tcx>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
use infer::canonical::substitute::substitute_value;
|
||||
use infer::canonical::{
|
||||
Canonical, CanonicalVarKind, CanonicalVarValues, CanonicalizedQueryResult, Certainty,
|
||||
QueryRegionConstraint, QueryResult, SmallCanonicalVarValues,
|
||||
Canonical, CanonicalVarKind, CanonicalVarValues, CanonicalizedQueryResponse, Certainty,
|
||||
OriginalQueryValues, QueryRegionConstraint, QueryResponse,
|
||||
};
|
||||
use infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use infer::InferCtxtBuilder;
|
||||
|
|
@ -59,18 +59,20 @@ impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> {
|
|||
canonical_key: &Canonical<'tcx, K>,
|
||||
operation: impl FnOnce(&InferCtxt<'_, 'gcx, 'tcx>, &mut FulfillmentContext<'tcx>, K)
|
||||
-> Fallible<R>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, R>>
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, R>>
|
||||
where
|
||||
K: TypeFoldable<'tcx>,
|
||||
R: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
|
||||
{
|
||||
self.enter(|ref infcx| {
|
||||
let (key, canonical_inference_vars) =
|
||||
infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_key);
|
||||
let fulfill_cx = &mut FulfillmentContext::new();
|
||||
let value = operation(infcx, fulfill_cx, key)?;
|
||||
infcx.make_canonicalized_query_result(canonical_inference_vars, value, fulfill_cx)
|
||||
})
|
||||
self.enter_with_canonical(
|
||||
DUMMY_SP,
|
||||
canonical_key,
|
||||
|ref infcx, key, canonical_inference_vars| {
|
||||
let fulfill_cx = &mut FulfillmentContext::new();
|
||||
let value = operation(infcx, fulfill_cx, key)?;
|
||||
infcx.make_canonicalized_query_response(canonical_inference_vars, value, fulfill_cx)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,41 +96,41 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// the same thing happens, but the resulting query is marked as ambiguous.
|
||||
/// - Finally, if any of the obligations result in a hard error,
|
||||
/// then `Err(NoSolution)` is returned.
|
||||
pub fn make_canonicalized_query_result<T>(
|
||||
pub fn make_canonicalized_query_response<T>(
|
||||
&self,
|
||||
inference_vars: CanonicalVarValues<'tcx>,
|
||||
answer: T,
|
||||
fulfill_cx: &mut FulfillmentContext<'tcx>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, T>>
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, T>>
|
||||
where
|
||||
T: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
|
||||
{
|
||||
let query_result = self.make_query_result(inference_vars, answer, fulfill_cx)?;
|
||||
let canonical_result = self.canonicalize_response(&query_result);
|
||||
let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
|
||||
let canonical_result = self.canonicalize_response(&query_response);
|
||||
|
||||
debug!(
|
||||
"make_canonicalized_query_result: canonical_result = {:#?}",
|
||||
"make_canonicalized_query_response: canonical_result = {:#?}",
|
||||
canonical_result
|
||||
);
|
||||
|
||||
Ok(Lrc::new(canonical_result))
|
||||
}
|
||||
|
||||
/// Helper for `make_canonicalized_query_result` that does
|
||||
/// Helper for `make_canonicalized_query_response` that does
|
||||
/// everything up until the final canonicalization.
|
||||
fn make_query_result<T>(
|
||||
fn make_query_response<T>(
|
||||
&self,
|
||||
inference_vars: CanonicalVarValues<'tcx>,
|
||||
answer: T,
|
||||
fulfill_cx: &mut FulfillmentContext<'tcx>,
|
||||
) -> Result<QueryResult<'tcx, T>, NoSolution>
|
||||
) -> Result<QueryResponse<'tcx, T>, NoSolution>
|
||||
where
|
||||
T: Debug + TypeFoldable<'tcx> + Lift<'gcx>,
|
||||
{
|
||||
let tcx = self.tcx;
|
||||
|
||||
debug!(
|
||||
"make_query_result(\
|
||||
"make_query_response(\
|
||||
inference_vars={:?}, \
|
||||
answer={:?})",
|
||||
inference_vars, answer,
|
||||
|
|
@ -140,7 +142,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
|
||||
if !true_errors.is_empty() {
|
||||
// FIXME -- we don't indicate *why* we failed to solve
|
||||
debug!("make_query_result: true_errors={:#?}", true_errors);
|
||||
debug!("make_query_response: true_errors={:#?}", true_errors);
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
|
|
@ -155,7 +157,8 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
region_obligations
|
||||
.iter()
|
||||
.map(|(_, r_o)| (r_o.sup_type, r_o.sub_region)),
|
||||
region_constraints)
|
||||
region_constraints,
|
||||
)
|
||||
});
|
||||
|
||||
let certainty = if ambig_errors.is_empty() {
|
||||
|
|
@ -164,7 +167,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
Certainty::Ambiguous
|
||||
};
|
||||
|
||||
Ok(QueryResult {
|
||||
Ok(QueryResponse {
|
||||
var_values: inference_vars,
|
||||
region_constraints,
|
||||
certainty,
|
||||
|
|
@ -182,12 +185,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// out the [chapter in the rustc guide][c].
|
||||
///
|
||||
/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
|
||||
pub fn instantiate_query_result_and_region_obligations<R>(
|
||||
pub fn instantiate_query_response_and_region_obligations<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: &SmallCanonicalVarValues<'tcx>,
|
||||
query_result: &Canonical<'tcx, QueryResult<'tcx, R>>,
|
||||
original_values: &OriginalQueryValues<'tcx>,
|
||||
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
|
||||
) -> InferResult<'tcx, R>
|
||||
where
|
||||
R: Debug + TypeFoldable<'tcx>,
|
||||
|
|
@ -195,17 +198,17 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
let InferOk {
|
||||
value: result_subst,
|
||||
mut obligations,
|
||||
} = self.query_result_substitution(cause, param_env, original_values, query_result)?;
|
||||
} = self.query_response_substitution(cause, param_env, original_values, query_response)?;
|
||||
|
||||
obligations.extend(self.query_region_constraints_into_obligations(
|
||||
cause,
|
||||
param_env,
|
||||
&query_result.value.region_constraints,
|
||||
&query_response.value.region_constraints,
|
||||
&result_subst,
|
||||
));
|
||||
|
||||
let user_result: R =
|
||||
query_result.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
|
||||
query_response.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
|
||||
|
||||
Ok(InferOk {
|
||||
value: user_result,
|
||||
|
|
@ -214,7 +217,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
/// An alternative to
|
||||
/// `instantiate_query_result_and_region_obligations` that is more
|
||||
/// `instantiate_query_response_and_region_obligations` that is more
|
||||
/// efficient for NLL. NLL is a bit more advanced in the
|
||||
/// "transition to chalk" than the rest of the compiler. During
|
||||
/// the NLL type check, all of the "processing" of types and
|
||||
|
|
@ -229,8 +232,8 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// into the older infcx-style constraints (e.g., calls to
|
||||
/// `sub_regions` or `register_region_obligation`).
|
||||
///
|
||||
/// Therefore, `instantiate_nll_query_result_and_region_obligations` performs the same
|
||||
/// basic operations as `instantiate_query_result_and_region_obligations` but
|
||||
/// Therefore, `instantiate_nll_query_response_and_region_obligations` performs the same
|
||||
/// basic operations as `instantiate_query_response_and_region_obligations` but
|
||||
/// it returns its result differently:
|
||||
///
|
||||
/// - It creates a substitution `S` that maps from the original
|
||||
|
|
@ -248,12 +251,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// are propagated back in the return value.
|
||||
/// - Finally, the query result (of type `R`) is propagated back,
|
||||
/// after applying the substitution `S`.
|
||||
pub fn instantiate_nll_query_result_and_region_obligations<R>(
|
||||
pub fn instantiate_nll_query_response_and_region_obligations<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: &SmallCanonicalVarValues<'tcx>,
|
||||
query_result: &Canonical<'tcx, QueryResult<'tcx, R>>,
|
||||
original_values: &OriginalQueryValues<'tcx>,
|
||||
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
|
||||
output_query_region_constraints: &mut Vec<QueryRegionConstraint<'tcx>>,
|
||||
) -> InferResult<'tcx, R>
|
||||
where
|
||||
|
|
@ -261,22 +264,22 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
{
|
||||
// In an NLL query, there should be no type variables in the
|
||||
// query, only region variables.
|
||||
debug_assert!(query_result.variables.iter().all(|v| match v.kind {
|
||||
debug_assert!(query_response.variables.iter().all(|v| match v.kind {
|
||||
CanonicalVarKind::Ty(_) => false,
|
||||
CanonicalVarKind::Region => true,
|
||||
}));
|
||||
|
||||
let result_subst =
|
||||
self.query_result_substitution_guess(cause, original_values, query_result);
|
||||
self.query_response_substitution_guess(cause, original_values, query_response);
|
||||
|
||||
// Compute `QueryRegionConstraint` values that unify each of
|
||||
// the original values `v_o` that was canonicalized into a
|
||||
// variable...
|
||||
let mut obligations = vec![];
|
||||
|
||||
for (index, original_value) in original_values.iter().enumerate() {
|
||||
for (index, original_value) in original_values.var_values.iter().enumerate() {
|
||||
// ...with the value `v_r` of that variable from the query.
|
||||
let result_value = query_result.substitute_projected(self.tcx, &result_subst, |v| {
|
||||
let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| {
|
||||
&v.var_values[CanonicalVar::new(index)]
|
||||
});
|
||||
match (original_value.unpack(), result_value.unpack()) {
|
||||
|
|
@ -311,7 +314,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
|
||||
// ...also include the other query region constraints from the query.
|
||||
output_query_region_constraints.extend(
|
||||
query_result.value.region_constraints.iter().filter_map(|r_c| {
|
||||
query_response.value.region_constraints.iter().filter_map(|r_c| {
|
||||
let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
|
||||
let k1 = substitute_value(self.tcx, &result_subst, &k1);
|
||||
let r2 = substitute_value(self.tcx, &result_subst, &r2);
|
||||
|
|
@ -324,7 +327,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
);
|
||||
|
||||
let user_result: R =
|
||||
query_result.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
|
||||
query_response.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
|
||||
|
||||
Ok(InferOk {
|
||||
value: user_result,
|
||||
|
|
@ -342,30 +345,30 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// example) we are doing lazy normalization and the value
|
||||
/// assigned to a type variable is unified with an unnormalized
|
||||
/// projection.
|
||||
fn query_result_substitution<R>(
|
||||
fn query_response_substitution<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: &SmallCanonicalVarValues<'tcx>,
|
||||
query_result: &Canonical<'tcx, QueryResult<'tcx, R>>,
|
||||
original_values: &OriginalQueryValues<'tcx>,
|
||||
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
|
||||
) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
|
||||
where
|
||||
R: Debug + TypeFoldable<'tcx>,
|
||||
{
|
||||
debug!(
|
||||
"query_result_substitution(original_values={:#?}, query_result={:#?})",
|
||||
original_values, query_result,
|
||||
"query_response_substitution(original_values={:#?}, query_response={:#?})",
|
||||
original_values, query_response,
|
||||
);
|
||||
|
||||
let result_subst =
|
||||
self.query_result_substitution_guess(cause, original_values, query_result);
|
||||
self.query_response_substitution_guess(cause, original_values, query_response);
|
||||
|
||||
let obligations = self.unify_query_result_substitution_guess(
|
||||
let obligations = self.unify_query_response_substitution_guess(
|
||||
cause,
|
||||
param_env,
|
||||
original_values,
|
||||
&result_subst,
|
||||
query_result,
|
||||
query_response,
|
||||
)?
|
||||
.into_obligations();
|
||||
|
||||
|
|
@ -384,26 +387,26 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// will instantiate fresh inference variables for each canonical
|
||||
/// variable instead. Therefore, the result of this method must be
|
||||
/// properly unified
|
||||
fn query_result_substitution_guess<R>(
|
||||
fn query_response_substitution_guess<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
original_values: &SmallCanonicalVarValues<'tcx>,
|
||||
query_result: &Canonical<'tcx, QueryResult<'tcx, R>>,
|
||||
original_values: &OriginalQueryValues<'tcx>,
|
||||
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
|
||||
) -> CanonicalVarValues<'tcx>
|
||||
where
|
||||
R: Debug + TypeFoldable<'tcx>,
|
||||
{
|
||||
debug!(
|
||||
"query_result_substitution_guess(original_values={:#?}, query_result={:#?})",
|
||||
original_values, query_result,
|
||||
"query_response_substitution_guess(original_values={:#?}, query_response={:#?})",
|
||||
original_values, query_response,
|
||||
);
|
||||
|
||||
// Every canonical query result includes values for each of
|
||||
// the inputs to the query. Therefore, we begin by unifying
|
||||
// these values with the original inputs that were
|
||||
// canonicalized.
|
||||
let result_values = &query_result.value.var_values;
|
||||
assert_eq!(original_values.len(), result_values.len());
|
||||
let result_values = &query_response.value.var_values;
|
||||
assert_eq!(original_values.var_values.len(), result_values.len());
|
||||
|
||||
// Quickly try to find initial values for the canonical
|
||||
// variables in the result in terms of the query. We do this
|
||||
|
|
@ -413,11 +416,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
// result, then we can type the corresponding value from the
|
||||
// input. See the example above.
|
||||
let mut opt_values: IndexVec<CanonicalVar, Option<Kind<'tcx>>> =
|
||||
IndexVec::from_elem_n(None, query_result.variables.len());
|
||||
IndexVec::from_elem_n(None, query_response.variables.len());
|
||||
|
||||
// In terms of our example above, we are iterating over pairs like:
|
||||
// [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
|
||||
for (original_value, result_value) in original_values.iter().zip(result_values) {
|
||||
for (original_value, result_value) in original_values.var_values.iter().zip(result_values) {
|
||||
match result_value.unpack() {
|
||||
UnpackedKind::Type(result_value) => {
|
||||
// e.g., here `result_value` might be `?0` in the example above...
|
||||
|
|
@ -440,7 +443,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
// given variable in the loop above, use that. Otherwise, use
|
||||
// a fresh inference variable.
|
||||
let result_subst = CanonicalVarValues {
|
||||
var_values: query_result
|
||||
var_values: query_response
|
||||
.variables
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
|
@ -458,29 +461,34 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// query result. Often, but not always, this is a no-op, because
|
||||
/// we already found the mapping in the "guessing" step.
|
||||
///
|
||||
/// See also: `query_result_substitution_guess`
|
||||
fn unify_query_result_substitution_guess<R>(
|
||||
/// See also: `query_response_substitution_guess`
|
||||
fn unify_query_response_substitution_guess<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: &SmallCanonicalVarValues<'tcx>,
|
||||
original_values: &OriginalQueryValues<'tcx>,
|
||||
result_subst: &CanonicalVarValues<'tcx>,
|
||||
query_result: &Canonical<'tcx, QueryResult<'tcx, R>>,
|
||||
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
|
||||
) -> InferResult<'tcx, ()>
|
||||
where
|
||||
R: Debug + TypeFoldable<'tcx>,
|
||||
{
|
||||
// A closure that yields the result value for the given
|
||||
// canonical variable; this is taken from
|
||||
// `query_result.var_values` after applying the substitution
|
||||
// `query_response.var_values` after applying the substitution
|
||||
// `result_subst`.
|
||||
let substituted_query_result = |index: CanonicalVar| -> Kind<'tcx> {
|
||||
query_result.substitute_projected(self.tcx, &result_subst, |v| &v.var_values[index])
|
||||
let substituted_query_response = |index: CanonicalVar| -> Kind<'tcx> {
|
||||
query_response.substitute_projected(self.tcx, &result_subst, |v| &v.var_values[index])
|
||||
};
|
||||
|
||||
// Unify the original value for each variable with the value
|
||||
// taken from `query_result` (after applying `result_subst`).
|
||||
Ok(self.unify_canonical_vars(cause, param_env, original_values, substituted_query_result)?)
|
||||
// taken from `query_response` (after applying `result_subst`).
|
||||
Ok(self.unify_canonical_vars(
|
||||
cause,
|
||||
param_env,
|
||||
original_values,
|
||||
substituted_query_response,
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Converts the region constraints resulting from a query into an
|
||||
|
|
@ -524,12 +532,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
variables1: &SmallCanonicalVarValues<'tcx>,
|
||||
variables1: &OriginalQueryValues<'tcx>,
|
||||
variables2: impl Fn(CanonicalVar) -> Kind<'tcx>,
|
||||
) -> InferResult<'tcx, ()> {
|
||||
self.commit_if_ok(|_| {
|
||||
let mut obligations = vec![];
|
||||
for (index, value1) in variables1.iter().enumerate() {
|
||||
for (index, value1) in variables1.var_values.iter().enumerate() {
|
||||
let value2 = variables2(CanonicalVar::new(index));
|
||||
|
||||
match (value1.unpack(), value2.unpack()) {
|
||||
|
|
@ -593,11 +593,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
where
|
||||
T : TypeFoldable<'tcx>,
|
||||
{
|
||||
let new_universe = self.create_subuniverse();
|
||||
let next_universe = self.create_next_universe();
|
||||
|
||||
let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
|
||||
self.tcx.mk_region(ty::RePlaceholder(ty::Placeholder {
|
||||
universe: new_universe,
|
||||
universe: next_universe,
|
||||
name: br,
|
||||
}))
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ pub use ty::IntVarValue;
|
|||
use arena::SyncDroplessArena;
|
||||
use errors::DiagnosticBuilder;
|
||||
use hir::def_id::DefId;
|
||||
use infer::canonical::{Canonical, CanonicalVarValues};
|
||||
use middle::free_region::RegionRelations;
|
||||
use middle::lang_items;
|
||||
use middle::region;
|
||||
|
|
@ -49,7 +50,6 @@ use self::region_constraints::{RegionConstraintCollector, RegionSnapshot};
|
|||
use self::type_variable::TypeVariableOrigin;
|
||||
use self::unify_key::ToType;
|
||||
|
||||
pub mod opaque_types;
|
||||
pub mod at;
|
||||
pub mod canonical;
|
||||
mod combine;
|
||||
|
|
@ -62,6 +62,7 @@ mod higher_ranked;
|
|||
pub mod lattice;
|
||||
mod lexical_region_resolve;
|
||||
mod lub;
|
||||
pub mod opaque_types;
|
||||
pub mod outlives;
|
||||
pub mod region_constraints;
|
||||
pub mod resolve;
|
||||
|
|
@ -86,7 +87,7 @@ pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
|
|||
/// NLL borrow checker will also do -- it might be set to true.
|
||||
#[derive(Copy, Clone, Default, Debug)]
|
||||
pub struct SuppressRegionErrors {
|
||||
suppressed: bool
|
||||
suppressed: bool,
|
||||
}
|
||||
|
||||
impl SuppressRegionErrors {
|
||||
|
|
@ -100,15 +101,11 @@ impl SuppressRegionErrors {
|
|||
pub fn when_nll_is_enabled(tcx: TyCtxt<'_, '_, '_>) -> Self {
|
||||
match tcx.borrowck_mode() {
|
||||
// If we're on AST or Migrate mode, report AST region errors
|
||||
BorrowckMode::Ast | BorrowckMode::Migrate => SuppressRegionErrors {
|
||||
suppressed: false
|
||||
},
|
||||
BorrowckMode::Ast | BorrowckMode::Migrate => SuppressRegionErrors { suppressed: false },
|
||||
|
||||
// If we're on MIR or Compare mode, don't report AST region errors as they should
|
||||
// be reported by NLL
|
||||
BorrowckMode::Compare | BorrowckMode::Mir => SuppressRegionErrors {
|
||||
suppressed: true
|
||||
},
|
||||
BorrowckMode::Compare | BorrowckMode::Mir => SuppressRegionErrors { suppressed: true },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -494,10 +491,30 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn enter<F, R>(&'tcx mut self, f: F) -> R
|
||||
/// Given a canonical value `C` as a starting point, create an
|
||||
/// inference context that contains each of the bound values
|
||||
/// within instantiated as a fresh variable. The `f` closure is
|
||||
/// invoked with the new infcx, along with the instantiated value
|
||||
/// `V` and a substitution `S`. This substitution `S` maps from
|
||||
/// the bound values in `C` to their instantiated values in `V`
|
||||
/// (in other words, `S(C) = V`).
|
||||
pub fn enter_with_canonical<T, R>(
|
||||
&'tcx mut self,
|
||||
span: Span,
|
||||
canonical: &Canonical<'tcx, T>,
|
||||
f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>, T, CanonicalVarValues<'tcx>) -> R,
|
||||
) -> R
|
||||
where
|
||||
F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R,
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
self.enter(|infcx| {
|
||||
let (value, subst) =
|
||||
infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
|
||||
f(infcx, value, subst)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R {
|
||||
let InferCtxtBuilder {
|
||||
global_tcx,
|
||||
ref arena,
|
||||
|
|
@ -1472,13 +1489,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
self.universe.get()
|
||||
}
|
||||
|
||||
/// Create and return a new subunivese of the current universe;
|
||||
/// update `self.universe` to that new subuniverse. At present,
|
||||
/// used only in the NLL subtyping code, which uses the new
|
||||
/// universe-based scheme instead of the more limited leak-check
|
||||
/// scheme.
|
||||
pub fn create_subuniverse(&self) -> ty::UniverseIndex {
|
||||
let u = self.universe.get().subuniverse();
|
||||
/// Create and return a fresh universe that extends all previous
|
||||
/// universes. Updates `self.universe` to that new universe.
|
||||
pub fn create_next_universe(&self) -> ty::UniverseIndex {
|
||||
let u = self.universe.get().next_universe();
|
||||
self.universe.set(u);
|
||||
u
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use infer::at::At;
|
||||
use infer::InferOk;
|
||||
use smallvec::SmallVec;
|
||||
use infer::canonical::OriginalQueryValues;
|
||||
use std::iter::FromIterator;
|
||||
use syntax::source_map::Span;
|
||||
use ty::subst::Kind;
|
||||
|
|
@ -51,14 +51,14 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
let gcx = tcx.global_tcx();
|
||||
let mut orig_values = SmallVec::new();
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
let c_ty = self.infcx.canonicalize_query(&self.param_env.and(ty), &mut orig_values);
|
||||
let span = self.cause.span;
|
||||
debug!("c_ty = {:?}", c_ty);
|
||||
match &gcx.dropck_outlives(c_ty) {
|
||||
Ok(result) if result.is_proven() => {
|
||||
if let Ok(InferOk { value, obligations }) =
|
||||
self.infcx.instantiate_query_result_and_region_obligations(
|
||||
self.infcx.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
use infer::InferCtxt;
|
||||
use smallvec::SmallVec;
|
||||
use infer::canonical::OriginalQueryValues;
|
||||
use traits::{EvaluationResult, PredicateObligation, SelectionContext,
|
||||
TraitQueryMode, OverflowError};
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
let mut _orig_values = SmallVec::new();
|
||||
let mut _orig_values = OriginalQueryValues::default();
|
||||
let c_pred = self.canonicalize_query(&obligation.param_env.and(obligation.predicate),
|
||||
&mut _orig_values);
|
||||
// Run canonical query. If overflow occurs, rerun from scratch but this time
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@
|
|||
//! `normalize_projection_ty` query when it encounters projections.
|
||||
|
||||
use infer::at::At;
|
||||
use infer::canonical::OriginalQueryValues;
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use mir::interpret::{ConstValue, GlobalId};
|
||||
use smallvec::SmallVec;
|
||||
use traits::project::Normalized;
|
||||
use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
|
||||
use ty::fold::{TypeFoldable, TypeFolder};
|
||||
|
|
@ -154,7 +154,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
|
|||
|
||||
let gcx = self.infcx.tcx.global_tcx();
|
||||
|
||||
let mut orig_values = SmallVec::new();
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
let c_data = self.infcx.canonicalize_query(
|
||||
&self.param_env.and(*data), &mut orig_values);
|
||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||
|
|
@ -167,7 +167,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
|
|||
return ty;
|
||||
}
|
||||
|
||||
match self.infcx.instantiate_query_result_and_region_obligations(
|
||||
match self.infcx.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
// except according to those terms.
|
||||
|
||||
use infer::InferCtxt;
|
||||
use infer::canonical::OriginalQueryValues;
|
||||
use syntax::ast;
|
||||
use syntax::source_map::Span;
|
||||
use smallvec::SmallVec;
|
||||
use traits::{FulfillmentContext, ObligationCause, TraitEngine, TraitEngineExt};
|
||||
use traits::query::NoSolution;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
|
|
@ -105,7 +105,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
) -> Vec<OutlivesBound<'tcx>> {
|
||||
debug!("implied_outlives_bounds(ty = {:?})", ty);
|
||||
|
||||
let mut orig_values = SmallVec::new();
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
let key = self.canonicalize_query(¶m_env.and(ty), &mut orig_values);
|
||||
let result = match self.tcx.global_tcx().implied_outlives_bounds(key) {
|
||||
Ok(r) => r,
|
||||
|
|
@ -119,7 +119,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
};
|
||||
assert!(result.value.is_proven());
|
||||
|
||||
let result = self.instantiate_query_result_and_region_obligations(
|
||||
let result = self.instantiate_query_response_and_region_obligations(
|
||||
&ObligationCause::misc(span, body_id), param_env, &orig_values, &result);
|
||||
debug!("implied_outlives_bounds for {:?}: {:#?}", ty, result);
|
||||
let result = match result {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use infer::{InferCtxt, InferOk};
|
|||
use std::fmt;
|
||||
use traits::query::Fallible;
|
||||
|
||||
use infer::canonical::query_result;
|
||||
use infer::canonical::query_response;
|
||||
use infer::canonical::QueryRegionConstraint;
|
||||
use std::rc::Rc;
|
||||
use syntax::source_map::DUMMY_SP;
|
||||
|
|
@ -102,7 +102,7 @@ fn scrape_region_constraints<'gcx, 'tcx, R>(
|
|||
|
||||
let region_constraint_data = infcx.take_and_reset_region_constraints();
|
||||
|
||||
let outlives = query_result::make_query_outlives(
|
||||
let outlives = query_response::make_query_outlives(
|
||||
infcx.tcx,
|
||||
region_obligations
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
|
||||
use traits::query::Fallible;
|
||||
use ty::{ParamEnvAnd, Ty, TyCtxt};
|
||||
|
||||
|
|
@ -25,12 +25,12 @@ impl<'tcx> Eq<'tcx> {
|
|||
}
|
||||
|
||||
impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> {
|
||||
type QueryResult = ();
|
||||
type QueryResponse = ();
|
||||
|
||||
fn try_fast_path(
|
||||
_tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
key: &ParamEnvAnd<'tcx, Eq<'tcx>>,
|
||||
) -> Option<Self::QueryResult> {
|
||||
) -> Option<Self::QueryResponse> {
|
||||
if key.value.a == key.value.b {
|
||||
Some(())
|
||||
} else {
|
||||
|
|
@ -41,13 +41,13 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> {
|
|||
fn perform_query(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, ()>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
|
||||
tcx.type_op_eq(canonicalized)
|
||||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, ()>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, ()>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, ()>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
|
||||
use traits::query::outlives_bounds::OutlivesBound;
|
||||
use traits::query::Fallible;
|
||||
use ty::{ParamEnvAnd, Ty, TyCtxt};
|
||||
|
|
@ -25,19 +25,19 @@ impl<'tcx> ImpliedOutlivesBounds<'tcx> {
|
|||
}
|
||||
|
||||
impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ImpliedOutlivesBounds<'tcx> {
|
||||
type QueryResult = Vec<OutlivesBound<'tcx>>;
|
||||
type QueryResponse = Vec<OutlivesBound<'tcx>>;
|
||||
|
||||
fn try_fast_path(
|
||||
_tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
_key: &ParamEnvAnd<'tcx, Self>,
|
||||
) -> Option<Self::QueryResult> {
|
||||
) -> Option<Self::QueryResponse> {
|
||||
None
|
||||
}
|
||||
|
||||
fn perform_query(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self::QueryResult>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>> {
|
||||
// FIXME the query should take a `ImpliedOutlivesBounds`
|
||||
let Canonical {
|
||||
variables,
|
||||
|
|
@ -56,8 +56,8 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ImpliedOutlivesBounds<
|
|||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, Self::QueryResult>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self::QueryResult>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, Self::QueryResponse>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>> {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryRegionConstraint,
|
||||
QueryResult};
|
||||
use infer::canonical::{
|
||||
Canonical, Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues,
|
||||
QueryRegionConstraint, QueryResponse,
|
||||
};
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use smallvec::SmallVec;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
use traits::query::Fallible;
|
||||
|
|
@ -55,7 +56,7 @@ pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
|
|||
pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
|
||||
fmt::Debug + Sized + TypeFoldable<'tcx> + Lift<'gcx>
|
||||
{
|
||||
type QueryResult: TypeFoldable<'tcx> + Lift<'gcx>;
|
||||
type QueryResponse: TypeFoldable<'tcx> + Lift<'gcx>;
|
||||
|
||||
/// Give query the option for a simple fast path that never
|
||||
/// actually hits the tcx cache lookup etc. Return `Some(r)` with
|
||||
|
|
@ -63,7 +64,7 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
|
|||
fn try_fast_path(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
key: &ParamEnvAnd<'tcx, Self>,
|
||||
) -> Option<Self::QueryResult>;
|
||||
) -> Option<Self::QueryResponse>;
|
||||
|
||||
/// Performs the actual query with the canonicalized key -- the
|
||||
/// real work happens here. This method is not given an `infcx`
|
||||
|
|
@ -74,29 +75,29 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
|
|||
fn perform_query(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self::QueryResult>>;
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>>;
|
||||
|
||||
/// Casts a lifted query result (which is in the gcx lifetime)
|
||||
/// into the tcx lifetime. This is always just an identity cast,
|
||||
/// but the generic code doesn't realize it -- put another way, in
|
||||
/// the generic code, we have a `Lifted<'gcx, Self::QueryResult>`
|
||||
/// and we want to convert that to a `Self::QueryResult`. This is
|
||||
/// the generic code, we have a `Lifted<'gcx, Self::QueryResponse>`
|
||||
/// and we want to convert that to a `Self::QueryResponse`. This is
|
||||
/// not a priori valid, so we can't do it -- but in practice, it
|
||||
/// is always a no-op (e.g., the lifted form of a type,
|
||||
/// `Ty<'gcx>`, is a subtype of `Ty<'tcx>`). So we have to push
|
||||
/// the operation into the impls that know more specifically what
|
||||
/// `QueryResult` is. This operation would (maybe) be nicer with
|
||||
/// `QueryResponse` is. This operation would (maybe) be nicer with
|
||||
/// something like HKTs or GATs, since then we could make
|
||||
/// `QueryResult` parametric and `'gcx` and `'tcx` etc.
|
||||
/// `QueryResponse` parametric and `'gcx` and `'tcx` etc.
|
||||
fn shrink_to_tcx_lifetime(
|
||||
lifted_query_result: &'a CanonicalizedQueryResult<'gcx, Self::QueryResult>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self::QueryResult>>;
|
||||
lifted_query_result: &'a CanonicalizedQueryResponse<'gcx, Self::QueryResponse>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>>;
|
||||
|
||||
fn fully_perform_into(
|
||||
query_key: ParamEnvAnd<'tcx, Self>,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
output_query_region_constraints: &mut Vec<QueryRegionConstraint<'tcx>>,
|
||||
) -> Fallible<Self::QueryResult> {
|
||||
) -> Fallible<Self::QueryResponse> {
|
||||
if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) {
|
||||
return Ok(result);
|
||||
}
|
||||
|
|
@ -105,7 +106,7 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
|
|||
// `canonicalize_hr_query_hack` here because of things
|
||||
// like the subtype query, which go awry around
|
||||
// `'static` otherwise.
|
||||
let mut canonical_var_values = SmallVec::new();
|
||||
let mut canonical_var_values = OriginalQueryValues::default();
|
||||
let canonical_self =
|
||||
infcx.canonicalize_hr_query_hack(&query_key, &mut canonical_var_values);
|
||||
let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;
|
||||
|
|
@ -114,7 +115,7 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
|
|||
let param_env = query_key.param_env;
|
||||
|
||||
let InferOk { value, obligations } = infcx
|
||||
.instantiate_nll_query_result_and_region_obligations(
|
||||
.instantiate_nll_query_response_and_region_obligations(
|
||||
&ObligationCause::dummy(),
|
||||
param_env,
|
||||
&canonical_var_values,
|
||||
|
|
@ -145,7 +146,7 @@ impl<'gcx: 'tcx, 'tcx, Q> TypeOp<'gcx, 'tcx> for ParamEnvAnd<'tcx, Q>
|
|||
where
|
||||
Q: QueryTypeOp<'gcx, 'tcx>,
|
||||
{
|
||||
type Output = Q::QueryResult;
|
||||
type Output = Q::QueryResponse;
|
||||
|
||||
fn fully_perform(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
|
||||
use std::fmt;
|
||||
use traits::query::Fallible;
|
||||
use ty::fold::TypeFoldable;
|
||||
|
|
@ -32,7 +32,7 @@ impl<'gcx: 'tcx, 'tcx, T> super::QueryTypeOp<'gcx, 'tcx> for Normalize<T>
|
|||
where
|
||||
T: Normalizable<'gcx, 'tcx>,
|
||||
{
|
||||
type QueryResult = T;
|
||||
type QueryResponse = T;
|
||||
|
||||
fn try_fast_path(_tcx: TyCtxt<'_, 'gcx, 'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
|
||||
if !key.value.value.has_projections() {
|
||||
|
|
@ -45,13 +45,13 @@ where
|
|||
fn perform_query(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self::QueryResult>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>> {
|
||||
T::type_op_method(tcx, canonicalized)
|
||||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, T>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, T>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, T>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, T>> {
|
||||
T::shrink_to_tcx_lifetime(v)
|
||||
}
|
||||
}
|
||||
|
|
@ -60,13 +60,13 @@ pub trait Normalizable<'gcx, 'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx>
|
|||
fn type_op_method(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>>;
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>>;
|
||||
|
||||
/// Convert from the `'gcx` (lifted) form of `Self` into the `tcx`
|
||||
/// form of `Self`.
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>>;
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>>;
|
||||
}
|
||||
|
||||
impl Normalizable<'gcx, 'tcx> for Ty<'tcx>
|
||||
|
|
@ -76,13 +76,13 @@ where
|
|||
fn type_op_method(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>> {
|
||||
tcx.type_op_normalize_ty(canonicalized)
|
||||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
@ -94,13 +94,13 @@ where
|
|||
fn type_op_method(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>> {
|
||||
tcx.type_op_normalize_predicate(canonicalized)
|
||||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
@ -112,13 +112,13 @@ where
|
|||
fn type_op_method(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>> {
|
||||
tcx.type_op_normalize_poly_fn_sig(canonicalized)
|
||||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
@ -130,13 +130,13 @@ where
|
|||
fn type_op_method(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>> {
|
||||
tcx.type_op_normalize_fn_sig(canonicalized)
|
||||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, Self>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
|
||||
use traits::query::dropck_outlives::trivial_dropck_outlives;
|
||||
use traits::query::dropck_outlives::DropckOutlivesResult;
|
||||
use traits::query::Fallible;
|
||||
|
|
@ -29,12 +29,12 @@ impl super::QueryTypeOp<'gcx, 'tcx> for DropckOutlives<'tcx>
|
|||
where
|
||||
'gcx: 'tcx,
|
||||
{
|
||||
type QueryResult = DropckOutlivesResult<'tcx>;
|
||||
type QueryResponse = DropckOutlivesResult<'tcx>;
|
||||
|
||||
fn try_fast_path(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
key: &ParamEnvAnd<'tcx, Self>,
|
||||
) -> Option<Self::QueryResult> {
|
||||
) -> Option<Self::QueryResponse> {
|
||||
if trivial_dropck_outlives(tcx, key.value.dropped_ty) {
|
||||
Some(DropckOutlivesResult::default())
|
||||
} else {
|
||||
|
|
@ -45,7 +45,7 @@ where
|
|||
fn perform_query(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, Self::QueryResult>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>> {
|
||||
// Subtle: note that we are not invoking
|
||||
// `infcx.at(...).dropck_outlives(...)` here, but rather the
|
||||
// underlying `dropck_outlives` query. This same underlying
|
||||
|
|
@ -76,8 +76,8 @@ where
|
|||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
lifted_query_result: &'a CanonicalizedQueryResult<'gcx, Self::QueryResult>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, Self::QueryResult>> {
|
||||
lifted_query_result: &'a CanonicalizedQueryResponse<'gcx, Self::QueryResponse>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>> {
|
||||
lifted_query_result
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
|
||||
use traits::query::Fallible;
|
||||
use ty::{ParamEnvAnd, Predicate, TyCtxt};
|
||||
|
||||
|
|
@ -24,12 +24,12 @@ impl<'tcx> ProvePredicate<'tcx> {
|
|||
}
|
||||
|
||||
impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> {
|
||||
type QueryResult = ();
|
||||
type QueryResponse = ();
|
||||
|
||||
fn try_fast_path(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
key: &ParamEnvAnd<'tcx, Self>,
|
||||
) -> Option<Self::QueryResult> {
|
||||
) -> Option<Self::QueryResponse> {
|
||||
// Proving Sized, very often on "obviously sized" types like
|
||||
// `&T`, accounts for about 60% percentage of the predicates
|
||||
// we have to prove. No need to canonicalize and all that for
|
||||
|
|
@ -50,13 +50,13 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> {
|
|||
fn perform_query(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, ()>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
|
||||
tcx.type_op_prove_predicate(canonicalized)
|
||||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, ()>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, ()>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, ()>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
|
||||
use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResponse, QueryResponse};
|
||||
use traits::query::Fallible;
|
||||
use ty::{ParamEnvAnd, Ty, TyCtxt};
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ impl<'tcx> Subtype<'tcx> {
|
|||
}
|
||||
|
||||
impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
|
||||
type QueryResult = ();
|
||||
type QueryResponse = ();
|
||||
|
||||
fn try_fast_path(_tcx: TyCtxt<'_, 'gcx, 'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<()> {
|
||||
if key.value.sub == key.value.sup {
|
||||
|
|
@ -41,13 +41,13 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
|
|||
fn perform_query(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
|
||||
) -> Fallible<CanonicalizedQueryResult<'gcx, ()>> {
|
||||
) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
|
||||
tcx.type_op_subtype(canonicalized)
|
||||
}
|
||||
|
||||
fn shrink_to_tcx_lifetime(
|
||||
v: &'a CanonicalizedQueryResult<'gcx, ()>,
|
||||
) -> &'a Canonical<'tcx, QueryResult<'tcx, ()>> {
|
||||
v: &'a CanonicalizedQueryResponse<'gcx, ()>,
|
||||
) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ use syntax::symbol::{keywords, Symbol, LocalInternedString, InternedString};
|
|||
use syntax_pos::{DUMMY_SP, Span};
|
||||
|
||||
use smallvec;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
|
||||
HashStable};
|
||||
|
||||
|
|
@ -1456,10 +1457,10 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
|
|||
/// "Universes" are used during type- and trait-checking in the
|
||||
/// presence of `for<..>` binders to control what sets of names are
|
||||
/// visible. Universes are arranged into a tree: the root universe
|
||||
/// contains names that are always visible. But when you enter into
|
||||
/// some subuniverse, then it may add names that are only visible
|
||||
/// within that subtree (but it can still name the names of its
|
||||
/// ancestor universes).
|
||||
/// contains names that are always visible. Each child then adds a new
|
||||
/// set of names that are visible, in addition to those of its parent.
|
||||
/// We say that the child universe "extends" the parent universe with
|
||||
/// new names.
|
||||
///
|
||||
/// To make this more concrete, consider this program:
|
||||
///
|
||||
|
|
@ -1471,11 +1472,11 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
|
|||
/// ```
|
||||
///
|
||||
/// The struct name `Foo` is in the root universe U0. But the type
|
||||
/// parameter `T`, introduced on `bar`, is in a subuniverse U1 --
|
||||
/// i.e., within `bar`, we can name both `T` and `Foo`, but outside of
|
||||
/// `bar`, we cannot name `T`. Then, within the type of `y`, the
|
||||
/// region `'a` is in a subuniverse U2 of U1, because we can name it
|
||||
/// inside the fn type but not outside.
|
||||
/// parameter `T`, introduced on `bar`, is in an extended universe U1
|
||||
/// -- i.e., within `bar`, we can name both `T` and `Foo`, but outside
|
||||
/// of `bar`, we cannot name `T`. Then, within the type of `y`, the
|
||||
/// region `'a` is in a universe U2 that extends U1, because we can
|
||||
/// name it inside the fn type but not outside.
|
||||
///
|
||||
/// Universes are used to do type- and trait-checking around these
|
||||
/// "forall" binders (also called **universal quantification**). The
|
||||
|
|
@ -1488,65 +1489,39 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
|
|||
/// declared, but a type name in a non-zero universe is a placeholder
|
||||
/// type -- an idealized representative of "types in general" that we
|
||||
/// use for checking generic functions.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
|
||||
pub struct UniverseIndex(u32);
|
||||
newtype_index! {
|
||||
pub struct UniverseIndex {
|
||||
DEBUG_FORMAT = "U{}",
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct UniverseIndex { private });
|
||||
|
||||
impl UniverseIndex {
|
||||
/// The root universe, where things that the user defined are
|
||||
/// visible.
|
||||
pub const ROOT: Self = UniverseIndex(0);
|
||||
pub const ROOT: UniverseIndex = UniverseIndex::from_u32_const(0);
|
||||
|
||||
/// The "max universe" -- this isn't really a valid universe, but
|
||||
/// it's useful sometimes as a "starting value" when you are
|
||||
/// taking the minimum of a (non-empty!) set of universes.
|
||||
pub const MAX: Self = UniverseIndex(::std::u32::MAX);
|
||||
|
||||
/// Creates a universe index from the given integer. Not to be
|
||||
/// used lightly lest you pick a bad value. But sometimes we
|
||||
/// convert universe indices into integers and back for various
|
||||
/// reasons.
|
||||
pub fn from_u32(index: u32) -> Self {
|
||||
UniverseIndex(index)
|
||||
}
|
||||
|
||||
/// A "subuniverse" corresponds to being inside a `forall` quantifier.
|
||||
/// So, for example, suppose we have this type in universe `U`:
|
||||
/// Returns the "next" universe index in order -- this new index
|
||||
/// is considered to extend all previous universes. This
|
||||
/// corresponds to entering a `forall` quantifier. So, for
|
||||
/// example, suppose we have this type in universe `U`:
|
||||
///
|
||||
/// ```
|
||||
/// for<'a> fn(&'a u32)
|
||||
/// ```
|
||||
///
|
||||
/// Once we "enter" into this `for<'a>` quantifier, we are in a
|
||||
/// subuniverse of `U` -- in this new universe, we can name the
|
||||
/// region `'a`, but that region was not nameable from `U` because
|
||||
/// it was not in scope there.
|
||||
pub fn subuniverse(self) -> UniverseIndex {
|
||||
UniverseIndex(self.0.checked_add(1).unwrap())
|
||||
/// new universe that extends `U` -- in this new universe, we can
|
||||
/// name the region `'a`, but that region was not nameable from
|
||||
/// `U` because it was not in scope there.
|
||||
pub fn next_universe(self) -> UniverseIndex {
|
||||
UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
|
||||
}
|
||||
|
||||
/// True if the names in this universe are a subset of the names in `other`.
|
||||
pub fn is_subset_of(self, other: UniverseIndex) -> bool {
|
||||
self.0 <= other.0
|
||||
}
|
||||
|
||||
pub fn as_u32(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn as_usize(&self) -> usize {
|
||||
self.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for UniverseIndex {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(fmt, "U{}", self.as_u32())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for UniverseIndex {
|
||||
fn from(index: u32) -> Self {
|
||||
UniverseIndex(index)
|
||||
/// True if `self` can name a name from `other` -- in other words,
|
||||
/// if the set of names in `self` is a superset of those in
|
||||
/// `other`.
|
||||
pub fn can_name(self, other: UniverseIndex) -> bool {
|
||||
self.private >= other.private
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -559,7 +559,7 @@ define_queries! { <'tcx>
|
|||
[] fn normalize_projection_ty: NormalizeProjectionTy(
|
||||
CanonicalProjectionGoal<'tcx>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, NormalizationResult<'tcx>>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, NormalizationResult<'tcx>>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -571,7 +571,7 @@ define_queries! { <'tcx>
|
|||
[] fn implied_outlives_bounds: ImpliedOutlivesBounds(
|
||||
CanonicalTyGoal<'tcx>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, Vec<OutlivesBound<'tcx>>>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -579,7 +579,7 @@ define_queries! { <'tcx>
|
|||
[] fn dropck_outlives: DropckOutlives(
|
||||
CanonicalTyGoal<'tcx>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, DropckOutlivesResult<'tcx>>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -593,7 +593,7 @@ define_queries! { <'tcx>
|
|||
[] fn type_op_eq: TypeOpEq(
|
||||
CanonicalTypeOpEqGoal<'tcx>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ()>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -601,7 +601,7 @@ define_queries! { <'tcx>
|
|||
[] fn type_op_subtype: TypeOpSubtype(
|
||||
CanonicalTypeOpSubtypeGoal<'tcx>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ()>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -609,7 +609,7 @@ define_queries! { <'tcx>
|
|||
[] fn type_op_prove_predicate: TypeOpProvePredicate(
|
||||
CanonicalTypeOpProvePredicateGoal<'tcx>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ()>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -617,7 +617,7 @@ define_queries! { <'tcx>
|
|||
[] fn type_op_normalize_ty: TypeOpNormalizeTy(
|
||||
CanonicalTypeOpNormalizeGoal<'tcx, Ty<'tcx>>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, Ty<'tcx>>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, Ty<'tcx>>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -625,7 +625,7 @@ define_queries! { <'tcx>
|
|||
[] fn type_op_normalize_predicate: TypeOpNormalizePredicate(
|
||||
CanonicalTypeOpNormalizeGoal<'tcx, ty::Predicate<'tcx>>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ty::Predicate<'tcx>>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, ty::Predicate<'tcx>>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -633,7 +633,7 @@ define_queries! { <'tcx>
|
|||
[] fn type_op_normalize_poly_fn_sig: TypeOpNormalizePolyFnSig(
|
||||
CanonicalTypeOpNormalizeGoal<'tcx, ty::PolyFnSig<'tcx>>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ty::PolyFnSig<'tcx>>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, ty::PolyFnSig<'tcx>>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
@ -641,7 +641,7 @@ define_queries! { <'tcx>
|
|||
[] fn type_op_normalize_fn_sig: TypeOpNormalizeFnSig(
|
||||
CanonicalTypeOpNormalizeGoal<'tcx, ty::FnSig<'tcx>>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, ty::FnSig<'tcx>>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, ty::FnSig<'tcx>>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ CloneTypeFoldableAndLiftImpls! {
|
|||
::ty::ClosureKind,
|
||||
::ty::IntVarValue,
|
||||
::ty::ParamTy,
|
||||
::ty::UniverseIndex,
|
||||
::ty::Variance,
|
||||
::syntax_pos::Span,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ struct RegionDefinition<'tcx> {
|
|||
/// Which universe is this region variable defined in? This is
|
||||
/// most often `ty::UniverseIndex::ROOT`, but when we encounter
|
||||
/// forall-quantifiers like `for<'a> { 'a = 'b }`, we would create
|
||||
/// the variable for `'a` in a subuniverse.
|
||||
/// the variable for `'a` in a fresh universe that extends ROOT.
|
||||
universe: ty::UniverseIndex,
|
||||
|
||||
/// If this is 'static or an early-bound region, then this is
|
||||
|
|
@ -339,11 +339,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|
||||
NLLRegionVariableOrigin::Placeholder(placeholder) => {
|
||||
// Each placeholder region is only visible from
|
||||
// its universe `ui` and its superuniverses. So we
|
||||
// its universe `ui` and its extensions. So we
|
||||
// can't just add it into `scc` unless the
|
||||
// universe of the scc can name this region.
|
||||
let scc_universe = self.scc_universes[scc];
|
||||
if placeholder.universe.is_subset_of(scc_universe) {
|
||||
if scc_universe.can_name(placeholder.universe) {
|
||||
self.scc_values.add_element(scc, placeholder);
|
||||
} else {
|
||||
self.add_incompatible_universe(scc);
|
||||
|
|
@ -541,7 +541,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// Quick check: if scc_b's declared universe is a subset of
|
||||
// scc_a's declared univese (typically, both are ROOT), then
|
||||
// it cannot contain any problematic universe elements.
|
||||
if self.scc_universes[scc_b].is_subset_of(universe_a) {
|
||||
if universe_a.can_name(self.scc_universes[scc_b]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -550,7 +550,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// from universe_a
|
||||
self.scc_values
|
||||
.placeholders_contained_in(scc_b)
|
||||
.all(|p| p.universe.is_subset_of(universe_a))
|
||||
.all(|p| universe_a.can_name(p.universe))
|
||||
}
|
||||
|
||||
/// Extend `scc` so that it can outlive some placeholder region
|
||||
|
|
|
|||
|
|
@ -148,8 +148,8 @@ crate enum RegionElement {
|
|||
/// a lifetime parameter).
|
||||
RootUniversalRegion(RegionVid),
|
||||
|
||||
/// A subuniverse from a subuniverse (e.g., instantiated from a
|
||||
/// `for<'a> fn(&'a u32)` type).
|
||||
/// A placeholder (e.g., instantiated from a `for<'a> fn(&'a u32)`
|
||||
/// type).
|
||||
PlaceholderRegion(ty::Placeholder),
|
||||
}
|
||||
|
||||
|
|
@ -252,19 +252,6 @@ impl PlaceholderIndices {
|
|||
}
|
||||
}
|
||||
|
||||
impl ::std::iter::FromIterator<ty::Placeholder> for PlaceholderIndices {
|
||||
fn from_iter<I>(iter: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = ty::Placeholder>,
|
||||
{
|
||||
let mut result = Self::default();
|
||||
iter.into_iter().for_each(|p| {
|
||||
result.insert(p);
|
||||
});
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores the full values for a set of regions (in contrast to
|
||||
/// `LivenessValues`, which only stores those points in the where a
|
||||
/// region is live). The full value for a region may contain points in
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ trait TypeRelatingDelegate<'tcx> {
|
|||
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
|
||||
|
||||
/// Creates a new universe index. Used when instantiating placeholders.
|
||||
fn next_subuniverse(&mut self) -> ty::UniverseIndex;
|
||||
fn create_next_universe(&mut self) -> ty::UniverseIndex;
|
||||
|
||||
/// Creates a new region variable representing a higher-ranked
|
||||
/// region that is instantiated existentially. This creates an
|
||||
|
|
@ -218,8 +218,8 @@ impl NllTypeRelatingDelegate<'me, 'bccx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, '_, 'tcx> {
|
||||
fn next_subuniverse(&mut self) -> ty::UniverseIndex {
|
||||
self.infcx.create_subuniverse()
|
||||
fn create_next_universe(&mut self) -> ty::UniverseIndex {
|
||||
self.infcx.create_next_universe()
|
||||
}
|
||||
|
||||
fn next_existential_region_var(&mut self) -> ty::Region<'tcx> {
|
||||
|
|
@ -324,7 +324,7 @@ where
|
|||
// new universe for the placeholders we will make
|
||||
// from here out.
|
||||
let universe = lazy_universe.unwrap_or_else(|| {
|
||||
let universe = delegate.next_subuniverse();
|
||||
let universe = delegate.create_next_universe();
|
||||
lazy_universe = Some(universe);
|
||||
universe
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@
|
|||
|
||||
use chalk_engine::fallible::Fallible as ChalkEngineFallible;
|
||||
use chalk_engine::{context, hh::HhGoal, DelayedLiteral, ExClause};
|
||||
use rustc::infer::canonical::{Canonical, CanonicalVarValues, QueryRegionConstraint, QueryResult};
|
||||
use rustc::infer::canonical::{
|
||||
Canonical, CanonicalVarValues, OriginalQueryValues, QueryRegionConstraint, QueryResponse,
|
||||
};
|
||||
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
|
||||
use rustc::traits::{
|
||||
WellFormed,
|
||||
|
|
@ -26,7 +28,6 @@ use rustc::traits::{
|
|||
use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use rustc::ty::subst::Kind;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use std::fmt::{self, Debug};
|
||||
use std::marker::PhantomData;
|
||||
|
|
@ -77,7 +78,7 @@ impl context::Context for ChalkArenas<'tcx> {
|
|||
// u-canonicalization not yet implemented
|
||||
type UniverseMap = UniverseMap;
|
||||
|
||||
type Solution = Canonical<'tcx, QueryResult<'tcx, ()>>;
|
||||
type Solution = Canonical<'tcx, QueryResponse<'tcx, ()>>;
|
||||
|
||||
type InferenceNormalizedSubst = CanonicalVarValues<'tcx>;
|
||||
|
||||
|
|
@ -116,7 +117,7 @@ impl context::AggregateOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
|
|||
&self,
|
||||
_root_goal: &Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>>,
|
||||
_simplified_answers: impl context::AnswerStream<ChalkArenas<'gcx>>,
|
||||
) -> Option<Canonical<'gcx, QueryResult<'gcx, ()>>> {
|
||||
) -> Option<Canonical<'gcx, QueryResponse<'gcx, ()>>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
@ -390,7 +391,7 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
|
|||
&mut self,
|
||||
value: &ty::ParamEnvAnd<'tcx, Goal<'tcx>>,
|
||||
) -> Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>> {
|
||||
let mut _orig_values = SmallVec::new();
|
||||
let mut _orig_values = OriginalQueryValues::default();
|
||||
self.infcx.canonicalize_query(value, &mut _orig_values)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::canonical::{Canonical, QueryResult};
|
||||
use rustc::infer::canonical::{Canonical, QueryResponse};
|
||||
use rustc::traits::query::dropck_outlives::{DropckOutlivesResult, DtorckConstraint};
|
||||
use rustc::traits::query::{CanonicalTyGoal, NoSolution};
|
||||
use rustc::traits::{FulfillmentContext, Normalized, ObligationCause, TraitEngineExt};
|
||||
|
|
@ -30,124 +30,125 @@ crate fn provide(p: &mut Providers) {
|
|||
|
||||
fn dropck_outlives<'tcx>(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
goal: CanonicalTyGoal<'tcx>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, DropckOutlivesResult<'tcx>>>>, NoSolution> {
|
||||
debug!("dropck_outlives(goal={:#?})", goal);
|
||||
canonical_goal: CanonicalTyGoal<'tcx>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, DropckOutlivesResult<'tcx>>>>, NoSolution> {
|
||||
debug!("dropck_outlives(goal={:#?})", canonical_goal);
|
||||
|
||||
tcx.infer_ctxt().enter(|ref infcx| {
|
||||
let tcx = infcx.tcx;
|
||||
let (
|
||||
ParamEnvAnd {
|
||||
tcx.infer_ctxt().enter_with_canonical(
|
||||
DUMMY_SP,
|
||||
&canonical_goal,
|
||||
|ref infcx, goal, canonical_inference_vars| {
|
||||
let tcx = infcx.tcx;
|
||||
let ParamEnvAnd {
|
||||
param_env,
|
||||
value: for_ty,
|
||||
},
|
||||
canonical_inference_vars,
|
||||
) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal);
|
||||
} = goal;
|
||||
|
||||
let mut result = DropckOutlivesResult {
|
||||
kinds: vec![],
|
||||
overflows: vec![],
|
||||
};
|
||||
let mut result = DropckOutlivesResult {
|
||||
kinds: vec![],
|
||||
overflows: vec![],
|
||||
};
|
||||
|
||||
// A stack of types left to process. Each round, we pop
|
||||
// something from the stack and invoke
|
||||
// `dtorck_constraint_for_ty`. This may produce new types that
|
||||
// have to be pushed on the stack. This continues until we have explored
|
||||
// all the reachable types from the type `for_ty`.
|
||||
//
|
||||
// Example: Imagine that we have the following code:
|
||||
//
|
||||
// ```rust
|
||||
// struct A {
|
||||
// value: B,
|
||||
// children: Vec<A>,
|
||||
// }
|
||||
//
|
||||
// struct B {
|
||||
// value: u32
|
||||
// }
|
||||
//
|
||||
// fn f() {
|
||||
// let a: A = ...;
|
||||
// ..
|
||||
// } // here, `a` is dropped
|
||||
// ```
|
||||
//
|
||||
// at the point where `a` is dropped, we need to figure out
|
||||
// which types inside of `a` contain region data that may be
|
||||
// accessed by any destructors in `a`. We begin by pushing `A`
|
||||
// onto the stack, as that is the type of `a`. We will then
|
||||
// invoke `dtorck_constraint_for_ty` which will expand `A`
|
||||
// into the types of its fields `(B, Vec<A>)`. These will get
|
||||
// pushed onto the stack. Eventually, expanding `Vec<A>` will
|
||||
// lead to us trying to push `A` a second time -- to prevent
|
||||
// infinite recursion, we notice that `A` was already pushed
|
||||
// once and stop.
|
||||
let mut ty_stack = vec![(for_ty, 0)];
|
||||
// A stack of types left to process. Each round, we pop
|
||||
// something from the stack and invoke
|
||||
// `dtorck_constraint_for_ty`. This may produce new types that
|
||||
// have to be pushed on the stack. This continues until we have explored
|
||||
// all the reachable types from the type `for_ty`.
|
||||
//
|
||||
// Example: Imagine that we have the following code:
|
||||
//
|
||||
// ```rust
|
||||
// struct A {
|
||||
// value: B,
|
||||
// children: Vec<A>,
|
||||
// }
|
||||
//
|
||||
// struct B {
|
||||
// value: u32
|
||||
// }
|
||||
//
|
||||
// fn f() {
|
||||
// let a: A = ...;
|
||||
// ..
|
||||
// } // here, `a` is dropped
|
||||
// ```
|
||||
//
|
||||
// at the point where `a` is dropped, we need to figure out
|
||||
// which types inside of `a` contain region data that may be
|
||||
// accessed by any destructors in `a`. We begin by pushing `A`
|
||||
// onto the stack, as that is the type of `a`. We will then
|
||||
// invoke `dtorck_constraint_for_ty` which will expand `A`
|
||||
// into the types of its fields `(B, Vec<A>)`. These will get
|
||||
// pushed onto the stack. Eventually, expanding `Vec<A>` will
|
||||
// lead to us trying to push `A` a second time -- to prevent
|
||||
// infinite recursion, we notice that `A` was already pushed
|
||||
// once and stop.
|
||||
let mut ty_stack = vec![(for_ty, 0)];
|
||||
|
||||
// Set used to detect infinite recursion.
|
||||
let mut ty_set = FxHashSet();
|
||||
// Set used to detect infinite recursion.
|
||||
let mut ty_set = FxHashSet();
|
||||
|
||||
let fulfill_cx = &mut FulfillmentContext::new();
|
||||
let fulfill_cx = &mut FulfillmentContext::new();
|
||||
|
||||
let cause = ObligationCause::dummy();
|
||||
while let Some((ty, depth)) = ty_stack.pop() {
|
||||
let DtorckConstraint {
|
||||
dtorck_types,
|
||||
outlives,
|
||||
overflows,
|
||||
} = dtorck_constraint_for_ty(tcx, DUMMY_SP, for_ty, depth, ty)?;
|
||||
let cause = ObligationCause::dummy();
|
||||
while let Some((ty, depth)) = ty_stack.pop() {
|
||||
let DtorckConstraint {
|
||||
dtorck_types,
|
||||
outlives,
|
||||
overflows,
|
||||
} = dtorck_constraint_for_ty(tcx, DUMMY_SP, for_ty, depth, ty)?;
|
||||
|
||||
// "outlives" represent types/regions that may be touched
|
||||
// by a destructor.
|
||||
result.kinds.extend(outlives);
|
||||
result.overflows.extend(overflows);
|
||||
// "outlives" represent types/regions that may be touched
|
||||
// by a destructor.
|
||||
result.kinds.extend(outlives);
|
||||
result.overflows.extend(overflows);
|
||||
|
||||
// dtorck types are "types that will get dropped but which
|
||||
// do not themselves define a destructor", more or less. We have
|
||||
// to push them onto the stack to be expanded.
|
||||
for ty in dtorck_types {
|
||||
match infcx.at(&cause, param_env).normalize(&ty) {
|
||||
Ok(Normalized {
|
||||
value: ty,
|
||||
obligations,
|
||||
}) => {
|
||||
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
||||
// dtorck types are "types that will get dropped but which
|
||||
// do not themselves define a destructor", more or less. We have
|
||||
// to push them onto the stack to be expanded.
|
||||
for ty in dtorck_types {
|
||||
match infcx.at(&cause, param_env).normalize(&ty) {
|
||||
Ok(Normalized {
|
||||
value: ty,
|
||||
obligations,
|
||||
}) => {
|
||||
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
||||
|
||||
debug!("dropck_outlives: ty from dtorck_types = {:?}", ty);
|
||||
debug!("dropck_outlives: ty from dtorck_types = {:?}", ty);
|
||||
|
||||
match ty.sty {
|
||||
// All parameters live for the duration of the
|
||||
// function.
|
||||
ty::Param(..) => {}
|
||||
match ty.sty {
|
||||
// All parameters live for the duration of the
|
||||
// function.
|
||||
ty::Param(..) => {}
|
||||
|
||||
// A projection that we couldn't resolve - it
|
||||
// might have a destructor.
|
||||
ty::Projection(..) | ty::Opaque(..) => {
|
||||
result.kinds.push(ty.into());
|
||||
}
|
||||
// A projection that we couldn't resolve - it
|
||||
// might have a destructor.
|
||||
ty::Projection(..) | ty::Opaque(..) => {
|
||||
result.kinds.push(ty.into());
|
||||
}
|
||||
|
||||
_ => {
|
||||
if ty_set.insert(ty) {
|
||||
ty_stack.push((ty, depth + 1));
|
||||
_ => {
|
||||
if ty_set.insert(ty) {
|
||||
ty_stack.push((ty, depth + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We don't actually expect to fail to normalize.
|
||||
// That implies a WF error somewhere else.
|
||||
Err(NoSolution) => {
|
||||
return Err(NoSolution);
|
||||
// We don't actually expect to fail to normalize.
|
||||
// That implies a WF error somewhere else.
|
||||
Err(NoSolution) => {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!("dropck_outlives: result = {:#?}", result);
|
||||
debug!("dropck_outlives: result = {:#?}", result);
|
||||
|
||||
infcx.make_canonicalized_query_result(canonical_inference_vars, result, fulfill_cx)
|
||||
})
|
||||
infcx.make_canonicalized_query_response(canonical_inference_vars, result, fulfill_cx)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Return a set of constraints that needs to be satisfied in
|
||||
|
|
@ -195,8 +196,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>(
|
|||
dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ety)
|
||||
}
|
||||
|
||||
ty::Tuple(tys) => tys
|
||||
.iter()
|
||||
ty::Tuple(tys) => tys.iter()
|
||||
.map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty))
|
||||
.collect(),
|
||||
|
||||
|
|
@ -308,8 +308,7 @@ crate fn adt_dtorck_constraint<'a, 'tcx>(
|
|||
return Ok(result);
|
||||
}
|
||||
|
||||
let mut result = def
|
||||
.all_fields()
|
||||
let mut result = def.all_fields()
|
||||
.map(|field| tcx.type_of(field.did))
|
||||
.map(|fty| dtorck_constraint_for_ty(tcx, span, fty, 0, fty))
|
||||
.collect::<Result<DtorckConstraint, NoSolution>>()?;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::traits::{EvaluationResult, Obligation, ObligationCause,
|
||||
OverflowError, SelectionContext, TraitQueryMode};
|
||||
use rustc::traits::query::CanonicalPredicateGoal;
|
||||
use rustc::traits::{
|
||||
EvaluationResult, Obligation, ObligationCause, OverflowError, SelectionContext, TraitQueryMode,
|
||||
};
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::{ParamEnvAnd, TyCtxt};
|
||||
use syntax::source_map::DUMMY_SP;
|
||||
|
|
@ -24,20 +25,21 @@ crate fn provide(p: &mut Providers) {
|
|||
|
||||
fn evaluate_obligation<'tcx>(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
goal: CanonicalPredicateGoal<'tcx>,
|
||||
canonical_goal: CanonicalPredicateGoal<'tcx>,
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
tcx.infer_ctxt().enter(|ref infcx| {
|
||||
let (
|
||||
ParamEnvAnd {
|
||||
tcx.infer_ctxt().enter_with_canonical(
|
||||
DUMMY_SP,
|
||||
&canonical_goal,
|
||||
|ref infcx, goal, _canonical_inference_vars| {
|
||||
let ParamEnvAnd {
|
||||
param_env,
|
||||
value: predicate,
|
||||
},
|
||||
_canonical_inference_vars,
|
||||
) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal);
|
||||
} = goal;
|
||||
|
||||
let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
|
||||
let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
|
||||
|
||||
selcx.evaluate_obligation_recursively(&obligation)
|
||||
})
|
||||
selcx.evaluate_obligation_recursively(&obligation)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ fn implied_outlives_bounds<'tcx>(
|
|||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
goal: CanonicalTyGoal<'tcx>,
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, canonical::QueryResult<'tcx, Vec<OutlivesBound<'tcx>>>>>,
|
||||
Lrc<Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>>,
|
||||
NoSolution,
|
||||
> {
|
||||
tcx.infer_ctxt()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::infer::canonical::{Canonical, QueryResult};
|
||||
use rustc::infer::canonical::{Canonical, QueryResponse};
|
||||
use rustc::traits::query::{normalize::NormalizationResult, CanonicalProjectionGoal, NoSolution};
|
||||
use rustc::traits::{self, ObligationCause, SelectionContext, TraitEngineExt};
|
||||
use rustc::ty::query::Providers;
|
||||
|
|
@ -28,7 +28,7 @@ crate fn provide(p: &mut Providers) {
|
|||
fn normalize_projection_ty<'tcx>(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
goal: CanonicalProjectionGoal<'tcx>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, NormalizationResult<'tcx>>>>, NoSolution> {
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, NormalizationResult<'tcx>>>>, NoSolution> {
|
||||
debug!("normalize_provider(goal={:#?})", goal);
|
||||
|
||||
tcx.sess
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::infer::canonical::{Canonical, QueryResult};
|
||||
use rustc::infer::canonical::{Canonical, QueryResponse};
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::traits::query::type_op::eq::Eq;
|
||||
use rustc::traits::query::type_op::normalize::Normalize;
|
||||
|
|
@ -38,7 +38,7 @@ crate fn provide(p: &mut Providers) {
|
|||
fn type_op_eq<'tcx>(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, ()>>>, NoSolution> {
|
||||
tcx.infer_ctxt()
|
||||
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
|
||||
let (param_env, Eq { a, b }) = key.into_parts();
|
||||
|
|
@ -68,7 +68,7 @@ where
|
|||
fn type_op_normalize_ty(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Ty<'tcx>>>>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, Ty<'tcx>>>>, NoSolution> {
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>>, NoSolution> {
|
||||
tcx.infer_ctxt()
|
||||
.enter_canonical_trait_query(&canonicalized, type_op_normalize)
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ fn type_op_normalize_ty(
|
|||
fn type_op_normalize_predicate(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Predicate<'tcx>>>>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, Predicate<'tcx>>>>, NoSolution> {
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, Predicate<'tcx>>>>, NoSolution> {
|
||||
tcx.infer_ctxt()
|
||||
.enter_canonical_trait_query(&canonicalized, type_op_normalize)
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ fn type_op_normalize_predicate(
|
|||
fn type_op_normalize_fn_sig(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<FnSig<'tcx>>>>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, FnSig<'tcx>>>>, NoSolution> {
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, FnSig<'tcx>>>>, NoSolution> {
|
||||
tcx.infer_ctxt()
|
||||
.enter_canonical_trait_query(&canonicalized, type_op_normalize)
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ fn type_op_normalize_fn_sig(
|
|||
fn type_op_normalize_poly_fn_sig(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<PolyFnSig<'tcx>>>>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, PolyFnSig<'tcx>>>>, NoSolution> {
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, PolyFnSig<'tcx>>>>, NoSolution> {
|
||||
tcx.infer_ctxt()
|
||||
.enter_canonical_trait_query(&canonicalized, type_op_normalize)
|
||||
}
|
||||
|
|
@ -100,7 +100,7 @@ fn type_op_normalize_poly_fn_sig(
|
|||
fn type_op_subtype<'tcx>(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, ()>>>, NoSolution> {
|
||||
tcx.infer_ctxt()
|
||||
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
|
||||
let (param_env, Subtype { sub, sup }) = key.into_parts();
|
||||
|
|
@ -114,7 +114,7 @@ fn type_op_subtype<'tcx>(
|
|||
fn type_op_prove_predicate<'tcx>(
|
||||
tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, ProvePredicate<'tcx>>>,
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResult<'tcx, ()>>>, NoSolution> {
|
||||
) -> Result<Lrc<Canonical<'tcx, QueryResponse<'tcx, ()>>>, NoSolution> {
|
||||
tcx.infer_ctxt()
|
||||
.enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
|
||||
let (param_env, ProvePredicate { predicate }) = key.into_parts();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue