Auto merge of #55921 - scalexm:placeholders, r=nikomatsakis
Add placeholder types Fixes #48696 (handle universes in canonicalization of type inference vars), and fixes #55098.
This commit is contained in:
commit
abe19a7305
52 changed files with 412 additions and 210 deletions
|
|
@ -684,9 +684,13 @@ for ty::TyKind<'gcx>
|
|||
Param(param_ty) => {
|
||||
param_ty.hash_stable(hcx, hasher);
|
||||
}
|
||||
Bound(bound_ty) => {
|
||||
Bound(debruijn, bound_ty) => {
|
||||
debruijn.hash_stable(hcx, hasher);
|
||||
bound_ty.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::Placeholder(placeholder_ty) => {
|
||||
placeholder_ty.hash_stable(hcx, hasher);
|
||||
}
|
||||
Foreign(def_id) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
}
|
||||
|
|
@ -1096,12 +1100,13 @@ impl_stable_hash_for!(struct infer::canonical::CanonicalVarInfo {
|
|||
|
||||
impl_stable_hash_for!(enum infer::canonical::CanonicalVarKind {
|
||||
Ty(k),
|
||||
PlaceholderTy(placeholder),
|
||||
Region(ui),
|
||||
PlaceholderRegion(placeholder),
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind {
|
||||
General,
|
||||
General(ui),
|
||||
Int,
|
||||
Float
|
||||
});
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use infer::InferCtxt;
|
|||
use std::sync::atomic::Ordering;
|
||||
use ty::fold::{TypeFoldable, TypeFolder};
|
||||
use ty::subst::Kind;
|
||||
use ty::{self, BoundTy, BoundVar, Lift, List, Ty, TyCtxt, TypeFlags};
|
||||
use ty::{self, BoundVar, Lift, List, Ty, TyCtxt, TypeFlags};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
|
@ -339,11 +339,35 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
|
|||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match t.sty {
|
||||
ty::Infer(ty::TyVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::General, t),
|
||||
ty::Infer(ty::TyVar(vid)) => {
|
||||
match self.infcx.unwrap().probe_ty_var(vid) {
|
||||
// `t` could be a float / int variable: canonicalize that instead
|
||||
Ok(t) => self.fold_ty(t),
|
||||
|
||||
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Int, t),
|
||||
// `TyVar(vid)` is unresolved, track its universe index in the canonicalized
|
||||
// result
|
||||
Err(ui) => self.canonicalize_ty_var(
|
||||
CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
|
||||
},
|
||||
t
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Float, t),
|
||||
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
|
||||
CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int)
|
||||
},
|
||||
t
|
||||
),
|
||||
|
||||
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
|
||||
CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float)
|
||||
},
|
||||
t
|
||||
),
|
||||
|
||||
ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
|
|
@ -351,8 +375,15 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
|
|||
bug!("encountered a fresh type during canonicalization")
|
||||
}
|
||||
|
||||
ty::Bound(bound_ty) => {
|
||||
if bound_ty.index >= self.binder_index {
|
||||
ty::Placeholder(placeholder) => self.canonicalize_ty_var(
|
||||
CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::PlaceholderTy(placeholder)
|
||||
},
|
||||
t
|
||||
),
|
||||
|
||||
ty::Bound(debruijn, _) => {
|
||||
if debruijn >= self.binder_index {
|
||||
bug!("escaping bound type during canonicalization")
|
||||
} else {
|
||||
t
|
||||
|
|
@ -408,9 +439,13 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
V: TypeFoldable<'tcx> + Lift<'gcx>,
|
||||
{
|
||||
let needs_canonical_flags = if canonicalize_region_mode.any() {
|
||||
TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX
|
||||
TypeFlags::KEEP_IN_LOCAL_TCX |
|
||||
TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS`
|
||||
TypeFlags::HAS_TY_PLACEHOLDER
|
||||
} else {
|
||||
TypeFlags::KEEP_IN_LOCAL_TCX
|
||||
TypeFlags::KEEP_IN_LOCAL_TCX |
|
||||
TypeFlags::HAS_RE_PLACEHOLDER |
|
||||
TypeFlags::HAS_TY_PLACEHOLDER
|
||||
};
|
||||
|
||||
let gcx = tcx.global_tcx();
|
||||
|
|
@ -574,17 +609,14 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
|||
/// if `ty_var` is bound to anything; if so, canonicalize
|
||||
/// *that*. Otherwise, create a new canonical variable for
|
||||
/// `ty_var`.
|
||||
fn canonicalize_ty_var(&mut self, ty_kind: CanonicalTyVarKind, ty_var: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo, ty_var: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let infcx = self.infcx.expect("encountered ty-var without infcx");
|
||||
let bound_to = infcx.shallow_resolve(ty_var);
|
||||
if bound_to != ty_var {
|
||||
self.fold_ty(bound_to)
|
||||
} else {
|
||||
let info = CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Ty(ty_kind),
|
||||
};
|
||||
let var = self.canonical_var(info, ty_var.into());
|
||||
self.tcx().mk_ty(ty::Bound(BoundTy::new(self.binder_index, var)))
|
||||
self.tcx().mk_ty(ty::Bound(self.binder_index, var.into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ impl CanonicalVarInfo {
|
|||
pub fn is_existential(&self) -> bool {
|
||||
match self.kind {
|
||||
CanonicalVarKind::Ty(_) => true,
|
||||
CanonicalVarKind::PlaceholderTy(_) => false,
|
||||
CanonicalVarKind::Region(_) => true,
|
||||
CanonicalVarKind::PlaceholderRegion(..) => false,
|
||||
}
|
||||
|
|
@ -136,24 +137,27 @@ pub enum CanonicalVarKind {
|
|||
/// Some kind of type inference variable.
|
||||
Ty(CanonicalTyVarKind),
|
||||
|
||||
/// A "placeholder" that represents "any type".
|
||||
PlaceholderTy(ty::PlaceholderType),
|
||||
|
||||
/// Region variable `'?R`.
|
||||
Region(ty::UniverseIndex),
|
||||
|
||||
/// A "placeholder" that represents "any region". Created when you
|
||||
/// are solving a goal like `for<'a> T: Foo<'a>` to represent the
|
||||
/// bound region `'a`.
|
||||
PlaceholderRegion(ty::Placeholder),
|
||||
PlaceholderRegion(ty::PlaceholderRegion),
|
||||
}
|
||||
|
||||
impl CanonicalVarKind {
|
||||
pub fn universe(self) -> ty::UniverseIndex {
|
||||
match self {
|
||||
// At present, we don't support higher-ranked
|
||||
// quantification over types, so all type variables are in
|
||||
// the root universe.
|
||||
CanonicalVarKind::Ty(_) => ty::UniverseIndex::ROOT,
|
||||
CanonicalVarKind::Ty(kind) => match kind {
|
||||
CanonicalTyVarKind::General(ui) => ui,
|
||||
CanonicalTyVarKind::Float | CanonicalTyVarKind::Int => ty::UniverseIndex::ROOT,
|
||||
}
|
||||
|
||||
// Region variables can be created in sub-universes.
|
||||
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe,
|
||||
CanonicalVarKind::Region(ui) => ui,
|
||||
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe,
|
||||
}
|
||||
|
|
@ -168,7 +172,7 @@ impl CanonicalVarKind {
|
|||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
|
||||
pub enum CanonicalTyVarKind {
|
||||
/// General type variable `?T` that can be unified with arbitrary types.
|
||||
General,
|
||||
General(ty::UniverseIndex),
|
||||
|
||||
/// Integral type variable `?I` (that can only be unified with integral types).
|
||||
Int,
|
||||
|
|
@ -358,8 +362,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
match cv_info.kind {
|
||||
CanonicalVarKind::Ty(ty_kind) => {
|
||||
let ty = match ty_kind {
|
||||
CanonicalTyVarKind::General => {
|
||||
self.next_ty_var(TypeVariableOrigin::MiscVariable(span))
|
||||
CanonicalTyVarKind::General(ui) => {
|
||||
self.next_ty_var_in_universe(
|
||||
TypeVariableOrigin::MiscVariable(span),
|
||||
universe_map(ui)
|
||||
)
|
||||
}
|
||||
|
||||
CanonicalTyVarKind::Int => self.tcx.mk_int_var(self.next_int_var_id()),
|
||||
|
|
@ -369,20 +376,27 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
ty.into()
|
||||
}
|
||||
|
||||
CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, name }) => {
|
||||
let universe_mapped = universe_map(universe);
|
||||
let placeholder_mapped = ty::PlaceholderType {
|
||||
universe: universe_mapped,
|
||||
name,
|
||||
};
|
||||
self.tcx.mk_ty(ty::Placeholder(placeholder_mapped)).into()
|
||||
}
|
||||
|
||||
CanonicalVarKind::Region(ui) => self.next_region_var_in_universe(
|
||||
RegionVariableOrigin::MiscVariable(span),
|
||||
universe_map(ui),
|
||||
).into(),
|
||||
|
||||
CanonicalVarKind::PlaceholderRegion(ty::Placeholder { universe, name }) => {
|
||||
CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, name }) => {
|
||||
let universe_mapped = universe_map(universe);
|
||||
let placeholder_mapped = ty::Placeholder {
|
||||
let placeholder_mapped = ty::PlaceholderRegion {
|
||||
universe: universe_mapped,
|
||||
name,
|
||||
};
|
||||
self.tcx
|
||||
.mk_region(ty::RePlaceholder(placeholder_mapped))
|
||||
.into()
|
||||
self.tcx.mk_region(ty::RePlaceholder(placeholder_mapped)).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,21 +435,21 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
match result_value.unpack() {
|
||||
UnpackedKind::Type(result_value) => {
|
||||
// e.g., here `result_value` might be `?0` in the example above...
|
||||
if let ty::Bound(b) = result_value.sty {
|
||||
if let ty::Bound(debruijn, b) = result_value.sty {
|
||||
// ...in which case we would set `canonical_vars[0]` to `Some(?U)`.
|
||||
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
assert_eq!(b.index, ty::INNERMOST);
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
opt_values[b.var] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
UnpackedKind::Lifetime(result_value) => {
|
||||
// e.g., here `result_value` might be `'?1` in the example above...
|
||||
if let &ty::RegionKind::ReLateBound(index, br) = result_value {
|
||||
if let &ty::RegionKind::ReLateBound(debruijn, br) = result_value {
|
||||
// ... in which case we would set `canonical_vars[0]` to `Some('static)`.
|
||||
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
assert_eq!(index, ty::INNERMOST);
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
opt_values[br.assert_bound_var()] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,9 +170,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
|
|||
t
|
||||
}
|
||||
|
||||
ty::Bound(..) =>
|
||||
bug!("encountered bound ty during freshening"),
|
||||
|
||||
ty::Generator(..) |
|
||||
ty::Bool |
|
||||
ty::Char |
|
||||
|
|
@ -200,6 +197,9 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
|
|||
ty::Opaque(..) => {
|
||||
t.super_fold_with(self)
|
||||
}
|
||||
|
||||
ty::Placeholder(..) |
|
||||
ty::Bound(..) => bug!("unexpected type {:?}", t),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
// First, we instantiate each bound region in the supertype with a
|
||||
// fresh placeholder region.
|
||||
let (b_prime, placeholder_map) =
|
||||
self.infcx.replace_late_bound_regions_with_placeholders(b);
|
||||
self.infcx.replace_bound_vars_with_placeholders(b);
|
||||
|
||||
// Next, we instantiate each bound region in the subtype
|
||||
// with a fresh region variable. These region variables --
|
||||
|
|
@ -115,7 +115,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
|
|||
// First, we instantiate each bound region in the matcher
|
||||
// with a placeholder region.
|
||||
let ((a_match, a_value), placeholder_map) =
|
||||
self.infcx.replace_late_bound_regions_with_placeholders(a_pair);
|
||||
self.infcx.replace_bound_vars_with_placeholders(a_pair);
|
||||
|
||||
debug!("higher_ranked_match: a_match={:?}", a_match);
|
||||
debug!("higher_ranked_match: placeholder_map={:?}", placeholder_map);
|
||||
|
|
@ -314,10 +314,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
region_vars
|
||||
}
|
||||
|
||||
/// Replace all regions bound by `binder` with placeholder regions and
|
||||
/// return a map indicating which bound-region was replaced with what
|
||||
/// placeholder region. This is the first step of checking subtyping
|
||||
/// when higher-ranked things are involved.
|
||||
/// Replace all regions (resp. types) bound by `binder` with placeholder
|
||||
/// regions (resp. types) and return a map indicating which bound-region
|
||||
/// was replaced with what placeholder region. This is the first step of
|
||||
/// checking subtyping when higher-ranked things are involved.
|
||||
///
|
||||
/// **Important:** you must call this function from within a snapshot.
|
||||
/// Moreover, before committing the snapshot, you must eventually call
|
||||
|
|
@ -330,26 +330,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
/// the [rustc guide].
|
||||
///
|
||||
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
|
||||
pub fn replace_late_bound_regions_with_placeholders<T>(
|
||||
pub fn replace_bound_vars_with_placeholders<T>(
|
||||
&self,
|
||||
binder: &ty::Binder<T>,
|
||||
binder: &ty::Binder<T>
|
||||
) -> (T, PlaceholderMap<'tcx>)
|
||||
where
|
||||
T : TypeFoldable<'tcx>,
|
||||
T: TypeFoldable<'tcx>
|
||||
{
|
||||
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 {
|
||||
let fld_r = |br| {
|
||||
self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion {
|
||||
universe: next_universe,
|
||||
name: br,
|
||||
}))
|
||||
});
|
||||
};
|
||||
|
||||
debug!("replace_late_bound_regions_with_placeholders(binder={:?}, result={:?}, map={:?})",
|
||||
binder,
|
||||
result,
|
||||
map);
|
||||
let fld_t = |bound_ty: ty::BoundTy| {
|
||||
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||
universe: next_universe,
|
||||
name: bound_ty.var,
|
||||
}))
|
||||
};
|
||||
|
||||
let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t);
|
||||
|
||||
debug!(
|
||||
"replace_bound_vars_with_placeholders(binder={:?}, result={:?}, map={:?})",
|
||||
binder,
|
||||
result,
|
||||
map
|
||||
);
|
||||
|
||||
(result, map)
|
||||
}
|
||||
|
|
@ -530,7 +541,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
/// Pops the placeholder regions found in `placeholder_map` from the region
|
||||
/// inference context. Whenever you create placeholder regions via
|
||||
/// `replace_late_bound_regions_with_placeholders`, they must be popped before you
|
||||
/// `replace_bound_vars_with_placeholders`, they must be popped before you
|
||||
/// commit the enclosing snapshot (if you do not commit, e.g. within a
|
||||
/// probe or as a result of an error, then this is not necessary, as
|
||||
/// popping happens as part of the rollback).
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
|
|||
universe: Cell<ty::UniverseIndex>,
|
||||
}
|
||||
|
||||
/// A map returned by `replace_late_bound_regions_with_placeholders()`
|
||||
/// A map returned by `replace_bound_vars_with_placeholders()`
|
||||
/// indicating the placeholder region that each late-bound region was
|
||||
/// replaced with.
|
||||
pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
|
||||
|
|
@ -411,7 +411,7 @@ pub enum NLLRegionVariableOrigin {
|
|||
|
||||
/// "Universal" instantiation of a higher-ranked region (e.g.,
|
||||
/// from a `for<'a> T` binder). Meant to represent "any region".
|
||||
Placeholder(ty::Placeholder),
|
||||
Placeholder(ty::PlaceholderRegion),
|
||||
|
||||
Existential,
|
||||
}
|
||||
|
|
@ -935,7 +935,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
b,
|
||||
},
|
||||
placeholder_map,
|
||||
) = self.replace_late_bound_regions_with_placeholders(predicate);
|
||||
) = self.replace_bound_vars_with_placeholders(predicate);
|
||||
|
||||
let cause_span = cause.span;
|
||||
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
|
||||
|
|
@ -952,7 +952,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
) -> UnitResult<'tcx> {
|
||||
self.commit_if_ok(|snapshot| {
|
||||
let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) =
|
||||
self.replace_late_bound_regions_with_placeholders(predicate);
|
||||
self.replace_bound_vars_with_placeholders(predicate);
|
||||
let origin = SubregionOrigin::from_obligation_cause(cause, || {
|
||||
RelateRegionParamBound(cause.span)
|
||||
});
|
||||
|
|
@ -972,6 +972,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
self.tcx.mk_var(self.next_ty_var_id(false, origin))
|
||||
}
|
||||
|
||||
pub fn next_ty_var_in_universe(
|
||||
&self,
|
||||
origin: TypeVariableOrigin,
|
||||
universe: ty::UniverseIndex
|
||||
) -> Ty<'tcx> {
|
||||
let vid = self.type_variables
|
||||
.borrow_mut()
|
||||
.new_var(universe, false, origin);
|
||||
self.tcx.mk_var(vid)
|
||||
}
|
||||
|
||||
pub fn next_diverging_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> {
|
||||
self.tcx.mk_var(self.next_ty_var_id(true, origin))
|
||||
}
|
||||
|
|
@ -1227,6 +1238,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// If `TyVar(vid)` resolves to a type, return that type. Else, return the
|
||||
/// universe index of `TyVar(vid)`.
|
||||
pub fn probe_ty_var(&self, vid: TyVid) -> Result<Ty<'tcx>, ty::UniverseIndex> {
|
||||
use self::type_variable::TypeVariableValue;
|
||||
|
||||
match self.type_variables.borrow_mut().probe(vid) {
|
||||
TypeVariableValue::Known { value } => Ok(value),
|
||||
TypeVariableValue::Unknown { universe } => Err(universe),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.inlined_shallow_resolve(typ)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ pub trait TypeRelatingDelegate<'tcx> {
|
|||
/// So e.g. if you have `for<'a> fn(..) <: for<'b> fn(..)`, then
|
||||
/// we will invoke this method to instantiate `'b` with a
|
||||
/// placeholder region.
|
||||
fn next_placeholder_region(&mut self, placeholder: ty::Placeholder) -> ty::Region<'tcx>;
|
||||
fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx>;
|
||||
|
||||
/// Creates a new existential region in the given universe. This
|
||||
/// is used when handling subtyping and type variables -- if we
|
||||
|
|
@ -176,7 +176,7 @@ where
|
|||
universe
|
||||
});
|
||||
|
||||
let placeholder = ty::Placeholder { universe, name: br };
|
||||
let placeholder = ty::PlaceholderRegion { universe, name: br };
|
||||
delegate.next_placeholder_region(placeholder)
|
||||
} else {
|
||||
delegate.next_existential_region_var()
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ pub type TypeVariableMap = FxHashMap<ty::TyVid, TypeVariableOrigin>;
|
|||
|
||||
struct TypeVariableData {
|
||||
origin: TypeVariableOrigin,
|
||||
diverging: bool
|
||||
diverging: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
|
|
|||
|
|
@ -455,7 +455,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
ty::Bound(..) | ty::Infer(..) => match in_crate {
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match in_crate {
|
||||
InCrate::Local => false,
|
||||
// The inference variable might be unified with a local
|
||||
// type in that remote crate.
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
ty::Generator(..) => Some(18),
|
||||
ty::Foreign(..) => Some(19),
|
||||
ty::GeneratorWitness(..) => Some(20),
|
||||
ty::Bound(..) | ty::Infer(..) | ty::Error => None,
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None,
|
||||
ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>(
|
|||
let infcx = selcx.infcx();
|
||||
infcx.commit_if_ok(|snapshot| {
|
||||
let (placeholder_predicate, placeholder_map) =
|
||||
infcx.replace_late_bound_regions_with_placeholders(&obligation.predicate);
|
||||
infcx.replace_bound_vars_with_placeholders(&obligation.predicate);
|
||||
|
||||
let skol_obligation = obligation.with(placeholder_predicate);
|
||||
let r = match project_and_unify_type(selcx, &skol_obligation) {
|
||||
|
|
@ -424,7 +424,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
|
|||
if let ConstValue::Unevaluated(def_id, substs) = constant.val {
|
||||
let tcx = self.selcx.tcx().global_tcx();
|
||||
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
|
||||
if substs.needs_infer() || substs.has_skol() {
|
||||
if substs.needs_infer() || substs.has_placeholders() {
|
||||
let identity_substs = Substs::identity_for_item(tcx, def_id);
|
||||
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
|
||||
if let Some(instance) = instance {
|
||||
|
|
@ -1656,7 +1656,7 @@ impl<'tcx> ProjectionCache<'tcx> {
|
|||
}
|
||||
|
||||
pub fn rollback_placeholder(&mut self, snapshot: &ProjectionCacheSnapshot) {
|
||||
self.map.partial_rollback(&snapshot.snapshot, &|k| k.ty.has_re_skol());
|
||||
self.map.partial_rollback(&snapshot.snapshot, &|k| k.ty.has_re_placeholders());
|
||||
}
|
||||
|
||||
pub fn commit(&mut self, snapshot: &ProjectionCacheSnapshot) {
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) ->
|
|||
| ty::Projection(..)
|
||||
| ty::Param(_)
|
||||
| ty::Opaque(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(_)
|
||||
| ty::Bound(..)
|
||||
| ty::Generator(..) => false,
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
|
|||
if let ConstValue::Unevaluated(def_id, substs) = constant.val {
|
||||
let tcx = self.infcx.tcx.global_tcx();
|
||||
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
|
||||
if substs.needs_infer() || substs.has_skol() {
|
||||
if substs.needs_infer() || substs.has_placeholders() {
|
||||
let identity_substs = Substs::identity_for_item(tcx, def_id);
|
||||
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
|
||||
if let Some(instance) = instance {
|
||||
|
|
|
|||
|
|
@ -1726,7 +1726,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
let poly_trait_predicate = self.infcx()
|
||||
.resolve_type_vars_if_possible(&obligation.predicate);
|
||||
let (skol_trait_predicate, placeholder_map) = self.infcx()
|
||||
.replace_late_bound_regions_with_placeholders(&poly_trait_predicate);
|
||||
.replace_bound_vars_with_placeholders(&poly_trait_predicate);
|
||||
debug!(
|
||||
"match_projection_obligation_against_definition_bounds: \
|
||||
skol_trait_predicate={:?} placeholder_map={:?}",
|
||||
|
|
@ -2470,7 +2470,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
ty::Infer(ty::TyVar(_)) => Ambiguous,
|
||||
|
||||
ty::UnnormalizedProjection(..)
|
||||
| ty::Bound(_)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
| ty::Infer(ty::FreshFloatTy(_)) => {
|
||||
|
|
@ -2555,7 +2556,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::UnnormalizedProjection(..)
|
||||
| ty::Bound(_)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
| ty::Infer(ty::FreshFloatTy(_)) => {
|
||||
|
|
@ -2594,11 +2596,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
| ty::Char => Vec::new(),
|
||||
|
||||
ty::UnnormalizedProjection(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Param(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Projection(..)
|
||||
| ty::Bound(_)
|
||||
| ty::Bound(..)
|
||||
| ty::Infer(ty::TyVar(_))
|
||||
| ty::Infer(ty::FreshTy(_))
|
||||
| ty::Infer(ty::FreshIntTy(_))
|
||||
|
|
@ -2682,7 +2685,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
|
||||
self.in_snapshot(|this, snapshot| {
|
||||
let (skol_ty, placeholder_map) = this.infcx()
|
||||
.replace_late_bound_regions_with_placeholders(&ty);
|
||||
.replace_bound_vars_with_placeholders(&ty);
|
||||
let Normalized {
|
||||
value: normalized_ty,
|
||||
mut obligations,
|
||||
|
|
@ -2916,7 +2919,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
let trait_obligations: Vec<PredicateObligation<'_>> = self.in_snapshot(|this, snapshot| {
|
||||
let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
|
||||
let (trait_ref, placeholder_map) = this.infcx()
|
||||
.replace_late_bound_regions_with_placeholders(&poly_trait_ref);
|
||||
.replace_bound_vars_with_placeholders(&poly_trait_ref);
|
||||
let cause = obligation.derived_cause(ImplDerivedObligation);
|
||||
this.impl_or_trait_obligations(
|
||||
cause,
|
||||
|
|
@ -3119,7 +3122,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
|
||||
self.in_snapshot(|this, snapshot| {
|
||||
let (predicate, placeholder_map) = this.infcx()
|
||||
.replace_late_bound_regions_with_placeholders(&obligation.predicate);
|
||||
.replace_bound_vars_with_placeholders(&obligation.predicate);
|
||||
let trait_ref = predicate.trait_ref;
|
||||
let trait_def_id = trait_ref.def_id;
|
||||
let substs = trait_ref.substs;
|
||||
|
|
@ -3582,7 +3585,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
let (skol_obligation, placeholder_map) = self.infcx()
|
||||
.replace_late_bound_regions_with_placeholders(&obligation.predicate);
|
||||
.replace_bound_vars_with_placeholders(&obligation.predicate);
|
||||
let skol_obligation_trait_ref = skol_obligation.trait_ref;
|
||||
|
||||
let impl_substs = self.infcx
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
|
|||
use syntax::symbol::Symbol;
|
||||
|
||||
match t.sty {
|
||||
ty::Bound(bound_ty) if bound_ty.index == self.binder_index => {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
|
||||
self.types.insert(
|
||||
bound_ty.var.as_u32(),
|
||||
match bound_ty.kind {
|
||||
|
|
|
|||
|
|
@ -2243,7 +2243,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
|
|||
pub fn print_debug_stats(self) {
|
||||
sty_debug_print!(
|
||||
self,
|
||||
Adt, Array, Slice, RawPtr, Ref, FnDef, FnPtr,
|
||||
Adt, Array, Slice, RawPtr, Ref, FnDef, FnPtr, Placeholder,
|
||||
Generator, GeneratorWitness, Dynamic, Closure, Tuple, Bound,
|
||||
Param, Infer, UnnormalizedProjection, Projection, Opaque, Foreign);
|
||||
|
||||
|
|
|
|||
|
|
@ -212,7 +212,8 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
|
|||
ty::Infer(ty::TyVar(_)) => "inferred type".into(),
|
||||
ty::Infer(ty::IntVar(_)) => "integral variable".into(),
|
||||
ty::Infer(ty::FloatVar(_)) => "floating-point variable".into(),
|
||||
ty::Bound(_) |
|
||||
ty::Placeholder(..) => "placeholder type".into(),
|
||||
ty::Bound(..) => "bound type".into(),
|
||||
ty::Infer(ty::FreshTy(_)) => "fresh type".into(),
|
||||
ty::Infer(ty::FreshIntTy(_)) => "fresh integral type".into(),
|
||||
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||
ty::Foreign(def_id) => {
|
||||
Some(ForeignSimplifiedType(def_id))
|
||||
}
|
||||
ty::Bound(..) | ty::Infer(_) | ty::Error => None,
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) | ty::Error => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,8 +115,12 @@ impl FlagComputation {
|
|||
self.add_substs(&substs.substs);
|
||||
}
|
||||
|
||||
&ty::Bound(bound_ty) => {
|
||||
self.add_binder(bound_ty.index);
|
||||
&ty::Bound(debruijn, _) => {
|
||||
self.add_binder(debruijn);
|
||||
}
|
||||
|
||||
&ty::Placeholder(..) => {
|
||||
self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
|
||||
}
|
||||
|
||||
&ty::Infer(infer) => {
|
||||
|
|
|
|||
|
|
@ -102,14 +102,14 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
|||
fn needs_infer(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
|
||||
}
|
||||
fn has_skol(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_SKOL)
|
||||
fn has_placeholders(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER | TypeFlags::HAS_TY_PLACEHOLDER)
|
||||
}
|
||||
fn needs_subst(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::NEEDS_SUBST)
|
||||
}
|
||||
fn has_re_skol(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_SKOL)
|
||||
fn has_re_placeholders(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER)
|
||||
}
|
||||
fn has_closure_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
|
||||
|
|
@ -460,8 +460,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for BoundVarReplacer<'a, 'gcx, 'tcx>
|
|||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match t.sty {
|
||||
ty::Bound(bound_ty) => {
|
||||
if bound_ty.index == self.current_index {
|
||||
ty::Bound(debruijn, bound_ty) => {
|
||||
if debruijn == self.current_index {
|
||||
let fld_t = &mut self.fld_t;
|
||||
let ty = fld_t(bound_ty);
|
||||
ty::fold::shift_vars(
|
||||
|
|
@ -526,7 +526,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
T: TypeFoldable<'tcx>
|
||||
{
|
||||
// identity for bound types
|
||||
let fld_t = |bound_ty| self.mk_ty(ty::Bound(bound_ty));
|
||||
let fld_t = |bound_ty| self.mk_ty(ty::Bound(ty::INNERMOST, bound_ty));
|
||||
self.replace_escaping_bound_vars(value.skip_binder(), fld_r, fld_t)
|
||||
}
|
||||
|
||||
|
|
@ -722,16 +722,13 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Shifter<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn fold_ty(&mut self, ty: ty::Ty<'tcx>) -> ty::Ty<'tcx> {
|
||||
match ty.sty {
|
||||
ty::Bound(bound_ty) => {
|
||||
if self.amount == 0 || bound_ty.index < self.current_index {
|
||||
ty::Bound(debruijn, bound_ty) => {
|
||||
if self.amount == 0 || debruijn < self.current_index {
|
||||
ty
|
||||
} else {
|
||||
let shifted = ty::BoundTy {
|
||||
index: bound_ty.index.shifted_in(self.amount),
|
||||
var: bound_ty.var,
|
||||
kind: bound_ty.kind,
|
||||
};
|
||||
self.tcx.mk_ty(ty::Bound(shifted))
|
||||
self.tcx.mk_ty(
|
||||
ty::Bound(debruijn.shifted_in(self.amount), bound_ty)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -515,6 +515,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
|||
ty::Str |
|
||||
ty::FnPtr(_) |
|
||||
ty::Projection(_) |
|
||||
ty::Placeholder(..) |
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::Param(_) |
|
||||
ty::Opaque(..) |
|
||||
|
|
|
|||
|
|
@ -1159,6 +1159,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
}
|
||||
|
||||
ty::Bound(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::GeneratorWitness(..) |
|
||||
ty::Infer(_) => {
|
||||
|
|
@ -1743,7 +1744,8 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
|
|||
}
|
||||
|
||||
ty::Projection(_) | ty::UnnormalizedProjection(..) | ty::Bound(..) |
|
||||
ty::Opaque(..) | ty::Param(_) | ty::Infer(_) | ty::Error => {
|
||||
ty::Placeholder(..) | ty::Opaque(..) | ty::Param(_) | ty::Infer(_) |
|
||||
ty::Error => {
|
||||
bug!("TyLayout::field_type: unexpected type `{}`", this.ty)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -432,7 +432,7 @@ bitflags! {
|
|||
const HAS_SELF = 1 << 1;
|
||||
const HAS_TY_INFER = 1 << 2;
|
||||
const HAS_RE_INFER = 1 << 3;
|
||||
const HAS_RE_SKOL = 1 << 4;
|
||||
const HAS_RE_PLACEHOLDER = 1 << 4;
|
||||
|
||||
/// Does this have any `ReEarlyBound` regions? Used to
|
||||
/// determine whether substitition is required, since those
|
||||
|
|
@ -467,6 +467,8 @@ bitflags! {
|
|||
/// if a global bound is safe to evaluate.
|
||||
const HAS_RE_LATE_BOUND = 1 << 13;
|
||||
|
||||
const HAS_TY_PLACEHOLDER = 1 << 14;
|
||||
|
||||
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
|
||||
TypeFlags::HAS_SELF.bits |
|
||||
TypeFlags::HAS_RE_EARLY_BOUND.bits;
|
||||
|
|
@ -478,7 +480,7 @@ bitflags! {
|
|||
TypeFlags::HAS_SELF.bits |
|
||||
TypeFlags::HAS_TY_INFER.bits |
|
||||
TypeFlags::HAS_RE_INFER.bits |
|
||||
TypeFlags::HAS_RE_SKOL.bits |
|
||||
TypeFlags::HAS_RE_PLACEHOLDER.bits |
|
||||
TypeFlags::HAS_RE_EARLY_BOUND.bits |
|
||||
TypeFlags::HAS_FREE_REGIONS.bits |
|
||||
TypeFlags::HAS_TY_ERR.bits |
|
||||
|
|
@ -486,7 +488,8 @@ bitflags! {
|
|||
TypeFlags::HAS_TY_CLOSURE.bits |
|
||||
TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
|
||||
TypeFlags::KEEP_IN_LOCAL_TCX.bits |
|
||||
TypeFlags::HAS_RE_LATE_BOUND.bits;
|
||||
TypeFlags::HAS_RE_LATE_BOUND.bits |
|
||||
TypeFlags::HAS_TY_PLACEHOLDER.bits;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1587,12 +1590,27 @@ impl UniverseIndex {
|
|||
/// universe are just two regions with an unknown relationship to one
|
||||
/// another.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
|
||||
pub struct Placeholder {
|
||||
pub struct Placeholder<T> {
|
||||
pub universe: UniverseIndex,
|
||||
pub name: BoundRegion,
|
||||
pub name: T,
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct Placeholder { universe, name });
|
||||
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for Placeholder<T>
|
||||
where T: HashStable<StableHashingContext<'a>>
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(
|
||||
&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>
|
||||
) {
|
||||
self.universe.hash_stable(hcx, hasher);
|
||||
self.name.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
pub type PlaceholderRegion = Placeholder<BoundRegion>;
|
||||
|
||||
pub type PlaceholderType = Placeholder<BoundVar>;
|
||||
|
||||
/// When type checking, we use the `ParamEnv` to track
|
||||
/// details about the set of where-clauses that are in scope at this
|
||||
|
|
@ -1674,7 +1692,7 @@ impl<'tcx> ParamEnv<'tcx> {
|
|||
}
|
||||
|
||||
Reveal::All => {
|
||||
if value.has_skol()
|
||||
if value.has_placeholders()
|
||||
|| value.needs_infer()
|
||||
|| value.has_param_types()
|
||||
|| value.has_self_ty()
|
||||
|
|
@ -2430,6 +2448,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
|||
}
|
||||
}
|
||||
|
||||
Placeholder(..) |
|
||||
Bound(..) |
|
||||
Infer(..) => {
|
||||
bug!("unexpected type `{:?}` in sized_constraint_for_ty",
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
ty::FnDef(..) | // OutlivesFunction (*)
|
||||
ty::FnPtr(_) | // OutlivesFunction (*)
|
||||
ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*)
|
||||
ty::Placeholder(..) |
|
||||
ty::Bound(..) |
|
||||
ty::Error => {
|
||||
// (*) Bare functions and traits are both binders. In the
|
||||
|
|
|
|||
|
|
@ -746,6 +746,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
|||
ty::Infer(_) |
|
||||
ty::Param(..) |
|
||||
ty::Bound(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::Never |
|
||||
ty::Foreign(..) => return self
|
||||
};
|
||||
|
|
@ -792,6 +793,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
|||
ty::Error |
|
||||
ty::Infer(_) |
|
||||
ty::Bound(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::Param(..) |
|
||||
ty::Never |
|
||||
ty::Foreign(..) => false,
|
||||
|
|
|
|||
|
|
@ -201,7 +201,10 @@ pub enum TyKind<'tcx> {
|
|||
Param(ParamTy),
|
||||
|
||||
/// Bound type variable, used only when preparing a trait query.
|
||||
Bound(BoundTy),
|
||||
Bound(ty::DebruijnIndex, BoundTy),
|
||||
|
||||
/// A placeholder type - universally quantified higher-ranked type.
|
||||
Placeholder(ty::PlaceholderType),
|
||||
|
||||
/// A type variable used during type checking.
|
||||
Infer(InferTy),
|
||||
|
|
@ -1165,7 +1168,7 @@ pub enum RegionKind {
|
|||
|
||||
/// A placeholder region - basically the higher-ranked version of ReFree.
|
||||
/// Should not exist after typeck.
|
||||
RePlaceholder(ty::Placeholder),
|
||||
RePlaceholder(ty::PlaceholderRegion),
|
||||
|
||||
/// Empty lifetime is for data that is never accessed.
|
||||
/// Bottom in the region lattice. We treat ReEmpty somewhat
|
||||
|
|
@ -1242,7 +1245,6 @@ newtype_index! {
|
|||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct BoundTy {
|
||||
pub index: DebruijnIndex,
|
||||
pub var: BoundVar,
|
||||
pub kind: BoundTyKind,
|
||||
}
|
||||
|
|
@ -1253,13 +1255,12 @@ pub enum BoundTyKind {
|
|||
Param(InternedString),
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct BoundTy { index, var, kind });
|
||||
impl_stable_hash_for!(struct BoundTy { var, kind });
|
||||
impl_stable_hash_for!(enum self::BoundTyKind { Anon, Param(a) });
|
||||
|
||||
impl BoundTy {
|
||||
pub fn new(index: DebruijnIndex, var: BoundVar) -> Self {
|
||||
impl From<BoundVar> for BoundTy {
|
||||
fn from(var: BoundVar) -> Self {
|
||||
BoundTy {
|
||||
index,
|
||||
var,
|
||||
kind: BoundTyKind::Anon,
|
||||
}
|
||||
|
|
@ -1462,7 +1463,7 @@ impl RegionKind {
|
|||
}
|
||||
ty::RePlaceholder(..) => {
|
||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||
flags = flags | TypeFlags::HAS_RE_SKOL;
|
||||
flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
|
||||
}
|
||||
ty::ReLateBound(..) => {
|
||||
flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
|
||||
|
|
@ -1890,6 +1891,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
Foreign(..) |
|
||||
Param(_) |
|
||||
Bound(..) |
|
||||
Placeholder(..) |
|
||||
Infer(_) |
|
||||
Error => {}
|
||||
}
|
||||
|
|
@ -1953,7 +1955,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
|
||||
ty::Infer(ty::TyVar(_)) => false,
|
||||
|
||||
ty::Bound(_) |
|
||||
ty::Bound(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::Infer(ty::FreshTy(_)) |
|
||||
ty::Infer(ty::FreshIntTy(_)) |
|
||||
ty::Infer(ty::FreshFloatTy(_)) =>
|
||||
|
|
|
|||
|
|
@ -190,11 +190,12 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
|||
Substs::for_item(tcx, def_id, |param, _| {
|
||||
match param.kind {
|
||||
ty::GenericParamDefKind::Type { .. } => {
|
||||
tcx.mk_ty(ty::Bound(ty::BoundTy {
|
||||
index: ty::INNERMOST,
|
||||
var: ty::BoundVar::from(param.index),
|
||||
kind: ty::BoundTyKind::Param(param.name),
|
||||
})).into()
|
||||
tcx.mk_ty(
|
||||
ty::Bound(ty::INNERMOST, ty::BoundTy {
|
||||
var: ty::BoundVar::from(param.index),
|
||||
kind: ty::BoundTyKind::Param(param.name),
|
||||
})
|
||||
).into()
|
||||
}
|
||||
|
||||
ty::GenericParamDefKind::Lifetime => {
|
||||
|
|
@ -584,18 +585,18 @@ impl CanonicalUserSubsts<'tcx> {
|
|||
self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
|
||||
match kind.unpack() {
|
||||
UnpackedKind::Type(ty) => match ty.sty {
|
||||
ty::Bound(b) => {
|
||||
ty::Bound(debruijn, b) => {
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
assert_eq!(b.index, ty::INNERMOST);
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
cvar == b.var
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
|
||||
UnpackedKind::Lifetime(r) => match r {
|
||||
ty::ReLateBound(index, br) => {
|
||||
ty::ReLateBound(debruijn, br) => {
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
assert_eq!(*index, ty::INNERMOST);
|
||||
assert_eq!(*debruijn, ty::INNERMOST);
|
||||
cvar == br.assert_bound_var()
|
||||
}
|
||||
_ => false,
|
||||
|
|
|
|||
|
|
@ -952,7 +952,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// Can refer to a type which may drop.
|
||||
// FIXME(eddyb) check this against a ParamEnv.
|
||||
ty::Dynamic(..) | ty::Projection(..) | ty::Param(_) | ty::Bound(..) |
|
||||
ty::Opaque(..) | ty::Infer(_) | ty::Error => true,
|
||||
ty::Placeholder(..) | ty::Opaque(..) | ty::Infer(_) | ty::Error => true,
|
||||
|
||||
ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
|
|||
match parent_ty.sty {
|
||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) |
|
||||
ty::Str | ty::Infer(_) | ty::Param(_) | ty::Never | ty::Error |
|
||||
ty::Bound(..) | ty::Foreign(..) => {
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Foreign(..) => {
|
||||
}
|
||||
ty::Array(ty, len) => {
|
||||
push_const(stack, len);
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||
ty::Never |
|
||||
ty::Param(_) |
|
||||
ty::Bound(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::Foreign(..) => {
|
||||
// WfScalar, WfParameter, etc
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ use ty::{Bool, Char, Adt};
|
|||
use ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr};
|
||||
use ty::{Param, Bound, RawPtr, Ref, Never, Tuple};
|
||||
use ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque};
|
||||
use ty::{UnnormalizedProjection, Dynamic, Int, Uint, Infer};
|
||||
use ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer};
|
||||
use ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind};
|
||||
use util::nodemap::FxHashSet;
|
||||
|
||||
|
|
@ -792,7 +792,7 @@ define_print! {
|
|||
}
|
||||
ty::ReLateBound(_, br) |
|
||||
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
||||
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||
ty::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
|
||||
write!(f, "{}", br)
|
||||
}
|
||||
ty::ReScope(scope) if cx.identify_regions => {
|
||||
|
|
@ -1110,13 +1110,13 @@ define_print! {
|
|||
Infer(infer_ty) => write!(f, "{}", infer_ty),
|
||||
Error => write!(f, "[type error]"),
|
||||
Param(ref param_ty) => write!(f, "{}", param_ty),
|
||||
Bound(bound_ty) => {
|
||||
Bound(debruijn, bound_ty) => {
|
||||
match bound_ty.kind {
|
||||
ty::BoundTyKind::Anon => {
|
||||
if bound_ty.index == ty::INNERMOST {
|
||||
if debruijn == ty::INNERMOST {
|
||||
write!(f, "^{}", bound_ty.var.index())
|
||||
} else {
|
||||
write!(f, "^{}_{}", bound_ty.index.index(), bound_ty.var.index())
|
||||
write!(f, "^{}_{}", debruijn.index(), bound_ty.var.index())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1144,6 +1144,9 @@ define_print! {
|
|||
data.print(f, cx)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
Placeholder(placeholder) => {
|
||||
write!(f, "Placeholder({:?})", placeholder)
|
||||
}
|
||||
Opaque(def_id, substs) => {
|
||||
if cx.is_verbose {
|
||||
return write!(f, "Opaque({:?}, {:?})", def_id, substs);
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||
}
|
||||
ty::Error |
|
||||
ty::Infer(_) |
|
||||
ty::Placeholder(..) |
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::Projection(..) |
|
||||
ty::Bound(..) |
|
||||
|
|
|
|||
|
|
@ -727,6 +727,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
ty::Closure(..) |
|
||||
ty::Generator(..) |
|
||||
ty::GeneratorWitness(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::Projection(..) |
|
||||
ty::Opaque(..) |
|
||||
|
|
|
|||
|
|
@ -2193,7 +2193,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
|
|||
match ty.sty {
|
||||
ty::TyKind::Ref(ty::RegionKind::ReLateBound(_, br), _, _)
|
||||
| ty::TyKind::Ref(
|
||||
ty::RegionKind::RePlaceholder(ty::Placeholder { name: br, .. }),
|
||||
ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
|
||||
_,
|
||||
_,
|
||||
) => with_highlight_region_for_bound_region(*br, counter, || ty.to_string()),
|
||||
|
|
@ -2207,7 +2207,7 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
|
|||
match ty.sty {
|
||||
ty::TyKind::Ref(region, _, _) => match region {
|
||||
ty::RegionKind::ReLateBound(_, br)
|
||||
| ty::RegionKind::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
|
||||
with_highlight_region_for_bound_region(*br, counter, || region.to_string())
|
||||
}
|
||||
_ => region.to_string(),
|
||||
|
|
|
|||
|
|
@ -1230,7 +1230,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
mir: &Mir<'tcx>,
|
||||
_mir_def_id: DefId,
|
||||
longer_fr: RegionVid,
|
||||
placeholder: ty::Placeholder,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
) {
|
||||
debug!(
|
||||
"check_bound_universal_region(fr={:?}, placeholder={:?})",
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ crate enum RegionElement {
|
|||
|
||||
/// A placeholder (e.g., instantiated from a `for<'a> fn(&'a u32)`
|
||||
/// type).
|
||||
PlaceholderRegion(ty::Placeholder),
|
||||
PlaceholderRegion(ty::PlaceholderRegion),
|
||||
}
|
||||
|
||||
/// When we initially compute liveness, we use a bit matrix storing
|
||||
|
|
@ -219,17 +219,17 @@ impl<N: Idx> LivenessValues<N> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Maps from `ty::Placeholder` values that are used in the rest of
|
||||
/// Maps from `ty::PlaceholderRegion` values that are used in the rest of
|
||||
/// rustc to the internal `PlaceholderIndex` values that are used in
|
||||
/// NLL.
|
||||
#[derive(Default)]
|
||||
crate struct PlaceholderIndices {
|
||||
to_index: FxHashMap<ty::Placeholder, PlaceholderIndex>,
|
||||
from_index: IndexVec<PlaceholderIndex, ty::Placeholder>,
|
||||
to_index: FxHashMap<ty::PlaceholderRegion, PlaceholderIndex>,
|
||||
from_index: IndexVec<PlaceholderIndex, ty::PlaceholderRegion>,
|
||||
}
|
||||
|
||||
impl PlaceholderIndices {
|
||||
crate fn insert(&mut self, placeholder: ty::Placeholder) -> PlaceholderIndex {
|
||||
crate fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
|
||||
let PlaceholderIndices {
|
||||
to_index,
|
||||
from_index,
|
||||
|
|
@ -239,11 +239,11 @@ impl PlaceholderIndices {
|
|||
.or_insert_with(|| from_index.push(placeholder))
|
||||
}
|
||||
|
||||
crate fn lookup_index(&self, placeholder: ty::Placeholder) -> PlaceholderIndex {
|
||||
crate fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
|
||||
self.to_index[&placeholder]
|
||||
}
|
||||
|
||||
crate fn lookup_placeholder(&self, placeholder: PlaceholderIndex) -> ty::Placeholder {
|
||||
crate fn lookup_placeholder(&self, placeholder: PlaceholderIndex) -> ty::PlaceholderRegion {
|
||||
self.from_index[placeholder]
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +375,7 @@ impl<N: Idx> RegionValues<N> {
|
|||
crate fn placeholders_contained_in<'a>(
|
||||
&'a self,
|
||||
r: N,
|
||||
) -> impl Iterator<Item = ty::Placeholder> + 'a {
|
||||
) -> impl Iterator<Item = ty::PlaceholderRegion> + 'a {
|
||||
self.placeholders
|
||||
.row(r)
|
||||
.into_iter()
|
||||
|
|
@ -432,7 +432,7 @@ impl ToElementIndex for RegionVid {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToElementIndex for ty::Placeholder {
|
||||
impl ToElementIndex for ty::PlaceholderRegion {
|
||||
fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool {
|
||||
let index = values.placeholder_indices.lookup_index(self);
|
||||
values.placeholders.insert(row, index)
|
||||
|
|
|
|||
|
|
@ -777,7 +777,7 @@ impl MirTypeckRegionConstraints<'tcx> {
|
|||
fn placeholder_region(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
placeholder: ty::Placeholder,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
) -> ty::Region<'tcx> {
|
||||
let placeholder_index = self.placeholder_indices.insert(placeholder);
|
||||
match self.placeholder_index_to_region.get(placeholder_index) {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,10 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, '_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn next_placeholder_region(&mut self, placeholder: ty::Placeholder) -> ty::Region<'tcx> {
|
||||
fn next_placeholder_region(
|
||||
&mut self,
|
||||
placeholder: ty::PlaceholderRegion
|
||||
) -> ty::Region<'tcx> {
|
||||
if let Some(borrowck_context) = &mut self.borrowck_context {
|
||||
borrowck_context.constraints.placeholder_region(self.infcx, placeholder)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -378,6 +378,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
|||
ty::Error |
|
||||
ty::Bound(..) |
|
||||
ty::Infer(_) |
|
||||
ty::Placeholder(..) |
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::Projection(..) |
|
||||
ty::Param(_) |
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
mod program_clauses;
|
||||
|
||||
use chalk_engine::fallible::Fallible as ChalkEngineFallible;
|
||||
use chalk_engine::{context, hh::HhGoal, DelayedLiteral, ExClause};
|
||||
use chalk_engine::{context, hh::HhGoal, DelayedLiteral, Literal, ExClause};
|
||||
use rustc::infer::canonical::{
|
||||
Canonical, CanonicalVarValues, OriginalQueryValues, QueryRegionConstraint, QueryResponse,
|
||||
};
|
||||
|
|
@ -28,7 +28,7 @@ use rustc::traits::{
|
|||
InEnvironment,
|
||||
};
|
||||
use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use rustc::ty::subst::Kind;
|
||||
use rustc::ty::subst::{Kind, UnpackedKind};
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
|
||||
use std::fmt::{self, Debug};
|
||||
|
|
@ -44,7 +44,7 @@ crate struct ChalkArenas<'gcx> {
|
|||
#[derive(Copy, Clone)]
|
||||
crate struct ChalkContext<'cx, 'gcx: 'cx> {
|
||||
_arenas: ChalkArenas<'gcx>,
|
||||
_tcx: TyCtxt<'cx, 'gcx, 'gcx>,
|
||||
tcx: TyCtxt<'cx, 'gcx, 'gcx>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
@ -68,7 +68,7 @@ BraceStructTypeFoldableImpl! {
|
|||
}
|
||||
|
||||
impl context::Context for ChalkArenas<'tcx> {
|
||||
type CanonicalExClause = Canonical<'tcx, ExClause<Self>>;
|
||||
type CanonicalExClause = Canonical<'tcx, ChalkExClause<'tcx>>;
|
||||
|
||||
type CanonicalGoalInEnvironment = Canonical<'tcx, InEnvironment<'tcx, Goal<'tcx>>>;
|
||||
|
||||
|
|
@ -147,19 +147,29 @@ impl context::ContextOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
|
|||
/// - the environment and goal found by substitution `S` into `arg`
|
||||
fn instantiate_ucanonical_goal<R>(
|
||||
&self,
|
||||
_arg: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>,
|
||||
_op: impl context::WithInstantiatedUCanonicalGoal<ChalkArenas<'gcx>, Output = R>,
|
||||
arg: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>,
|
||||
op: impl context::WithInstantiatedUCanonicalGoal<ChalkArenas<'gcx>, Output = R>,
|
||||
) -> R {
|
||||
unimplemented!()
|
||||
self.tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, arg, |ref infcx, arg, subst| {
|
||||
let chalk_infcx = &mut ChalkInferenceContext {
|
||||
infcx,
|
||||
};
|
||||
op.with(chalk_infcx, subst, arg.environment, arg.goal)
|
||||
})
|
||||
}
|
||||
|
||||
fn instantiate_ex_clause<R>(
|
||||
&self,
|
||||
_num_universes: usize,
|
||||
_canonical_ex_clause: &Canonical<'gcx, ChalkExClause<'gcx>>,
|
||||
_op: impl context::WithInstantiatedExClause<ChalkArenas<'gcx>, Output = R>,
|
||||
arg: &Canonical<'gcx, ChalkExClause<'gcx>>,
|
||||
op: impl context::WithInstantiatedExClause<ChalkArenas<'gcx>, Output = R>,
|
||||
) -> R {
|
||||
unimplemented!()
|
||||
self.tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &arg.upcast(), |ref infcx, arg, _| {
|
||||
let chalk_infcx = &mut ChalkInferenceContext {
|
||||
infcx,
|
||||
};
|
||||
op.with(chalk_infcx,arg)
|
||||
})
|
||||
}
|
||||
|
||||
/// True if this solution has no region constraints.
|
||||
|
|
@ -186,14 +196,33 @@ impl context::ContextOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
|
|||
}
|
||||
|
||||
fn is_trivial_substitution(
|
||||
_u_canon: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>,
|
||||
_canonical_subst: &Canonical<'gcx, ConstrainedSubst<'gcx>>,
|
||||
u_canon: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>,
|
||||
canonical_subst: &Canonical<'tcx, ConstrainedSubst<'tcx>>,
|
||||
) -> bool {
|
||||
unimplemented!()
|
||||
let subst = &canonical_subst.value.subst;
|
||||
assert_eq!(u_canon.variables.len(), subst.var_values.len());
|
||||
subst.var_values
|
||||
.iter_enumerated()
|
||||
.all(|(cvar, kind)| match kind.unpack() {
|
||||
UnpackedKind::Lifetime(r) => match r {
|
||||
&ty::ReLateBound(debruijn, br) => {
|
||||
debug_assert_eq!(debruijn, ty::INNERMOST);
|
||||
cvar == br.assert_bound_var()
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
UnpackedKind::Type(ty) => match ty.sty {
|
||||
ty::Bound(debruijn, bound_ty) => {
|
||||
debug_assert_eq!(debruijn, ty::INNERMOST);
|
||||
cvar == bound_ty.var
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn num_universes(_: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>) -> usize {
|
||||
0 // FIXME
|
||||
fn num_universes(canon: &Canonical<'gcx, InEnvironment<'gcx, Goal<'gcx>>>) -> usize {
|
||||
canon.max_universe.index() + 1
|
||||
}
|
||||
|
||||
/// Convert a goal G *from* the canonical universes *into* our
|
||||
|
|
@ -214,39 +243,6 @@ impl context::ContextOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
|
|||
}
|
||||
}
|
||||
|
||||
//impl context::UCanonicalGoalInEnvironment<ChalkContext<'cx, 'gcx>>
|
||||
// for Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>>
|
||||
//{
|
||||
// fn canonical(&self) -> &Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>> {
|
||||
// self
|
||||
// }
|
||||
//
|
||||
// fn is_trivial_substitution(
|
||||
// &self,
|
||||
// canonical_subst: &Canonical<'tcx, ConstrainedSubst<'tcx>>,
|
||||
// ) -> bool {
|
||||
// let subst = &canonical_subst.value.subst;
|
||||
// assert_eq!(self.canonical.variables.len(), subst.var_values.len());
|
||||
// subst
|
||||
// .var_values
|
||||
// .iter_enumerated()
|
||||
// .all(|(cvar, kind)| match kind.unpack() {
|
||||
// Kind::Lifetime(r) => match r {
|
||||
// ty::ReCanonical(cvar1) => cvar == cvar1,
|
||||
// _ => false,
|
||||
// },
|
||||
// Kind::Type(ty) => match ty.sty {
|
||||
// ty::Infer(ty::InferTy::CanonicalTy(cvar1)) => cvar == cvar1,
|
||||
// _ => false,
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// fn num_universes(&self) -> usize {
|
||||
// 0 // FIXME
|
||||
// }
|
||||
//}
|
||||
|
||||
impl context::InferenceTable<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
|
||||
for ChalkInferenceContext<'cx, 'gcx, 'tcx>
|
||||
{
|
||||
|
|
@ -260,7 +256,10 @@ impl context::InferenceTable<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
|
|||
|
||||
fn into_hh_goal(&mut self, goal: Goal<'tcx>) -> ChalkHhGoal<'tcx> {
|
||||
match *goal {
|
||||
GoalKind::Implies(..) => panic!("FIXME rust-lang-nursery/chalk#94"),
|
||||
GoalKind::Implies(hypotheses, goal) => HhGoal::Implies(
|
||||
hypotheses.iter().cloned().collect(),
|
||||
goal
|
||||
),
|
||||
GoalKind::And(left, right) => HhGoal::And(left, right),
|
||||
GoalKind::Not(subgoal) => HhGoal::Not(subgoal),
|
||||
GoalKind::DomainGoal(d) => HhGoal::DomainGoal(d),
|
||||
|
|
@ -338,9 +337,9 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
|
|||
|
||||
fn instantiate_binders_universally(
|
||||
&mut self,
|
||||
_arg: &ty::Binder<Goal<'tcx>>,
|
||||
arg: &ty::Binder<Goal<'tcx>>,
|
||||
) -> Goal<'tcx> {
|
||||
panic!("FIXME -- universal instantiation needs sgrif's branch")
|
||||
self.infcx.replace_bound_vars_with_placeholders(arg).0
|
||||
}
|
||||
|
||||
fn instantiate_binders_existentially(
|
||||
|
|
@ -491,3 +490,68 @@ BraceStructLiftImpl! {
|
|||
subst, constraints
|
||||
}
|
||||
}
|
||||
|
||||
trait Upcast<'tcx, 'gcx: 'tcx>: 'gcx {
|
||||
type Upcasted: 'tcx;
|
||||
|
||||
fn upcast(&self) -> Self::Upcasted;
|
||||
}
|
||||
|
||||
impl<'tcx, 'gcx: 'tcx> Upcast<'tcx, 'gcx> for DelayedLiteral<ChalkArenas<'gcx>> {
|
||||
type Upcasted = DelayedLiteral<ChalkArenas<'tcx>>;
|
||||
|
||||
fn upcast(&self) -> Self::Upcasted {
|
||||
match self {
|
||||
&DelayedLiteral::CannotProve(..) => DelayedLiteral::CannotProve(()),
|
||||
&DelayedLiteral::Negative(index) => DelayedLiteral::Negative(index),
|
||||
DelayedLiteral::Positive(index, subst) => DelayedLiteral::Positive(
|
||||
*index,
|
||||
subst.clone()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 'gcx: 'tcx> Upcast<'tcx, 'gcx> for Literal<ChalkArenas<'gcx>> {
|
||||
type Upcasted = Literal<ChalkArenas<'tcx>>;
|
||||
|
||||
fn upcast(&self) -> Self::Upcasted {
|
||||
match self {
|
||||
&Literal::Negative(goal) => Literal::Negative(goal),
|
||||
&Literal::Positive(goal) => Literal::Positive(goal),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 'gcx: 'tcx> Upcast<'tcx, 'gcx> for ExClause<ChalkArenas<'gcx>> {
|
||||
type Upcasted = ExClause<ChalkArenas<'tcx>>;
|
||||
|
||||
fn upcast(&self) -> Self::Upcasted {
|
||||
ExClause {
|
||||
subst: self.subst.clone(),
|
||||
delayed_literals: self.delayed_literals
|
||||
.iter()
|
||||
.map(|l| l.upcast())
|
||||
.collect(),
|
||||
constraints: self.constraints.clone(),
|
||||
subgoals: self.subgoals
|
||||
.iter()
|
||||
.map(|g| g.upcast())
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 'gcx: 'tcx, T> Upcast<'tcx, 'gcx> for Canonical<'gcx, T>
|
||||
where T: Upcast<'tcx, 'gcx>
|
||||
{
|
||||
type Upcasted = Canonical<'tcx, T::Upcasted>;
|
||||
|
||||
fn upcast(&self) -> Self::Upcasted {
|
||||
Canonical {
|
||||
max_universe: self.max_universe,
|
||||
value: self.value.upcast(),
|
||||
variables: self.variables,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ fn assemble_clauses_from_assoc_ty_values<'tcx>(
|
|||
|
||||
fn program_clauses_for_raw_ptr<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> {
|
||||
let ty = ty::Bound(
|
||||
ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(0))
|
||||
ty::INNERMOST,
|
||||
ty::BoundVar::from_u32(0).into()
|
||||
);
|
||||
let ty = tcx.mk_ty(ty);
|
||||
|
||||
|
|
@ -88,9 +89,9 @@ fn program_clauses_for_fn_ptr<'tcx>(
|
|||
) -> Clauses<'tcx> {
|
||||
let inputs_and_output = tcx.mk_type_list(
|
||||
(0..arity_and_output).into_iter()
|
||||
.map(|i| ty::BoundVar::from(i))
|
||||
// DebruijnIndex(1) because we are going to inject these in a `PolyFnSig`
|
||||
.map(|i| ty::BoundTy::new(ty::DebruijnIndex::from(1usize), ty::BoundVar::from(i)))
|
||||
.map(|t| tcx.mk_ty(ty::Bound(t)))
|
||||
.map(|var| tcx.mk_ty(ty::Bound(ty::DebruijnIndex::from(1usize), var.into())))
|
||||
);
|
||||
|
||||
let fn_sig = ty::Binder::bind(ty::FnSig {
|
||||
|
|
@ -115,7 +116,8 @@ fn program_clauses_for_fn_ptr<'tcx>(
|
|||
|
||||
fn program_clauses_for_slice<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> {
|
||||
let ty = ty::Bound(
|
||||
ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(0))
|
||||
ty::INNERMOST,
|
||||
ty::BoundVar::from_u32(0).into()
|
||||
);
|
||||
let ty = tcx.mk_ty(ty);
|
||||
|
||||
|
|
@ -151,7 +153,8 @@ fn program_clauses_for_array<'tcx>(
|
|||
length: &'tcx ty::Const<'tcx>
|
||||
) -> Clauses<'tcx> {
|
||||
let ty = ty::Bound(
|
||||
ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(0))
|
||||
ty::INNERMOST,
|
||||
ty::BoundVar::from_u32(0).into()
|
||||
);
|
||||
let ty = tcx.mk_ty(ty);
|
||||
|
||||
|
|
@ -188,8 +191,8 @@ fn program_clauses_for_tuple<'tcx>(
|
|||
) -> Clauses<'tcx> {
|
||||
let type_list = tcx.mk_type_list(
|
||||
(0..arity).into_iter()
|
||||
.map(|i| ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from(i)))
|
||||
.map(|t| tcx.mk_ty(ty::Bound(t)))
|
||||
.map(|i| ty::BoundVar::from(i))
|
||||
.map(|var| tcx.mk_ty(ty::Bound(ty::INNERMOST, var.into())))
|
||||
);
|
||||
|
||||
let tuple_ty = tcx.mk_ty(ty::Tuple(type_list));
|
||||
|
|
@ -233,7 +236,7 @@ fn program_clauses_for_ref<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx>
|
|||
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
|
||||
);
|
||||
let ty = tcx.mk_ty(
|
||||
ty::Bound(ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(1)))
|
||||
ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(1).into())
|
||||
);
|
||||
|
||||
let ref_ty = tcx.mk_ref(region, ty::TypeAndMut {
|
||||
|
|
@ -418,6 +421,7 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::GeneratorWitness(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::Infer(..) |
|
||||
ty::Bound(..) |
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>(
|
|||
|
||||
ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
|
||||
|
||||
ty::Bound(..) | ty::Infer(..) | ty::Error => {
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => {
|
||||
// By the time this code runs, all type variables ought to
|
||||
// be fully resolved.
|
||||
Err(NoSolution)
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
|
|||
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
|
||||
);
|
||||
let ty = self.tcx.mk_ty(
|
||||
ty::Bound(ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(1)))
|
||||
ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(1).into())
|
||||
);
|
||||
|
||||
let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
|
||||
|
|
@ -114,6 +114,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
|
|||
ty::Tuple(..) |
|
||||
ty::Never |
|
||||
ty::Infer(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::Bound(..) => (),
|
||||
|
||||
ty::GeneratorWitness(..) |
|
||||
|
|
|
|||
|
|
@ -515,7 +515,8 @@ pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
|
|||
.unwrap_or(0);
|
||||
// Add a new type param after the existing ones (`U` in the comment above).
|
||||
let ty_var = ty::Bound(
|
||||
ty::BoundTy::new(ty::INNERMOST, ty::BoundVar::from_u32(offset + 1))
|
||||
ty::INNERMOST,
|
||||
ty::BoundVar::from_u32(offset + 1).into()
|
||||
);
|
||||
|
||||
// `ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U)`
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)),
|
||||
ty::Param(ref p) => Some(PointerKind::OfParam(p)),
|
||||
// Insufficient type information.
|
||||
ty::Bound(..) | ty::Infer(_) => None,
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,
|
||||
|
||||
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
|
||||
ty::Float(_) | ty::Array(..) | ty::GeneratorWitness(..) |
|
||||
|
|
|
|||
|
|
@ -1494,7 +1494,7 @@ impl<'tcx> Candidate<'tcx> {
|
|||
// `WhereClausePick`.
|
||||
assert!(
|
||||
!trait_ref.skip_binder().substs.needs_infer()
|
||||
&& !trait_ref.skip_binder().substs.has_skol()
|
||||
&& !trait_ref.skip_binder().substs.has_placeholders()
|
||||
);
|
||||
|
||||
WhereClausePick(trait_ref.clone())
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
|||
|
||||
fn write_ty_to_tables(&mut self, hir_id: hir::HirId, ty: Ty<'gcx>) {
|
||||
debug!("write_ty_to_tables({:?}, {:?})", hir_id, ty);
|
||||
assert!(!ty.needs_infer() && !ty.has_skol());
|
||||
assert!(!ty.needs_infer() && !ty.has_placeholders());
|
||||
self.tables.node_types_mut().insert(hir_id, ty);
|
||||
}
|
||||
|
||||
|
|
@ -580,7 +580,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
|||
if let Some(substs) = self.fcx.tables.borrow().node_substs_opt(hir_id) {
|
||||
let substs = self.resolve(&substs, &span);
|
||||
debug!("write_substs_to_tcx({:?}, {:?})", hir_id, substs);
|
||||
assert!(!substs.needs_infer() && !substs.has_skol());
|
||||
assert!(!substs.needs_infer() && !substs.has_placeholders());
|
||||
self.tables.node_substs_mut().insert(hir_id, substs);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -336,6 +336,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
// types, where we use Error as the Self type
|
||||
}
|
||||
|
||||
ty::Placeholder(..) |
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::GeneratorWitness(..) |
|
||||
ty::Bound(..) |
|
||||
|
|
|
|||
|
|
@ -2744,6 +2744,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
ty::Closure(..) | ty::Generator(..) => Tuple(vec![]), // FIXME(pcwalton)
|
||||
|
||||
ty::Bound(..) => panic!("Bound"),
|
||||
ty::Placeholder(..) => panic!("Placeholder"),
|
||||
ty::UnnormalizedProjection(..) => panic!("UnnormalizedProjection"),
|
||||
ty::GeneratorWitness(..) => panic!("GeneratorWitness"),
|
||||
ty::Infer(..) => panic!("Infer"),
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
//
|
||||
// dont-check-compiler-stdout
|
||||
// dont-check-compiler-stderr
|
||||
// compile-flags: --error-format human
|
||||
|
||||
// rustc-env:RUST_LOG=debug
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ error: user substs: Canonical { max_universe: U0, variables: [], value: UserSubs
|
|||
LL | let x = foo::<u32>; //~ ERROR [u32]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: user substs: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: UserSubsts { substs: [^0, u32, ^1], user_self_ty: None } }
|
||||
error: user substs: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }, CanonicalVarInfo { kind: Ty(General(U0)) }], value: UserSubsts { substs: [^0, u32, ^1], user_self_ty: None } }
|
||||
--> $DIR/dump-fn-method.rs:42:13
|
||||
|
|
||||
LL | let x = <_ as Bazoom<u32>>::method::<_>; //~ ERROR [^0, u32, ^1]
|
||||
|
|
@ -16,7 +16,7 @@ error: user substs: Canonical { max_universe: U0, variables: [], value: UserSubs
|
|||
LL | let x = <u8 as Bazoom<u16>>::method::<u32>; //~ ERROR [u8, u16, u32]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: user substs: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General) }, CanonicalVarInfo { kind: Ty(General) }], value: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None } }
|
||||
error: user substs: Canonical { max_universe: U1, variables: [CanonicalVarInfo { kind: Ty(General(U1)) }, CanonicalVarInfo { kind: Ty(General(U1)) }], value: UserSubsts { substs: [^0, ^1, u32], user_self_ty: None } }
|
||||
--> $DIR/dump-fn-method.rs:54:5
|
||||
|
|
||||
LL | y.method::<u32>(44, 66); //~ ERROR [^0, ^1, u32]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue