mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #76814 - jackh726:binder-refactor, r=nikomatsakis
Refactor `Binder` to track bound vars c.c. `@rust-lang/wg-traits` This is super early (and might just get closed at some point), but want to get at least an initial idea of the perf impact. r? `@ghost`
This commit is contained in:
commit
4fdac23f31
@ -402,7 +402,7 @@ pub enum TraitBoundModifier {
|
||||
/// `typeck::collect::compute_bounds` matches these against
|
||||
/// the "special" built-in traits (see `middle::lang_items`) and
|
||||
/// detects `Copy`, `Send` and `Sync`.
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
#[derive(Clone, Debug, HashStable_Generic)]
|
||||
pub enum GenericBound<'hir> {
|
||||
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
||||
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
|
||||
@ -2556,7 +2556,7 @@ pub enum UseKind {
|
||||
/// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the
|
||||
/// trait being referred to but just a unique `HirId` that serves as a key
|
||||
/// within the resolution map.
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
#[derive(Clone, Debug, HashStable_Generic)]
|
||||
pub struct TraitRef<'hir> {
|
||||
pub path: &'hir Path<'hir>,
|
||||
// Don't hash the `ref_id`. It is tracked via the thing it is used to access.
|
||||
@ -2575,7 +2575,7 @@ impl TraitRef<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, HashStable_Generic)]
|
||||
#[derive(Clone, Debug, HashStable_Generic)]
|
||||
pub struct PolyTraitRef<'hir> {
|
||||
/// The `'a` in `for<'a> Foo<&'a T>`.
|
||||
pub bound_generic_params: &'hir [GenericParam<'hir>],
|
||||
|
@ -293,7 +293,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<T>) -> ty::Binder<T>
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -621,7 +621,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
let var = self.canonical_var(info, r.into());
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(var.as_u32()) };
|
||||
let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32()) };
|
||||
let region = ty::ReLateBound(self.binder_index, br);
|
||||
self.tcx().mk_region(region)
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
|
||||
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
opt_values[br.assert_bound_var()] = Some(*original_value);
|
||||
opt_values[br.var] = Some(*original_value);
|
||||
}
|
||||
}
|
||||
GenericArgKind::Const(result_value) => {
|
||||
|
@ -71,11 +71,10 @@ where
|
||||
if var_values.var_values.is_empty() {
|
||||
value
|
||||
} else {
|
||||
let fld_r =
|
||||
|br: ty::BoundRegion| match var_values.var_values[br.assert_bound_var()].unpack() {
|
||||
GenericArgKind::Lifetime(l) => l,
|
||||
r => bug!("{:?} is a region but value is {:?}", br, r),
|
||||
};
|
||||
let fld_r = |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() {
|
||||
GenericArgKind::Lifetime(l) => l,
|
||||
r => bug!("{:?} is a region but value is {:?}", br, r),
|
||||
};
|
||||
|
||||
let fld_t = |bound_ty: ty::BoundTy| match var_values.var_values[bound_ty.var].unpack() {
|
||||
GenericArgKind::Type(ty) => ty,
|
||||
|
@ -545,9 +545,9 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
@ -840,9 +840,9 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
|
@ -124,9 +124,9 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
|
@ -514,7 +514,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
fn print_dyn_existential(
|
||||
self,
|
||||
_predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
_predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Result<Self::DynExistential, Self::Error> {
|
||||
Err(NonTrivialPath)
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
||||
// error. We will then search the function parameters for a bound
|
||||
// region at the right depth with the same index
|
||||
(
|
||||
Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)),
|
||||
Some(rl::Region::LateBoundAnon(debruijn_index, _, anon_index)),
|
||||
ty::BrAnon(br_index),
|
||||
) => {
|
||||
debug!(
|
||||
@ -143,7 +143,7 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
||||
// error. We will then search the function parameters for a bound
|
||||
// region at the right depth with the same index
|
||||
(
|
||||
Some(rl::Region::LateBound(debruijn_index, id, _)),
|
||||
Some(rl::Region::LateBound(debruijn_index, _, id, _)),
|
||||
ty::BrNamed(def_id, _),
|
||||
) => {
|
||||
debug!(
|
||||
@ -162,8 +162,8 @@ impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
|
||||
rl::Region::Static
|
||||
| rl::Region::Free(_, _)
|
||||
| rl::Region::EarlyBound(_, _, _)
|
||||
| rl::Region::LateBound(_, _, _)
|
||||
| rl::Region::LateBoundAnon(_, _),
|
||||
| rl::Region::LateBound(_, _, _, _)
|
||||
| rl::Region::LateBoundAnon(_, _, _),
|
||||
)
|
||||
| None,
|
||||
_,
|
||||
@ -217,7 +217,10 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> {
|
||||
fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) {
|
||||
match (self.tcx.named_region(lifetime.hir_id), self.bound_region) {
|
||||
// the lifetime of the TyPath!
|
||||
(Some(rl::Region::LateBoundAnon(debruijn_index, anon_index)), ty::BrAnon(br_index)) => {
|
||||
(
|
||||
Some(rl::Region::LateBoundAnon(debruijn_index, _, anon_index)),
|
||||
ty::BrAnon(br_index),
|
||||
) => {
|
||||
if debruijn_index == self.current_index && anon_index == br_index {
|
||||
self.found_it = true;
|
||||
return;
|
||||
@ -232,7 +235,7 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
(Some(rl::Region::LateBound(debruijn_index, id, _)), ty::BrNamed(def_id, _)) => {
|
||||
(Some(rl::Region::LateBound(debruijn_index, _, id, _)), ty::BrNamed(def_id, _)) => {
|
||||
debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index,);
|
||||
debug!("id={:?}", id);
|
||||
debug!("def_id={:?}", def_id);
|
||||
@ -246,8 +249,8 @@ impl Visitor<'tcx> for TyPathVisitor<'tcx> {
|
||||
Some(
|
||||
rl::Region::Static
|
||||
| rl::Region::EarlyBound(_, _, _)
|
||||
| rl::Region::LateBound(_, _, _)
|
||||
| rl::Region::LateBoundAnon(_, _)
|
||||
| rl::Region::LateBound(_, _, _, _)
|
||||
| rl::Region::LateBoundAnon(_, _, _)
|
||||
| rl::Region::Free(_, _),
|
||||
)
|
||||
| None,
|
||||
|
@ -85,9 +85,9 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
|
@ -11,10 +11,10 @@ use rustc_middle::ty::{self, Binder, TypeFoldable};
|
||||
impl<'a, 'tcx> CombineFields<'a, 'tcx> {
|
||||
pub fn higher_ranked_sub<T>(
|
||||
&mut self,
|
||||
a: Binder<T>,
|
||||
b: Binder<T>,
|
||||
a: Binder<'tcx, T>,
|
||||
b: Binder<'tcx, T>,
|
||||
a_is_expected: bool,
|
||||
) -> RelateResult<'tcx, Binder<T>>
|
||||
) -> RelateResult<'tcx, Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
@ -50,7 +50,10 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
|
||||
|
||||
debug!("higher_ranked_sub: OK result={:?}", result);
|
||||
|
||||
Ok(ty::Binder::bind(result))
|
||||
// We related `a_prime` and `b_prime`, which just had any bound vars
|
||||
// replaced with placeholders or infer vars, respectively. Relating
|
||||
// them should not introduce new bound vars.
|
||||
Ok(ty::Binder::dummy(result))
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -66,7 +69,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
/// the [rustc dev guide].
|
||||
///
|
||||
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
|
||||
pub fn replace_bound_vars_with_placeholders<T>(&self, binder: ty::Binder<T>) -> T
|
||||
pub fn replace_bound_vars_with_placeholders<T>(&self, binder: ty::Binder<'tcx, T>) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
|
@ -85,9 +85,9 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
|
@ -1406,7 +1406,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
span: Span,
|
||||
lbrct: LateBoundRegionConversionTime,
|
||||
value: ty::Binder<T>,
|
||||
value: ty::Binder<'tcx, T>,
|
||||
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
|
@ -157,7 +157,7 @@ where
|
||||
|
||||
fn create_scope(
|
||||
&mut self,
|
||||
value: ty::Binder<impl Relate<'tcx>>,
|
||||
value: ty::Binder<'tcx, impl Relate<'tcx>>,
|
||||
universally_quantified: UniversallyQuantified,
|
||||
) -> BoundRegionScope<'tcx> {
|
||||
let mut scope = BoundRegionScope::default();
|
||||
@ -608,9 +608,9 @@ where
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
@ -744,7 +744,7 @@ struct ScopeInstantiator<'me, 'tcx> {
|
||||
impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &ty::Binder<T>,
|
||||
t: &ty::Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.target_index.shift_in(1);
|
||||
t.super_visit_with(self);
|
||||
@ -997,9 +997,9 @@ where
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
_: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
_: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
|
@ -162,9 +162,9 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
|
@ -128,7 +128,7 @@ impl<'tcx> FulfillmentError<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TraitObligation<'tcx> {
|
||||
pub fn self_ty(&self) -> ty::Binder<Ty<'tcx>> {
|
||||
pub fn self_ty(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||
self.predicate.map_bound(|p| p.self_ty())
|
||||
}
|
||||
}
|
||||
|
@ -909,7 +909,7 @@ impl<'tcx> LateContext<'tcx> {
|
||||
|
||||
fn print_dyn_existential(
|
||||
self,
|
||||
_predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
_predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Result<Self::DynExistential, Self::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -70,16 +70,16 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionKind {
|
||||
ty::ReEmpty(universe) => {
|
||||
universe.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrAnon(i) }) => {
|
||||
ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrAnon(i), .. }) => {
|
||||
db.hash_stable(hcx, hasher);
|
||||
i.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrNamed(def_id, name) }) => {
|
||||
ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrNamed(def_id, name), .. }) => {
|
||||
db.hash_stable(hcx, hasher);
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
name.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrEnv }) => {
|
||||
ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrEnv, .. }) => {
|
||||
db.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
|
||||
@ -118,12 +118,13 @@ impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
|
||||
impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for ty::Binder<'tcx, T>
|
||||
where
|
||||
T: HashStable<StableHashingContext<'a>>,
|
||||
{
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
self.as_ref().skip_binder().hash_stable(hcx, hasher);
|
||||
self.bound_vars().hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ impl<'tcx, V> Canonical<'tcx, V> {
|
||||
}
|
||||
|
||||
pub type QueryOutlivesConstraint<'tcx> =
|
||||
ty::Binder<ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>;
|
||||
ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>;
|
||||
|
||||
TrivialTypeFoldableAndLiftImpls! {
|
||||
for <'tcx> {
|
||||
@ -314,7 +314,8 @@ impl<'tcx> CanonicalVarValues<'tcx> {
|
||||
tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into()
|
||||
}
|
||||
GenericArgKind::Lifetime(..) => {
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(i) };
|
||||
let br =
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(i), kind: ty::BrAnon(i) };
|
||||
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into()
|
||||
}
|
||||
GenericArgKind::Const(ct) => tcx
|
||||
|
@ -39,8 +39,13 @@ impl LifetimeDefOrigin {
|
||||
pub enum Region {
|
||||
Static,
|
||||
EarlyBound(/* index */ u32, /* lifetime decl */ DefId, LifetimeDefOrigin),
|
||||
LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId, LifetimeDefOrigin),
|
||||
LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32),
|
||||
LateBound(
|
||||
ty::DebruijnIndex,
|
||||
/* late-bound index */ u32,
|
||||
/* lifetime decl */ DefId,
|
||||
LifetimeDefOrigin,
|
||||
),
|
||||
LateBoundAnon(ty::DebruijnIndex, /* late-bound index */ u32, /* anon index */ u32),
|
||||
Free(DefId, /* lifetime decl */ DefId),
|
||||
}
|
||||
|
||||
@ -78,4 +83,6 @@ pub struct ResolveLifetimes {
|
||||
/// be late-bound if (a) it does NOT appear in a where-clause and
|
||||
/// (b) it DOES appear in the arguments.
|
||||
pub late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
|
||||
|
||||
pub late_bound_vars: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
|
||||
}
|
||||
|
@ -1290,6 +1290,10 @@ rustc_queries! {
|
||||
-> Option<Vec<ObjectLifetimeDefault>> {
|
||||
desc { "looking up lifetime defaults for a region on an item" }
|
||||
}
|
||||
query late_bound_vars_map(_: LocalDefId)
|
||||
-> Option<&'tcx FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {
|
||||
desc { "looking up late bound vars" }
|
||||
}
|
||||
|
||||
query visibility(def_id: DefId) -> ty::Visibility {
|
||||
eval_always
|
||||
|
@ -341,7 +341,7 @@ impl ObligationCauseCode<'_> {
|
||||
|
||||
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(ObligationCauseCode<'_>, 32);
|
||||
static_assert_size!(ObligationCauseCode<'_>, 40);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum StatementAsExpression {
|
||||
|
@ -112,9 +112,9 @@ impl TypeRelation<'tcx> for Match<'tcx> {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
|
@ -120,8 +120,9 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for Ty<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<ty::PredicateKind<'tcx>> {
|
||||
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
|
||||
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
|
||||
self.bound_vars().encode(e)?;
|
||||
encode_with_shorthand(e, &self.skip_binder(), TyEncoder::predicate_shorthands)
|
||||
}
|
||||
}
|
||||
@ -226,18 +227,22 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<ty::PredicateKind<'tcx>> {
|
||||
fn decode(decoder: &mut D) -> Result<ty::Binder<ty::PredicateKind<'tcx>>, D::Error> {
|
||||
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
|
||||
fn decode(decoder: &mut D) -> Result<ty::Binder<'tcx, ty::PredicateKind<'tcx>>, D::Error> {
|
||||
let bound_vars = Decodable::decode(decoder)?;
|
||||
// Handle shorthands first, if we have an usize > 0x80.
|
||||
Ok(ty::Binder::bind(if decoder.positioned_at_shorthand() {
|
||||
let pos = decoder.read_usize()?;
|
||||
assert!(pos >= SHORTHAND_OFFSET);
|
||||
let shorthand = pos - SHORTHAND_OFFSET;
|
||||
Ok(ty::Binder::bind_with_vars(
|
||||
if decoder.positioned_at_shorthand() {
|
||||
let pos = decoder.read_usize()?;
|
||||
assert!(pos >= SHORTHAND_OFFSET);
|
||||
let shorthand = pos - SHORTHAND_OFFSET;
|
||||
|
||||
decoder.with_position(shorthand, ty::PredicateKind::decode)?
|
||||
} else {
|
||||
ty::PredicateKind::decode(decoder)?
|
||||
}))
|
||||
decoder.with_position(shorthand, ty::PredicateKind::decode)?
|
||||
} else {
|
||||
ty::PredicateKind::decode(decoder)?
|
||||
},
|
||||
bound_vars,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,7 +324,7 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
|
||||
for ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>
|
||||
for ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
|
||||
{
|
||||
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
|
||||
let len = decoder.read_usize()?;
|
||||
@ -379,15 +384,23 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [mir::abstract_const::N
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVariableKind> {
|
||||
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
|
||||
let len = decoder.read_usize()?;
|
||||
Ok(decoder.tcx().mk_bound_variable_kinds((0..len).map(|_| Decodable::decode(decoder)))?)
|
||||
}
|
||||
}
|
||||
|
||||
impl_decodable_via_ref! {
|
||||
&'tcx ty::TypeckResults<'tcx>,
|
||||
&'tcx ty::List<Ty<'tcx>>,
|
||||
&'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
&'tcx Allocation,
|
||||
&'tcx mir::Body<'tcx>,
|
||||
&'tcx mir::UnsafetyCheckResult,
|
||||
&'tcx mir::BorrowCheckResult<'tcx>,
|
||||
&'tcx mir::coverage::CodeRegion
|
||||
&'tcx mir::coverage::CodeRegion,
|
||||
&'tcx ty::List<ty::BoundVariableKind>
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
@ -488,14 +501,16 @@ macro_rules! implement_ty_decoder {
|
||||
macro_rules! impl_binder_encode_decode {
|
||||
($($t:ty),+ $(,)?) => {
|
||||
$(
|
||||
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<$t> {
|
||||
impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for ty::Binder<'tcx, $t> {
|
||||
fn encode(&self, e: &mut E) -> Result<(), E::Error> {
|
||||
self.bound_vars().encode(e)?;
|
||||
self.as_ref().skip_binder().encode(e)
|
||||
}
|
||||
}
|
||||
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<$t> {
|
||||
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, $t> {
|
||||
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
|
||||
Ok(ty::Binder::bind(Decodable::decode(decoder)?))
|
||||
let bound_vars = Decodable::decode(decoder)?;
|
||||
Ok(ty::Binder::bind_with_vars(Decodable::decode(decoder)?, bound_vars))
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
@ -87,7 +87,8 @@ pub struct CtxtInterners<'tcx> {
|
||||
substs: InternedSet<'tcx, InternalSubsts<'tcx>>,
|
||||
canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>,
|
||||
region: InternedSet<'tcx, RegionKind>,
|
||||
poly_existential_predicates: InternedSet<'tcx, List<ty::Binder<ExistentialPredicate<'tcx>>>>,
|
||||
poly_existential_predicates:
|
||||
InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>,
|
||||
predicate: InternedSet<'tcx, PredicateInner<'tcx>>,
|
||||
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
|
||||
projs: InternedSet<'tcx, List<ProjectionKind>>,
|
||||
@ -95,6 +96,7 @@ pub struct CtxtInterners<'tcx> {
|
||||
const_: InternedSet<'tcx, Const<'tcx>>,
|
||||
/// Const allocations.
|
||||
allocation: InternedSet<'tcx, Allocation>,
|
||||
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
|
||||
}
|
||||
|
||||
impl<'tcx> CtxtInterners<'tcx> {
|
||||
@ -113,6 +115,7 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||
place_elems: Default::default(),
|
||||
const_: Default::default(),
|
||||
allocation: Default::default(),
|
||||
bound_variable_kinds: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +139,10 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn intern_predicate(&self, kind: Binder<PredicateKind<'tcx>>) -> &'tcx PredicateInner<'tcx> {
|
||||
fn intern_predicate(
|
||||
&self,
|
||||
kind: Binder<'tcx, PredicateKind<'tcx>>,
|
||||
) -> &'tcx PredicateInner<'tcx> {
|
||||
self.predicate
|
||||
.intern(kind, |kind| {
|
||||
let flags = super::flags::FlagComputation::for_predicate(kind);
|
||||
@ -449,7 +455,7 @@ pub struct TypeckResults<'tcx> {
|
||||
|
||||
/// Stores the type, expression, span and optional scope span of all types
|
||||
/// that are live across the yield of this generator (if a generator).
|
||||
pub generator_interior_types: ty::Binder<Vec<GeneratorInteriorTypeCause<'tcx>>>,
|
||||
pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
|
||||
|
||||
/// We sometimes treat byte string literals (which are of type `&[u8; N]`)
|
||||
/// as `&[u8]`, depending on the pattern in which they are used.
|
||||
@ -804,7 +810,7 @@ impl CanonicalUserType<'tcx> {
|
||||
ty::ReLateBound(debruijn, br) => {
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
assert_eq!(*debruijn, ty::INNERMOST);
|
||||
cvar == br.assert_bound_var()
|
||||
cvar == br.var
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
@ -1616,10 +1622,11 @@ nop_lift! {allocation; &'a Allocation => &'tcx Allocation}
|
||||
nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>}
|
||||
|
||||
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
|
||||
nop_list_lift! {poly_existential_predicates; ty::Binder<ExistentialPredicate<'a>> => ty::Binder<ExistentialPredicate<'tcx>>}
|
||||
nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>}
|
||||
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
|
||||
nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>}
|
||||
nop_list_lift! {projs; ProjectionKind => ProjectionKind}
|
||||
nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariableKind}
|
||||
|
||||
// This is the impl for `&'a InternalSubsts<'a>`.
|
||||
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
|
||||
@ -1965,8 +1972,8 @@ impl<'tcx> Hash for Interned<'tcx, PredicateInner<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Borrow<Binder<PredicateKind<'tcx>>> for Interned<'tcx, PredicateInner<'tcx>> {
|
||||
fn borrow<'a>(&'a self) -> &'a Binder<PredicateKind<'tcx>> {
|
||||
impl<'tcx> Borrow<Binder<'tcx, PredicateKind<'tcx>>> for Interned<'tcx, PredicateInner<'tcx>> {
|
||||
fn borrow<'a>(&'a self) -> &'a Binder<'tcx, PredicateKind<'tcx>> {
|
||||
&self.0.kind
|
||||
}
|
||||
}
|
||||
@ -2072,10 +2079,11 @@ slice_interners!(
|
||||
substs: _intern_substs(GenericArg<'tcx>),
|
||||
canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>),
|
||||
poly_existential_predicates:
|
||||
_intern_poly_existential_predicates(ty::Binder<ExistentialPredicate<'tcx>>),
|
||||
_intern_poly_existential_predicates(ty::Binder<'tcx, ExistentialPredicate<'tcx>>),
|
||||
predicates: _intern_predicates(Predicate<'tcx>),
|
||||
projs: _intern_projs(ProjectionKind),
|
||||
place_elems: _intern_place_elems(PlaceElem<'tcx>),
|
||||
bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind),
|
||||
);
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
@ -2158,7 +2166,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mk_predicate(self, binder: Binder<PredicateKind<'tcx>>) -> Predicate<'tcx> {
|
||||
pub fn mk_predicate(self, binder: Binder<'tcx, PredicateKind<'tcx>>) -> Predicate<'tcx> {
|
||||
let inner = self.interners.intern_predicate(binder);
|
||||
Predicate { inner }
|
||||
}
|
||||
@ -2167,7 +2175,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn reuse_or_mk_predicate(
|
||||
self,
|
||||
pred: Predicate<'tcx>,
|
||||
binder: Binder<PredicateKind<'tcx>>,
|
||||
binder: Binder<'tcx, PredicateKind<'tcx>>,
|
||||
) -> Predicate<'tcx> {
|
||||
if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
|
||||
}
|
||||
@ -2334,7 +2342,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
#[inline]
|
||||
pub fn mk_dynamic(
|
||||
self,
|
||||
obj: &'tcx List<ty::Binder<ExistentialPredicate<'tcx>>>,
|
||||
obj: &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
|
||||
reg: ty::Region<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
self.mk_ty(Dynamic(obj, reg))
|
||||
@ -2361,7 +2369,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mk_generator_witness(self, types: ty::Binder<&'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
|
||||
pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> {
|
||||
self.mk_ty(GeneratorWitness(types))
|
||||
}
|
||||
|
||||
@ -2466,8 +2474,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
pub fn intern_poly_existential_predicates(
|
||||
self,
|
||||
eps: &[ty::Binder<ExistentialPredicate<'tcx>>],
|
||||
) -> &'tcx List<ty::Binder<ExistentialPredicate<'tcx>>> {
|
||||
eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
|
||||
) -> &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
|
||||
assert!(!eps.is_empty());
|
||||
assert!(
|
||||
eps.array_windows()
|
||||
@ -2512,6 +2520,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
|
||||
}
|
||||
|
||||
pub fn intern_bound_variable_kinds(
|
||||
self,
|
||||
ts: &[ty::BoundVariableKind],
|
||||
) -> &'tcx List<ty::BoundVariableKind> {
|
||||
if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) }
|
||||
}
|
||||
|
||||
pub fn mk_fn_sig<I>(
|
||||
self,
|
||||
inputs: I,
|
||||
@ -2533,8 +2548,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
pub fn mk_poly_existential_predicates<
|
||||
I: InternAs<
|
||||
[ty::Binder<ExistentialPredicate<'tcx>>],
|
||||
&'tcx List<ty::Binder<ExistentialPredicate<'tcx>>>,
|
||||
[ty::Binder<'tcx, ExistentialPredicate<'tcx>>],
|
||||
&'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
|
||||
>,
|
||||
>(
|
||||
self,
|
||||
@ -2572,6 +2587,15 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
|
||||
}
|
||||
|
||||
pub fn mk_bound_variable_kinds<
|
||||
I: InternAs<[ty::BoundVariableKind], &'tcx List<ty::BoundVariableKind>>,
|
||||
>(
|
||||
self,
|
||||
iter: I,
|
||||
) -> I::Output {
|
||||
iter.intern_with(|xs| self.intern_bound_variable_kinds(xs))
|
||||
}
|
||||
|
||||
/// Walks upwards from `id` to find a node which might change lint levels with attributes.
|
||||
/// It stops at `bound` and just returns it if reached.
|
||||
pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
|
||||
@ -2648,6 +2672,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn object_lifetime_defaults(self, id: HirId) -> Option<Vec<ObjectLifetimeDefault>> {
|
||||
self.object_lifetime_defaults_map(id.owner)
|
||||
}
|
||||
|
||||
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
|
||||
self.mk_bound_variable_kinds(
|
||||
self.late_bound_vars_map(id.owner)
|
||||
.and_then(|map| map.get(&id.local_id).cloned())
|
||||
.unwrap_or_else(|| {
|
||||
bug!("No bound vars found for {:?} ({:?})", self.hir().node_to_string(id), id)
|
||||
})
|
||||
.iter(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl TyCtxtAt<'tcx> {
|
||||
|
@ -43,7 +43,7 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
||||
if ty.needs_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) }
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<T>) -> ty::Binder<T>
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
|
@ -57,7 +57,9 @@ pub enum TypeError<'tcx> {
|
||||
CyclicTy(Ty<'tcx>),
|
||||
CyclicConst(&'tcx ty::Const<'tcx>),
|
||||
ProjectionMismatched(ExpectedFound<DefId>),
|
||||
ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>>),
|
||||
ExistentialMismatch(
|
||||
ExpectedFound<&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>>,
|
||||
),
|
||||
ObjectUnsafeCoercion(DefId),
|
||||
ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
|
||||
|
||||
|
@ -22,7 +22,7 @@ impl FlagComputation {
|
||||
result
|
||||
}
|
||||
|
||||
pub fn for_predicate(binder: ty::Binder<ty::PredicateKind<'_>>) -> FlagComputation {
|
||||
pub fn for_predicate(binder: ty::Binder<'tcx, ty::PredicateKind<'_>>) -> FlagComputation {
|
||||
let mut result = FlagComputation::new();
|
||||
result.add_predicate(binder);
|
||||
result
|
||||
@ -53,7 +53,7 @@ impl FlagComputation {
|
||||
|
||||
/// Adds the flags/depth from a set of types that appear within the current type, but within a
|
||||
/// region binder.
|
||||
fn bound_computation<T, F>(&mut self, value: ty::Binder<T>, f: F)
|
||||
fn bound_computation<T, F>(&mut self, value: ty::Binder<'_, T>, f: F)
|
||||
where
|
||||
F: FnOnce(&mut Self, T),
|
||||
{
|
||||
@ -204,7 +204,7 @@ impl FlagComputation {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_predicate(&mut self, binder: ty::Binder<ty::PredicateKind<'_>>) {
|
||||
fn add_predicate(&mut self, binder: ty::Binder<'tcx, ty::PredicateKind<'_>>) {
|
||||
self.bound_computation(binder, |computation, atom| computation.add_predicate_atom(atom));
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sso::SsoHashSet;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
@ -161,7 +162,7 @@ impl TypeFoldable<'tcx> for hir::Constness {
|
||||
pub trait TypeFolder<'tcx>: Sized {
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
|
||||
|
||||
fn fold_binder<T>(&mut self, t: Binder<T>) -> Binder<T>
|
||||
fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -184,7 +185,10 @@ pub trait TypeFolder<'tcx>: Sized {
|
||||
pub trait TypeVisitor<'tcx>: Sized {
|
||||
type BreakTy = !;
|
||||
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
@ -322,7 +326,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<T>,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.outer_index.shift_in(1);
|
||||
let result = t.as_ref().skip_binder().visit_with(self);
|
||||
@ -400,7 +404,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: ty::Binder<T>) -> ty::Binder<T> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
@ -460,7 +467,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: ty::Binder<T>) -> ty::Binder<T> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
@ -538,7 +548,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// contain escaping bound types.
|
||||
pub fn replace_late_bound_regions<T, F>(
|
||||
self,
|
||||
value: Binder<T>,
|
||||
value: Binder<'tcx, T>,
|
||||
mut fld_r: F,
|
||||
) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)
|
||||
where
|
||||
@ -588,7 +598,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// types.
|
||||
pub fn replace_bound_vars<T, F, G, H>(
|
||||
self,
|
||||
value: Binder<T>,
|
||||
value: Binder<'tcx, T>,
|
||||
mut fld_r: F,
|
||||
fld_t: G,
|
||||
fld_c: H,
|
||||
@ -607,7 +617,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
/// Replaces any late-bound regions bound in `value` with
|
||||
/// free variants attached to `all_outlive_scope`.
|
||||
pub fn liberate_late_bound_regions<T>(self, all_outlive_scope: DefId, value: ty::Binder<T>) -> T
|
||||
pub fn liberate_late_bound_regions<T>(
|
||||
self,
|
||||
all_outlive_scope: DefId,
|
||||
value: ty::Binder<'tcx, T>,
|
||||
) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -620,13 +634,49 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
.0
|
||||
}
|
||||
|
||||
pub fn shift_bound_var_indices<T>(self, bound_vars: usize, value: T) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
self.replace_escaping_bound_vars(
|
||||
value,
|
||||
|r| {
|
||||
self.mk_region(ty::ReLateBound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(r.var.as_usize() + bound_vars),
|
||||
kind: r.kind,
|
||||
},
|
||||
))
|
||||
},
|
||||
|t| {
|
||||
self.mk_ty(ty::Bound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundTy {
|
||||
var: ty::BoundVar::from_usize(t.var.as_usize() + bound_vars),
|
||||
kind: t.kind,
|
||||
},
|
||||
))
|
||||
},
|
||||
|c, ty| {
|
||||
self.mk_const(ty::Const {
|
||||
val: ty::ConstKind::Bound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundVar::from_usize(c.as_usize() + bound_vars),
|
||||
),
|
||||
ty,
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a set of all late-bound regions that are constrained
|
||||
/// by `value`, meaning that if we instantiate those LBR with
|
||||
/// variables and equate `value` with something else, those
|
||||
/// variables will also be equated.
|
||||
pub fn collect_constrained_late_bound_regions<T>(
|
||||
self,
|
||||
value: &Binder<T>,
|
||||
value: &Binder<'tcx, T>,
|
||||
) -> FxHashSet<ty::BoundRegionKind>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
@ -637,7 +687,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Returns a set of all late-bound regions that appear in `value` anywhere.
|
||||
pub fn collect_referenced_late_bound_regions<T>(
|
||||
self,
|
||||
value: &Binder<T>,
|
||||
value: &Binder<'tcx, T>,
|
||||
) -> FxHashSet<ty::BoundRegionKind>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
@ -647,7 +697,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
fn collect_late_bound_regions<T>(
|
||||
self,
|
||||
value: &Binder<T>,
|
||||
value: &Binder<'tcx, T>,
|
||||
just_constraint: bool,
|
||||
) -> FxHashSet<ty::BoundRegionKind>
|
||||
where
|
||||
@ -661,7 +711,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
/// Replaces any late-bound regions bound in `value` with `'erased`. Useful in codegen but also
|
||||
/// method lookup and a few other places where precise region relationships are not required.
|
||||
pub fn erase_late_bound_regions<T>(self, value: Binder<T>) -> T
|
||||
pub fn erase_late_bound_regions<T>(self, value: Binder<'tcx, T>) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -676,20 +726,205 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
|
||||
/// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
|
||||
/// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
|
||||
pub fn anonymize_late_bound_regions<T>(self, sig: Binder<T>) -> Binder<T>
|
||||
pub fn anonymize_late_bound_regions<T>(self, sig: Binder<'tcx, T>) -> Binder<'tcx, T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
let mut counter = 0;
|
||||
Binder::bind(
|
||||
self.replace_late_bound_regions(sig, |_| {
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(counter) };
|
||||
let inner = self
|
||||
.replace_late_bound_regions(sig, |_| {
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(counter),
|
||||
kind: ty::BrAnon(counter),
|
||||
};
|
||||
let r = self.mk_region(ty::ReLateBound(ty::INNERMOST, br));
|
||||
counter += 1;
|
||||
r
|
||||
})
|
||||
.0,
|
||||
)
|
||||
.0;
|
||||
let bound_vars = self.mk_bound_variable_kinds(
|
||||
(0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i))),
|
||||
);
|
||||
Binder::bind_with_vars(inner, bound_vars)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BoundVarsCollector<'tcx> {
|
||||
binder_index: ty::DebruijnIndex,
|
||||
vars: BTreeMap<u32, ty::BoundVariableKind>,
|
||||
// We may encounter the same variable at different levels of binding, so
|
||||
// this can't just be `Ty`
|
||||
visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>,
|
||||
}
|
||||
|
||||
impl<'tcx> BoundVarsCollector<'tcx> {
|
||||
pub fn new() -> Self {
|
||||
BoundVarsCollector {
|
||||
binder_index: ty::INNERMOST,
|
||||
vars: BTreeMap::new(),
|
||||
visited: SsoHashSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_vars(self, tcx: TyCtxt<'tcx>) -> &'tcx ty::List<ty::BoundVariableKind> {
|
||||
let max = self.vars.iter().map(|(k, _)| *k).max().unwrap_or_else(|| 0);
|
||||
for i in 0..max {
|
||||
if let None = self.vars.get(&i) {
|
||||
panic!("Unknown variable: {:?}", i);
|
||||
}
|
||||
}
|
||||
|
||||
tcx.mk_bound_variable_kinds(self.vars.into_iter().map(|(_, v)| v))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
|
||||
type BreakTy = ();
|
||||
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.binder_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if t.outer_exclusive_binder < self.binder_index
|
||||
|| !self.visited.insert((self.binder_index, t))
|
||||
{
|
||||
return ControlFlow::CONTINUE;
|
||||
}
|
||||
use std::collections::btree_map::Entry;
|
||||
match *t.kind() {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
|
||||
match self.vars.entry(bound_ty.var.as_u32()) {
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(ty::BoundVariableKind::Ty(bound_ty.kind));
|
||||
}
|
||||
Entry::Occupied(entry) => match entry.get() {
|
||||
ty::BoundVariableKind::Ty(_) => {}
|
||||
_ => bug!("Conflicting bound vars"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
_ => (),
|
||||
};
|
||||
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match r {
|
||||
ty::ReLateBound(index, _br) if *index == self.binder_index => {
|
||||
// If you hit this, you should be using `Binder::bind_with_vars` or `Binder::rebind`
|
||||
bug!("Trying to collect bound vars with a bound region: {:?} {:?}", index, _br)
|
||||
}
|
||||
|
||||
_ => (),
|
||||
};
|
||||
|
||||
r.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ValidateBoundVars<'tcx> {
|
||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||
binder_index: ty::DebruijnIndex,
|
||||
// We may encounter the same variable at different levels of binding, so
|
||||
// this can't just be `Ty`
|
||||
visited: SsoHashSet<(ty::DebruijnIndex, Ty<'tcx>)>,
|
||||
}
|
||||
|
||||
impl<'tcx> ValidateBoundVars<'tcx> {
|
||||
pub fn new(bound_vars: &'tcx ty::List<ty::BoundVariableKind>) -> Self {
|
||||
ValidateBoundVars {
|
||||
bound_vars,
|
||||
binder_index: ty::INNERMOST,
|
||||
visited: SsoHashSet::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for ValidateBoundVars<'tcx> {
|
||||
type BreakTy = ();
|
||||
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.binder_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if t.outer_exclusive_binder < self.binder_index
|
||||
|| !self.visited.insert((self.binder_index, t))
|
||||
{
|
||||
return ControlFlow::BREAK;
|
||||
}
|
||||
match *t.kind() {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
|
||||
if self.bound_vars.len() <= bound_ty.var.as_usize() {
|
||||
bug!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars);
|
||||
}
|
||||
let list_var = self.bound_vars[bound_ty.var.as_usize()];
|
||||
match list_var {
|
||||
ty::BoundVariableKind::Ty(kind) => {
|
||||
if kind != bound_ty.kind {
|
||||
bug!(
|
||||
"Mismatched type kinds: {:?} doesn't var in list {:?}",
|
||||
bound_ty.kind,
|
||||
list_var
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
bug!("Mismatched bound variable kinds! Expected type, found {:?}", list_var)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => (),
|
||||
};
|
||||
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match r {
|
||||
ty::ReLateBound(index, br) if *index == self.binder_index => {
|
||||
if self.bound_vars.len() <= br.var.as_usize() {
|
||||
bug!("Not enough bound vars: {:?} not found in {:?}", *br, self.bound_vars);
|
||||
}
|
||||
let list_var = self.bound_vars[br.var.as_usize()];
|
||||
match list_var {
|
||||
ty::BoundVariableKind::Region(kind) => {
|
||||
if kind != br.kind {
|
||||
bug!(
|
||||
"Mismatched region kinds: {:?} doesn't match var ({:?}) in list ({:?})",
|
||||
br.kind,
|
||||
list_var,
|
||||
self.bound_vars
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => bug!(
|
||||
"Mismatched bound variable kinds! Expected region, found {:?}",
|
||||
list_var
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
_ => (),
|
||||
};
|
||||
|
||||
r.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -719,7 +954,10 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: ty::Binder<T>) -> ty::Binder<T> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
@ -828,7 +1066,10 @@ struct HasEscapingVarsVisitor {
|
||||
impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
|
||||
type BreakTy = FoundEscapingVars;
|
||||
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.outer_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.outer_index.shift_out(1);
|
||||
@ -974,7 +1215,10 @@ impl LateBoundRegionsCollector {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.current_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
|
@ -1,3 +1,4 @@
|
||||
// ignore-tidy-filelength
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
|
||||
@ -2481,21 +2482,42 @@ impl<'tcx> ty::Instance<'tcx> {
|
||||
ty::Closure(def_id, substs) => {
|
||||
let sig = substs.as_closure().sig();
|
||||
|
||||
let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
|
||||
sig.map_bound(|sig| {
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(
|
||||
sig.bound_vars()
|
||||
.iter()
|
||||
.chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
|
||||
);
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
kind: ty::BoundRegionKind::BrEnv,
|
||||
};
|
||||
let env_region = ty::ReLateBound(ty::INNERMOST, br);
|
||||
let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
|
||||
|
||||
let sig = sig.skip_binder();
|
||||
ty::Binder::bind_with_vars(
|
||||
tcx.mk_fn_sig(
|
||||
iter::once(env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
|
||||
iter::once(env_ty).chain(sig.inputs().iter().cloned()),
|
||||
sig.output(),
|
||||
sig.c_variadic,
|
||||
sig.unsafety,
|
||||
sig.abi,
|
||||
)
|
||||
})
|
||||
),
|
||||
bound_vars,
|
||||
)
|
||||
}
|
||||
ty::Generator(_, substs, _) => {
|
||||
let sig = substs.as_generator().poly_sig();
|
||||
|
||||
let br = ty::BoundRegion { kind: ty::BrEnv };
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(
|
||||
sig.bound_vars()
|
||||
.iter()
|
||||
.chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
|
||||
);
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
kind: ty::BoundRegionKind::BrEnv,
|
||||
};
|
||||
let env_region = ty::ReLateBound(ty::INNERMOST, br);
|
||||
let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
|
||||
|
||||
@ -2504,21 +2526,21 @@ impl<'tcx> ty::Instance<'tcx> {
|
||||
let pin_substs = tcx.intern_substs(&[env_ty.into()]);
|
||||
let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs);
|
||||
|
||||
sig.map_bound(|sig| {
|
||||
let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
|
||||
let state_adt_ref = tcx.adt_def(state_did);
|
||||
let state_substs =
|
||||
tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
|
||||
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
|
||||
|
||||
let sig = sig.skip_binder();
|
||||
let state_did = tcx.require_lang_item(LangItem::GeneratorState, None);
|
||||
let state_adt_ref = tcx.adt_def(state_did);
|
||||
let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
|
||||
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
|
||||
ty::Binder::bind_with_vars(
|
||||
tcx.mk_fn_sig(
|
||||
[env_ty, sig.resume_ty].iter(),
|
||||
&ret_ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
rustc_target::spec::abi::Abi::Rust,
|
||||
)
|
||||
})
|
||||
),
|
||||
bound_vars,
|
||||
)
|
||||
}
|
||||
_ => bug!("unexpected type {:?} in Instance::fn_sig", ty),
|
||||
}
|
||||
|
@ -67,12 +67,12 @@ pub use self::sty::BoundRegionKind::*;
|
||||
pub use self::sty::RegionKind::*;
|
||||
pub use self::sty::TyKind::*;
|
||||
pub use self::sty::{
|
||||
Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, CanonicalPolyFnSig,
|
||||
ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion, ExistentialPredicate,
|
||||
ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, GeneratorSubsts,
|
||||
GeneratorSubstsParts, ParamConst, ParamTy, PolyExistentialProjection, PolyExistentialTraitRef,
|
||||
PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind, RegionVid, TraitRef,
|
||||
TyKind, TypeAndMut, UpvarSubsts,
|
||||
Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, BoundVariableKind,
|
||||
CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion,
|
||||
ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig,
|
||||
GeneratorSubsts, GeneratorSubstsParts, ParamConst, ParamTy, PolyExistentialProjection,
|
||||
PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind,
|
||||
RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts,
|
||||
};
|
||||
pub use self::trait_def::TraitDef;
|
||||
|
||||
@ -302,7 +302,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
|
||||
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(TyS<'_>, 32);
|
||||
static_assert_size!(TyS<'_>, 40);
|
||||
|
||||
impl<'tcx> Ord for TyS<'tcx> {
|
||||
fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
|
||||
@ -359,14 +359,14 @@ impl ty::EarlyBoundRegion {
|
||||
|
||||
#[derive(Debug)]
|
||||
crate struct PredicateInner<'tcx> {
|
||||
kind: Binder<PredicateKind<'tcx>>,
|
||||
kind: Binder<'tcx, PredicateKind<'tcx>>,
|
||||
flags: TypeFlags,
|
||||
/// See the comment for the corresponding field of [TyS].
|
||||
outer_exclusive_binder: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(PredicateInner<'_>, 40);
|
||||
static_assert_size!(PredicateInner<'_>, 48);
|
||||
|
||||
#[derive(Clone, Copy, Lift)]
|
||||
pub struct Predicate<'tcx> {
|
||||
@ -389,9 +389,9 @@ impl Hash for Predicate<'_> {
|
||||
impl<'tcx> Eq for Predicate<'tcx> {}
|
||||
|
||||
impl<'tcx> Predicate<'tcx> {
|
||||
/// Gets the inner `Binder<PredicateKind<'tcx>>`.
|
||||
/// Gets the inner `Binder<'tcx, PredicateKind<'tcx>>`.
|
||||
#[inline]
|
||||
pub fn kind(self) -> Binder<PredicateKind<'tcx>> {
|
||||
pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> {
|
||||
self.inner.kind
|
||||
}
|
||||
}
|
||||
@ -543,10 +543,33 @@ impl<'tcx> Predicate<'tcx> {
|
||||
// substitution code expects equal binding levels in the values
|
||||
// from the substitution and the value being substituted into, and
|
||||
// this trick achieves that).
|
||||
let substs = trait_ref.skip_binder().substs;
|
||||
let pred = self.kind().skip_binder();
|
||||
let new = pred.subst(tcx, substs);
|
||||
tcx.reuse_or_mk_predicate(self, ty::Binder::bind(new))
|
||||
|
||||
// Working through the second example:
|
||||
// trait_ref: for<'x> T: Foo1<'^0.0>; substs: [T, '^0.0]
|
||||
// predicate: for<'b> Self: Bar1<'a, '^0.0>; substs: [Self, 'a, '^0.0]
|
||||
// We want to end up with:
|
||||
// for<'x, 'b> T: Bar1<'^0.0, '^0.1>
|
||||
// To do this:
|
||||
// 1) We must shift all bound vars in predicate by the length
|
||||
// of trait ref's bound vars. So, we would end up with predicate like
|
||||
// Self: Bar1<'a, '^0.1>
|
||||
// 2) We can then apply the trait substs to this, ending up with
|
||||
// T: Bar1<'^0.0, '^0.1>
|
||||
// 3) Finally, to create the final bound vars, we concatenate the bound
|
||||
// vars of the trait ref with those of the predicate:
|
||||
// ['x, 'b]
|
||||
let bound_pred = self.kind();
|
||||
let pred_bound_vars = bound_pred.bound_vars();
|
||||
let trait_bound_vars = trait_ref.bound_vars();
|
||||
// 1) Self: Bar1<'a, '^0.0> -> Self: Bar1<'a, '^0.1>
|
||||
let shifted_pred =
|
||||
tcx.shift_bound_var_indices(trait_bound_vars.len(), bound_pred.skip_binder());
|
||||
// 2) Self: Bar1<'a, '^0.1> -> T: Bar1<'^0.0, '^0.1>
|
||||
let new = shifted_pred.subst(tcx, trait_ref.skip_binder().substs);
|
||||
// 3) ['x] + ['b] -> ['x, 'b]
|
||||
let bound_vars =
|
||||
tcx.mk_bound_variable_kinds(trait_bound_vars.iter().chain(pred_bound_vars));
|
||||
tcx.reuse_or_mk_predicate(self, ty::Binder::bind_with_vars(new, bound_vars))
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,7 +579,7 @@ pub struct TraitPredicate<'tcx> {
|
||||
pub trait_ref: TraitRef<'tcx>,
|
||||
}
|
||||
|
||||
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
|
||||
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
|
||||
|
||||
impl<'tcx> TraitPredicate<'tcx> {
|
||||
pub fn def_id(self) -> DefId {
|
||||
@ -574,7 +597,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||
self.skip_binder().def_id()
|
||||
}
|
||||
|
||||
pub fn self_ty(self) -> ty::Binder<Ty<'tcx>> {
|
||||
pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||
self.map_bound(|trait_ref| trait_ref.self_ty())
|
||||
}
|
||||
}
|
||||
@ -584,8 +607,8 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||
pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B`
|
||||
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>;
|
||||
pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
|
||||
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>;
|
||||
pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<TypeOutlivesPredicate<'tcx>>;
|
||||
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>;
|
||||
pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable)]
|
||||
@ -594,7 +617,7 @@ pub struct SubtypePredicate<'tcx> {
|
||||
pub a: Ty<'tcx>,
|
||||
pub b: Ty<'tcx>,
|
||||
}
|
||||
pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>;
|
||||
pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;
|
||||
|
||||
/// This kind of predicate has no *direct* correspondent in the
|
||||
/// syntax, but it roughly corresponds to the syntactic forms:
|
||||
@ -615,7 +638,7 @@ pub struct ProjectionPredicate<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
|
||||
pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyProjectionPredicate<'tcx> {
|
||||
/// Returns the `DefId` of the trait of the associated item being projected.
|
||||
@ -637,7 +660,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
|
||||
self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx))
|
||||
}
|
||||
|
||||
pub fn ty(&self) -> Binder<Ty<'tcx>> {
|
||||
pub fn ty(&self) -> Binder<'tcx, Ty<'tcx>> {
|
||||
self.map_bound(|predicate| predicate.ty)
|
||||
}
|
||||
|
||||
@ -671,7 +694,7 @@ pub trait ToPredicate<'tcx> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx>;
|
||||
}
|
||||
|
||||
impl ToPredicate<'tcx> for Binder<PredicateKind<'tcx>> {
|
||||
impl ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
tcx.mk_predicate(self)
|
||||
@ -694,11 +717,11 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
ConstnessAnd {
|
||||
value: self.value.map_bound(|trait_ref| ty::TraitPredicate { trait_ref }),
|
||||
constness: self.constness,
|
||||
}
|
||||
.to_predicate(tcx)
|
||||
self.value
|
||||
.map_bound(|trait_ref| {
|
||||
PredicateKind::Trait(ty::TraitPredicate { trait_ref }, self.constness)
|
||||
})
|
||||
.to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// If you have a `Binder<T>`, you can do this to strip out the
|
||||
/// If you have a `Binder<'tcx, T>`, you can do this to strip out the
|
||||
/// late-bound regions and then normalize the result, yielding up
|
||||
/// a `T` (with regions erased). This is appropriate when the
|
||||
/// binder is being instantiated at the call site.
|
||||
@ -49,7 +49,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn normalize_erasing_late_bound_regions<T>(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
value: ty::Binder<T>,
|
||||
value: ty::Binder<'tcx, T>,
|
||||
) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
|
@ -63,7 +63,7 @@ pub trait Printer<'tcx>: Sized {
|
||||
|
||||
fn print_dyn_existential(
|
||||
self,
|
||||
predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Result<Self::DynExistential, Self::Error>;
|
||||
|
||||
fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error>;
|
||||
@ -346,7 +346,7 @@ impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx, P: Printer<'tcx>> Print<'tcx, P>
|
||||
for &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>
|
||||
for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
|
||||
{
|
||||
type Output = P::DynExistential;
|
||||
type Error = P::Error;
|
||||
|
@ -202,7 +202,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
self.print_def_path(def_id, substs)
|
||||
}
|
||||
|
||||
fn in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, Self::Error>
|
||||
fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error>
|
||||
where
|
||||
T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -211,7 +211,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
|
||||
fn wrap_binder<T, F: Fn(&T, Self) -> Result<Self, fmt::Error>>(
|
||||
self,
|
||||
value: &ty::Binder<T>,
|
||||
value: &ty::Binder<'tcx, T>,
|
||||
f: F,
|
||||
) -> Result<Self, Self::Error>
|
||||
where
|
||||
@ -765,7 +765,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||
|
||||
fn pretty_print_dyn_existential(
|
||||
mut self,
|
||||
predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Result<Self::DynExistential, Self::Error> {
|
||||
// Generate the main trait ref, including associated types.
|
||||
let mut first = true;
|
||||
@ -1432,7 +1432,7 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
||||
|
||||
fn print_dyn_existential(
|
||||
self,
|
||||
predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Result<Self::DynExistential, Self::Error> {
|
||||
self.pretty_print_dyn_existential(predicates)
|
||||
}
|
||||
@ -1571,7 +1571,7 @@ impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, Self::Error>
|
||||
fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error>
|
||||
where
|
||||
T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -1580,7 +1580,7 @@ impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
||||
|
||||
fn wrap_binder<T, C: Fn(&T, Self) -> Result<Self, Self::Error>>(
|
||||
self,
|
||||
value: &ty::Binder<T>,
|
||||
value: &ty::Binder<'tcx, T>,
|
||||
f: C,
|
||||
) -> Result<Self, Self::Error>
|
||||
where
|
||||
@ -1636,7 +1636,7 @@ impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
|
||||
data.name != kw::Empty && data.name != kw::UnderscoreLifetime
|
||||
}
|
||||
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: br })
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
||||
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
|
||||
| ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||
if let ty::BrNamed(_, name) = br {
|
||||
@ -1715,7 +1715,7 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
|
||||
return Ok(self);
|
||||
}
|
||||
}
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: br })
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
||||
| ty::ReFree(ty::FreeRegion { bound_region: br, .. })
|
||||
| ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||
if let ty::BrNamed(_, name) = br {
|
||||
@ -1763,7 +1763,7 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
|
||||
impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
pub fn name_all_regions<T>(
|
||||
mut self,
|
||||
value: &ty::Binder<T>,
|
||||
value: &ty::Binder<'tcx, T>,
|
||||
) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error>
|
||||
where
|
||||
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
|
||||
@ -1821,7 +1821,8 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
|
||||
}
|
||||
};
|
||||
self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind }))
|
||||
self.tcx
|
||||
.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
|
||||
});
|
||||
start_or_continue(&mut self, "", "> ")?;
|
||||
|
||||
@ -1830,7 +1831,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
Ok((self, new_value))
|
||||
}
|
||||
|
||||
pub fn pretty_in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, fmt::Error>
|
||||
pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error>
|
||||
where
|
||||
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -1844,7 +1845,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
|
||||
pub fn pretty_wrap_binder<T, C: Fn(&T, Self) -> Result<Self, fmt::Error>>(
|
||||
self,
|
||||
value: &ty::Binder<T>,
|
||||
value: &ty::Binder<'tcx, T>,
|
||||
f: C,
|
||||
) -> Result<Self, fmt::Error>
|
||||
where
|
||||
@ -1858,14 +1859,14 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
Ok(inner)
|
||||
}
|
||||
|
||||
fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<T>)
|
||||
fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
|
||||
impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) = *r {
|
||||
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
|
||||
self.0.insert(name);
|
||||
}
|
||||
r.super_visit_with(self)
|
||||
@ -1879,7 +1880,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<T>
|
||||
impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T>
|
||||
where
|
||||
T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -1966,28 +1967,28 @@ impl ty::TraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl ty::Binder<ty::TraitRef<'tcx>> {
|
||||
pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>> {
|
||||
impl ty::Binder<'tcx, ty::TraitRef<'tcx>> {
|
||||
pub fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>> {
|
||||
self.map_bound(|tr| tr.print_only_trait_path())
|
||||
}
|
||||
}
|
||||
|
||||
forward_display_to_print! {
|
||||
Ty<'tcx>,
|
||||
&'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
&'tcx ty::Const<'tcx>,
|
||||
|
||||
// HACK(eddyb) these are exhaustive instead of generic,
|
||||
// because `for<'tcx>` isn't possible yet.
|
||||
ty::Binder<ty::ExistentialPredicate<'tcx>>,
|
||||
ty::Binder<ty::TraitRef<'tcx>>,
|
||||
ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>>,
|
||||
ty::Binder<ty::FnSig<'tcx>>,
|
||||
ty::Binder<ty::TraitPredicate<'tcx>>,
|
||||
ty::Binder<ty::SubtypePredicate<'tcx>>,
|
||||
ty::Binder<ty::ProjectionPredicate<'tcx>>,
|
||||
ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
|
||||
ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>,
|
||||
ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>,
|
||||
ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
|
||||
ty::Binder<'tcx, ty::FnSig<'tcx>>,
|
||||
ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
|
||||
ty::Binder<'tcx, ty::SubtypePredicate<'tcx>>,
|
||||
ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>,
|
||||
ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
|
||||
ty::Binder<'tcx, ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>,
|
||||
|
||||
ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
|
||||
ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
|
||||
|
@ -93,9 +93,9 @@ pub trait TypeRelation<'tcx>: Sized {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>;
|
||||
}
|
||||
@ -594,7 +594,7 @@ fn check_const_value_eq<R: TypeRelation<'tcx>>(
|
||||
})
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>> {
|
||||
impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> {
|
||||
fn relate<R: TypeRelation<'tcx>>(
|
||||
relation: &mut R,
|
||||
a: Self,
|
||||
@ -619,10 +619,9 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'
|
||||
let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| {
|
||||
use crate::ty::ExistentialPredicate::*;
|
||||
match (ep_a.skip_binder(), ep_b.skip_binder()) {
|
||||
(Trait(a), Trait(b)) => Ok(ty::Binder::bind(Trait(
|
||||
relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
|
||||
))),
|
||||
(Projection(a), Projection(b)) => Ok(ty::Binder::bind(Projection(
|
||||
(Trait(a), Trait(b)) => Ok(ep_a
|
||||
.rebind(Trait(relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder()))),
|
||||
(Projection(a), Projection(b)) => Ok(ep_a.rebind(Projection(
|
||||
relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
|
||||
))),
|
||||
(AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))),
|
||||
@ -685,12 +684,12 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder<T> {
|
||||
impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder<'tcx, T> {
|
||||
fn relate<R: TypeRelation<'tcx>>(
|
||||
relation: &mut R,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>> {
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>> {
|
||||
relation.binders(a, b)
|
||||
}
|
||||
}
|
||||
|
@ -454,10 +454,16 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
|
||||
type Lifted = ty::Binder<T::Lifted>;
|
||||
impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<'a, T>
|
||||
where
|
||||
<T as Lift<'tcx>>::Lifted: TypeFoldable<'tcx>,
|
||||
{
|
||||
type Lifted = ty::Binder<'tcx, T::Lifted>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
self.map_bound(|v| tcx.lift(v)).transpose()
|
||||
let bound_vars = tcx.lift(self.bound_vars());
|
||||
tcx.lift(self.skip_binder())
|
||||
.zip(bound_vars)
|
||||
.map(|(value, vars)| ty::Binder::bind_with_vars(value, vars))
|
||||
}
|
||||
}
|
||||
|
||||
@ -749,7 +755,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
self.map_bound(|ty| ty.fold_with(folder))
|
||||
}
|
||||
@ -767,7 +773,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>> {
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
use self::TyKind::*;
|
||||
|
||||
use crate::infer::canonical::Canonical;
|
||||
use crate::ty::fold::BoundVarsCollector;
|
||||
use crate::ty::fold::ValidateBoundVars;
|
||||
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
|
||||
use crate::ty::InferTy::{self, *};
|
||||
use crate::ty::{
|
||||
@ -62,22 +64,10 @@ pub enum BoundRegionKind {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)]
|
||||
#[derive(HashStable)]
|
||||
pub struct BoundRegion {
|
||||
pub var: BoundVar,
|
||||
pub kind: BoundRegionKind,
|
||||
}
|
||||
|
||||
impl BoundRegion {
|
||||
/// When canonicalizing, we replace unbound inference variables and free
|
||||
/// regions with anonymous late bound regions. This method asserts that
|
||||
/// we have an anonymous late bound region, which hence may refer to
|
||||
/// a canonical variable.
|
||||
pub fn assert_bound_var(&self) -> BoundVar {
|
||||
match self.kind {
|
||||
BoundRegionKind::BrAnon(var) => BoundVar::from_u32(var),
|
||||
_ => bug!("bound region is not anonymous"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BoundRegionKind {
|
||||
pub fn is_named(&self) -> bool {
|
||||
match *self {
|
||||
@ -161,7 +151,7 @@ pub enum TyKind<'tcx> {
|
||||
FnPtr(PolyFnSig<'tcx>),
|
||||
|
||||
/// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
|
||||
Dynamic(&'tcx List<Binder<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
|
||||
Dynamic(&'tcx List<Binder<'tcx, ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
|
||||
|
||||
/// The anonymous type of a closure. Used to represent the type of
|
||||
/// `|a| a`.
|
||||
@ -173,7 +163,7 @@ pub enum TyKind<'tcx> {
|
||||
|
||||
/// A type representing the types stored inside a generator.
|
||||
/// This should only appear in GeneratorInteriors.
|
||||
GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>),
|
||||
GeneratorWitness(Binder<'tcx, &'tcx List<Ty<'tcx>>>),
|
||||
|
||||
/// The never type `!`.
|
||||
Never,
|
||||
@ -232,7 +222,7 @@ impl TyKind<'tcx> {
|
||||
|
||||
// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(TyKind<'_>, 24);
|
||||
static_assert_size!(TyKind<'_>, 32);
|
||||
|
||||
/// A closure can be modeled as a struct that looks like:
|
||||
///
|
||||
@ -747,7 +737,7 @@ impl<'tcx> ExistentialPredicate<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
|
||||
impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> {
|
||||
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
|
||||
use crate::ty::ToPredicate;
|
||||
match self.skip_binder() {
|
||||
@ -768,7 +758,7 @@ impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> List<ty::Binder<ExistentialPredicate<'tcx>>> {
|
||||
impl<'tcx> List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> {
|
||||
/// Returns the "principal `DefId`" of this set of existential predicates.
|
||||
///
|
||||
/// A Rust trait object type consists (in addition to a lifetime bound)
|
||||
@ -794,7 +784,7 @@ impl<'tcx> List<ty::Binder<ExistentialPredicate<'tcx>>> {
|
||||
/// is `{Send, Sync}`, while there is no principal. These trait objects
|
||||
/// have a "trivial" vtable consisting of just the size, alignment,
|
||||
/// and destructor.
|
||||
pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
|
||||
pub fn principal(&self) -> Option<ty::Binder<'tcx, ExistentialTraitRef<'tcx>>> {
|
||||
self[0]
|
||||
.map_bound(|this| match this {
|
||||
ExistentialPredicate::Trait(tr) => Some(tr),
|
||||
@ -810,7 +800,7 @@ impl<'tcx> List<ty::Binder<ExistentialPredicate<'tcx>>> {
|
||||
#[inline]
|
||||
pub fn projection_bounds<'a>(
|
||||
&'a self,
|
||||
) -> impl Iterator<Item = ty::Binder<ExistentialProjection<'tcx>>> + 'a {
|
||||
) -> impl Iterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> + 'a {
|
||||
self.iter().filter_map(|predicate| {
|
||||
predicate
|
||||
.map_bound(|pred| match pred {
|
||||
@ -875,10 +865,10 @@ impl<'tcx> TraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
|
||||
pub type PolyTraitRef<'tcx> = Binder<'tcx, TraitRef<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyTraitRef<'tcx> {
|
||||
pub fn self_ty(&self) -> Binder<Ty<'tcx>> {
|
||||
pub fn self_ty(&self) -> Binder<'tcx, Ty<'tcx>> {
|
||||
self.map_bound_ref(|tr| tr.self_ty())
|
||||
}
|
||||
|
||||
@ -931,7 +921,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub type PolyExistentialTraitRef<'tcx> = Binder<ExistentialTraitRef<'tcx>>;
|
||||
pub type PolyExistentialTraitRef<'tcx> = Binder<'tcx, ExistentialTraitRef<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyExistentialTraitRef<'tcx> {
|
||||
pub fn def_id(&self) -> DefId {
|
||||
@ -947,36 +937,56 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable)]
|
||||
pub enum BoundVariableKind {
|
||||
Ty(BoundTyKind),
|
||||
Region(BoundRegionKind),
|
||||
Const,
|
||||
}
|
||||
|
||||
/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
|
||||
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
|
||||
/// (which would be represented by the type `PolyTraitRef ==
|
||||
/// Binder<TraitRef>`). Note that when we instantiate,
|
||||
/// Binder<'tcx, TraitRef>`). Note that when we instantiate,
|
||||
/// erase, or otherwise "discharge" these bound vars, we change the
|
||||
/// type from `Binder<T>` to just `T` (see
|
||||
/// type from `Binder<'tcx, T>` to just `T` (see
|
||||
/// e.g., `liberate_late_bound_regions`).
|
||||
///
|
||||
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct Binder<T>(T);
|
||||
pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>);
|
||||
|
||||
impl<T> Binder<T> {
|
||||
impl<'tcx, T> Binder<'tcx, T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
/// Wraps `value` in a binder, asserting that `value` does not
|
||||
/// contain any bound vars that would be bound by the
|
||||
/// binder. This is commonly used to 'inject' a value T into a
|
||||
/// different binding level.
|
||||
pub fn dummy<'tcx>(value: T) -> Binder<T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
pub fn dummy(value: T) -> Binder<'tcx, T> {
|
||||
debug_assert!(!value.has_escaping_bound_vars());
|
||||
Binder(value)
|
||||
Binder(value, ty::List::empty())
|
||||
}
|
||||
|
||||
/// Wraps `value` in a binder, binding higher-ranked vars (if any).
|
||||
pub fn bind(value: T) -> Binder<T> {
|
||||
Binder(value)
|
||||
pub fn bind(value: T, tcx: TyCtxt<'tcx>) -> Binder<'tcx, T> {
|
||||
let mut collector = BoundVarsCollector::new();
|
||||
value.visit_with(&mut collector);
|
||||
Binder(value, collector.into_vars(tcx))
|
||||
}
|
||||
|
||||
pub fn bind_with_vars(value: T, vars: &'tcx List<BoundVariableKind>) -> Binder<'tcx, T> {
|
||||
if cfg!(debug_assertions) {
|
||||
let mut validator = ValidateBoundVars::new(vars);
|
||||
value.visit_with(&mut validator);
|
||||
}
|
||||
Binder(value, vars)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Binder<'tcx, T> {
|
||||
/// Skips the binder and returns the "bound" value. This is a
|
||||
/// risky thing to do because it's easy to get confused about
|
||||
/// De Bruijn indices and the like. It is usually better to
|
||||
@ -997,22 +1007,39 @@ impl<T> Binder<T> {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn as_ref(&self) -> Binder<&T> {
|
||||
Binder(&self.0)
|
||||
pub fn bound_vars(&self) -> &'tcx List<BoundVariableKind> {
|
||||
self.1
|
||||
}
|
||||
|
||||
pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
|
||||
pub fn as_ref(&self) -> Binder<'tcx, &T> {
|
||||
Binder(&self.0, self.1)
|
||||
}
|
||||
|
||||
pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
|
||||
where
|
||||
F: FnOnce(&T) -> U,
|
||||
{
|
||||
let value = f(&self.0);
|
||||
Binder(value, self.1)
|
||||
}
|
||||
|
||||
pub fn map_bound_ref<F, U: TypeFoldable<'tcx>>(&self, f: F) -> Binder<'tcx, U>
|
||||
where
|
||||
F: FnOnce(&T) -> U,
|
||||
{
|
||||
self.as_ref().map_bound(f)
|
||||
}
|
||||
|
||||
pub fn map_bound<F, U>(self, f: F) -> Binder<U>
|
||||
pub fn map_bound<F, U: TypeFoldable<'tcx>>(self, f: F) -> Binder<'tcx, U>
|
||||
where
|
||||
F: FnOnce(T) -> U,
|
||||
{
|
||||
Binder(f(self.0))
|
||||
let value = f(self.0);
|
||||
if cfg!(debug_assertions) {
|
||||
let mut validator = ValidateBoundVars::new(self.1);
|
||||
value.visit_with(&mut validator);
|
||||
}
|
||||
Binder(value, self.1)
|
||||
}
|
||||
|
||||
/// Wraps a `value` in a binder, using the same bound variables as the
|
||||
@ -1024,8 +1051,15 @@ impl<T> Binder<T> {
|
||||
/// don't actually track bound vars. However, semantically, it is different
|
||||
/// because bound vars aren't allowed to change here, whereas they are
|
||||
/// in `bind`. This may be (debug) asserted in the future.
|
||||
pub fn rebind<U>(&self, value: U) -> Binder<U> {
|
||||
Binder(value)
|
||||
pub fn rebind<U>(&self, value: U) -> Binder<'tcx, U>
|
||||
where
|
||||
U: TypeFoldable<'tcx>,
|
||||
{
|
||||
if cfg!(debug_assertions) {
|
||||
let mut validator = ValidateBoundVars::new(self.bound_vars());
|
||||
value.visit_with(&mut validator);
|
||||
}
|
||||
Binder(value, self.1)
|
||||
}
|
||||
|
||||
/// Unwraps and returns the value within, but only if it contains
|
||||
@ -1038,45 +1072,32 @@ impl<T> Binder<T> {
|
||||
/// binders, but that would require adjusting the debruijn
|
||||
/// indices, and given the shallow binding structure we often use,
|
||||
/// would not be that useful.)
|
||||
pub fn no_bound_vars<'tcx>(self) -> Option<T>
|
||||
pub fn no_bound_vars(self) -> Option<T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
|
||||
}
|
||||
|
||||
/// Given two things that have the same binder level,
|
||||
/// and an operation that wraps on their contents, executes the operation
|
||||
/// and then wraps its result.
|
||||
///
|
||||
/// `f` should consider bound regions at depth 1 to be free, and
|
||||
/// anything it produces with bound regions at depth 1 will be
|
||||
/// bound in the resulting return value.
|
||||
pub fn fuse<U, F, R>(self, u: Binder<U>, f: F) -> Binder<R>
|
||||
where
|
||||
F: FnOnce(T, U) -> R,
|
||||
{
|
||||
Binder(f(self.0, u.0))
|
||||
}
|
||||
|
||||
/// Splits the contents into two things that share the same binder
|
||||
/// level as the original, returning two distinct binders.
|
||||
///
|
||||
/// `f` should consider bound regions at depth 1 to be free, and
|
||||
/// anything it produces with bound regions at depth 1 will be
|
||||
/// bound in the resulting return values.
|
||||
pub fn split<U, V, F>(self, f: F) -> (Binder<U>, Binder<V>)
|
||||
pub fn split<U, V, F>(self, f: F) -> (Binder<'tcx, U>, Binder<'tcx, V>)
|
||||
where
|
||||
F: FnOnce(T) -> (U, V),
|
||||
{
|
||||
let (u, v) = f(self.0);
|
||||
(Binder(u), Binder(v))
|
||||
(Binder(u, self.1), Binder(v, self.1))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Binder<Option<T>> {
|
||||
pub fn transpose(self) -> Option<Binder<T>> {
|
||||
self.0.map(Binder)
|
||||
impl<'tcx, T> Binder<'tcx, Option<T>> {
|
||||
pub fn transpose(self) -> Option<Binder<'tcx, T>> {
|
||||
let bound_vars = self.1;
|
||||
self.0.map(|v| Binder(v, bound_vars))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1139,7 +1160,7 @@ pub struct GenSig<'tcx> {
|
||||
pub return_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
pub type PolyGenSig<'tcx> = Binder<GenSig<'tcx>>;
|
||||
pub type PolyGenSig<'tcx> = Binder<'tcx, GenSig<'tcx>>;
|
||||
|
||||
/// Signature of a function type, which we have arbitrarily
|
||||
/// decided to use to refer to the input/output types.
|
||||
@ -1177,22 +1198,22 @@ impl<'tcx> FnSig<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
|
||||
pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyFnSig<'tcx> {
|
||||
#[inline]
|
||||
pub fn inputs(&self) -> Binder<&'tcx [Ty<'tcx>]> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.inputs())
|
||||
pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> {
|
||||
self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs())
|
||||
}
|
||||
#[inline]
|
||||
pub fn input(&self, index: usize) -> ty::Binder<Ty<'tcx>> {
|
||||
pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
|
||||
}
|
||||
pub fn inputs_and_output(&self) -> ty::Binder<&'tcx List<Ty<'tcx>>> {
|
||||
pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
|
||||
}
|
||||
#[inline]
|
||||
pub fn output(&self) -> ty::Binder<Ty<'tcx>> {
|
||||
pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||
self.map_bound_ref(|fn_sig| fn_sig.output())
|
||||
}
|
||||
pub fn c_variadic(&self) -> bool {
|
||||
@ -1206,7 +1227,7 @@ impl<'tcx> PolyFnSig<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;
|
||||
pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<'tcx, FnSig<'tcx>>>;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable)]
|
||||
@ -1450,7 +1471,7 @@ pub struct ExistentialProjection<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
pub type PolyExistentialProjection<'tcx> = Binder<ExistentialProjection<'tcx>>;
|
||||
pub type PolyExistentialProjection<'tcx> = Binder<'tcx, ExistentialProjection<'tcx>>;
|
||||
|
||||
impl<'tcx> ExistentialProjection<'tcx> {
|
||||
/// Extracts the underlying existential trait reference from this projection.
|
||||
|
@ -448,7 +448,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: ty::Binder<T>) -> ty::Binder<T> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
self.binders_passed += 1;
|
||||
let t = t.super_fold_with(self);
|
||||
self.binders_passed -= 1;
|
||||
|
@ -499,10 +499,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self,
|
||||
closure_def_id: DefId,
|
||||
closure_substs: SubstsRef<'tcx>,
|
||||
) -> Option<ty::Binder<Ty<'tcx>>> {
|
||||
env_region: ty::RegionKind,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
let closure_ty = self.mk_closure(closure_def_id, closure_substs);
|
||||
let br = ty::BoundRegion { kind: ty::BrEnv };
|
||||
let env_region = ty::ReLateBound(ty::INNERMOST, br);
|
||||
let closure_kind_ty = closure_substs.as_closure().kind_ty();
|
||||
let closure_kind = closure_kind_ty.to_opt_closure_kind()?;
|
||||
let env_ty = match closure_kind {
|
||||
@ -510,7 +509,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
ty::ClosureKind::FnMut => self.mk_mut_ref(self.mk_region(env_region), closure_ty),
|
||||
ty::ClosureKind::FnOnce => closure_ty,
|
||||
};
|
||||
Some(ty::Binder::bind(env_ty))
|
||||
Some(env_ty)
|
||||
}
|
||||
|
||||
/// Returns `true` if the node pointed to by `def_id` is a `static` item.
|
||||
|
@ -502,7 +502,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// lifetimes without names with the value `'0`.
|
||||
match ty.kind() {
|
||||
ty::Ref(
|
||||
ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br })
|
||||
ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
||||
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
|
||||
_,
|
||||
_,
|
||||
@ -523,7 +523,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let region = match ty.kind() {
|
||||
ty::Ref(region, _, _) => {
|
||||
match region {
|
||||
ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br })
|
||||
ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br, .. })
|
||||
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
|
||||
printer.region_highlight_mode.highlighting_bound_region(*br, counter)
|
||||
}
|
||||
|
@ -2028,7 +2028,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
traits::ObligationCauseCode::RepeatVec(is_const_fn),
|
||||
),
|
||||
self.param_env,
|
||||
ty::Binder::bind(ty::TraitRef::new(
|
||||
ty::Binder::dummy(ty::TraitRef::new(
|
||||
self.tcx().require_lang_item(
|
||||
LangItem::Copy,
|
||||
Some(self.last_span),
|
||||
|
@ -589,31 +589,45 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
&self,
|
||||
indices: &UniversalRegionIndices<'tcx>,
|
||||
defining_ty: DefiningTy<'tcx>,
|
||||
) -> ty::Binder<&'tcx ty::List<Ty<'tcx>>> {
|
||||
) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> {
|
||||
let tcx = self.infcx.tcx;
|
||||
match defining_ty {
|
||||
DefiningTy::Closure(def_id, substs) => {
|
||||
assert_eq!(self.mir_def.did.to_def_id(), def_id);
|
||||
let closure_sig = substs.as_closure().sig();
|
||||
let inputs_and_output = closure_sig.inputs_and_output();
|
||||
let closure_ty = tcx.closure_env_ty(def_id, substs).unwrap();
|
||||
ty::Binder::fuse(closure_ty, inputs_and_output, |closure_ty, inputs_and_output| {
|
||||
// The "inputs" of the closure in the
|
||||
// signature appear as a tuple. The MIR side
|
||||
// flattens this tuple.
|
||||
let (&output, tuplized_inputs) = inputs_and_output.split_last().unwrap();
|
||||
assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs");
|
||||
let inputs = match tuplized_inputs[0].kind() {
|
||||
ty::Tuple(inputs) => inputs,
|
||||
_ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]),
|
||||
};
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(
|
||||
inputs_and_output
|
||||
.bound_vars()
|
||||
.iter()
|
||||
.chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))),
|
||||
);
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
|
||||
kind: ty::BrEnv,
|
||||
};
|
||||
let env_region = ty::ReLateBound(ty::INNERMOST, br);
|
||||
let closure_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap();
|
||||
|
||||
// The "inputs" of the closure in the
|
||||
// signature appear as a tuple. The MIR side
|
||||
// flattens this tuple.
|
||||
let (&output, tuplized_inputs) =
|
||||
inputs_and_output.skip_binder().split_last().unwrap();
|
||||
assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs");
|
||||
let inputs = match tuplized_inputs[0].kind() {
|
||||
ty::Tuple(inputs) => inputs,
|
||||
_ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]),
|
||||
};
|
||||
|
||||
ty::Binder::bind_with_vars(
|
||||
tcx.mk_type_list(
|
||||
iter::once(closure_ty)
|
||||
.chain(inputs.iter().map(|k| k.expect_ty()))
|
||||
.chain(iter::once(output)),
|
||||
)
|
||||
})
|
||||
),
|
||||
bound_vars,
|
||||
)
|
||||
}
|
||||
|
||||
DefiningTy::Generator(def_id, substs, movability) => {
|
||||
@ -657,7 +671,7 @@ trait InferCtxtExt<'tcx> {
|
||||
&self,
|
||||
origin: NllRegionVariableOrigin,
|
||||
all_outlive_scope: LocalDefId,
|
||||
value: ty::Binder<T>,
|
||||
value: ty::Binder<'tcx, T>,
|
||||
indices: &mut UniversalRegionIndices<'tcx>,
|
||||
) -> T
|
||||
where
|
||||
@ -686,7 +700,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
|
||||
&self,
|
||||
origin: NllRegionVariableOrigin,
|
||||
all_outlive_scope: LocalDefId,
|
||||
value: ty::Binder<T>,
|
||||
value: ty::Binder<'tcx, T>,
|
||||
indices: &mut UniversalRegionIndices<'tcx>,
|
||||
) -> T
|
||||
where
|
||||
|
@ -74,7 +74,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
|
||||
|
||||
fn print_dyn_existential(
|
||||
mut self,
|
||||
predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Result<Self::DynExistential, Self::Error> {
|
||||
let mut first = true;
|
||||
for p in predicates {
|
||||
|
@ -8,14 +8,14 @@ pub mod collector;
|
||||
pub mod partitioning;
|
||||
pub mod polymorphize;
|
||||
|
||||
pub fn custom_coerce_unsize_info<'tcx>(
|
||||
fn custom_coerce_unsize_info<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
source_ty: Ty<'tcx>,
|
||||
target_ty: Ty<'tcx>,
|
||||
) -> CustomCoerceUnsized {
|
||||
let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None);
|
||||
|
||||
let trait_ref = ty::Binder::bind(ty::TraitRef {
|
||||
let trait_ref = ty::Binder::dummy(ty::TraitRef {
|
||||
def_id,
|
||||
substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]),
|
||||
});
|
||||
|
@ -850,9 +850,12 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||
let obligation = Obligation::new(
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
Binder::bind(TraitPredicate {
|
||||
trait_ref: TraitRef::from_method(tcx, trait_id, substs),
|
||||
}),
|
||||
Binder::bind(
|
||||
TraitPredicate {
|
||||
trait_ref: TraitRef::from_method(tcx, trait_id, substs),
|
||||
},
|
||||
tcx,
|
||||
),
|
||||
);
|
||||
|
||||
let implsrc = tcx.infer_ctxt().enter(|infcx| {
|
||||
|
@ -252,8 +252,13 @@ fn liberated_closure_env_ty(
|
||||
_ => bug!("closure expr does not have closure type: {:?}", closure_ty),
|
||||
};
|
||||
|
||||
let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs).unwrap();
|
||||
tcx.erase_late_bound_regions(closure_env_ty)
|
||||
let bound_vars =
|
||||
tcx.mk_bound_variable_kinds(std::iter::once(ty::BoundVariableKind::Region(ty::BrEnv)));
|
||||
let br =
|
||||
ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BrEnv };
|
||||
let env_region = ty::ReLateBound(ty::INNERMOST, br);
|
||||
let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap();
|
||||
tcx.erase_late_bound_regions(ty::Binder::bind_with_vars(closure_env_ty, bound_vars))
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -230,7 +230,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
|
||||
|
||||
fn print_dyn_existential(
|
||||
mut self,
|
||||
predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Result<Self::DynExistential, Self::Error> {
|
||||
let mut first = true;
|
||||
for p in predicates {
|
||||
|
@ -181,7 +181,7 @@ impl SymbolMangler<'tcx> {
|
||||
|
||||
fn in_binder<T>(
|
||||
mut self,
|
||||
value: &ty::Binder<T>,
|
||||
value: &ty::Binder<'tcx, T>,
|
||||
print_value: impl FnOnce(Self, &T) -> Result<Self, !>,
|
||||
) -> Result<Self, !>
|
||||
where
|
||||
@ -318,7 +318,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
|
||||
// Late-bound lifetimes use indices starting at 1,
|
||||
// see `BinderLevel` for more details.
|
||||
ty::ReLateBound(debruijn, ty::BoundRegion { kind: ty::BrAnon(i) }) => {
|
||||
ty::ReLateBound(debruijn, ty::BoundRegion { kind: ty::BrAnon(i), .. }) => {
|
||||
let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
|
||||
let depth = binder.lifetime_depths.start + i;
|
||||
|
||||
@ -483,7 +483,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
|
||||
fn print_dyn_existential(
|
||||
mut self,
|
||||
predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Result<Self::DynExistential, Self::Error> {
|
||||
for predicate in predicates {
|
||||
self = self.in_binder(&predicate, |mut cx, predicate| {
|
||||
|
@ -697,7 +697,7 @@ where
|
||||
{
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &ty::Binder<T>,
|
||||
t: &ty::Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
t.as_ref().skip_binder().visit_with(self);
|
||||
ControlFlow::CONTINUE
|
||||
|
@ -84,7 +84,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
|
||||
let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) };
|
||||
|
||||
let trait_pred = ty::Binder::bind(trait_ref);
|
||||
let trait_pred = ty::Binder::dummy(trait_ref);
|
||||
|
||||
let bail_out = tcx.infer_ctxt().enter(|infcx| {
|
||||
let mut selcx = SelectionContext::with_negative(&infcx, true);
|
||||
@ -280,7 +280,7 @@ impl AutoTraitFinder<'tcx> {
|
||||
|
||||
let mut already_visited = FxHashSet::default();
|
||||
let mut predicates = VecDeque::new();
|
||||
predicates.push_back(ty::Binder::bind(ty::TraitPredicate {
|
||||
predicates.push_back(ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: trait_did,
|
||||
substs: infcx.tcx.mk_substs_trait(ty, &[]),
|
||||
|
@ -65,7 +65,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
points_at_arg: bool,
|
||||
);
|
||||
|
||||
@ -73,7 +73,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
points_at_arg: bool,
|
||||
has_custom_message: bool,
|
||||
) -> bool;
|
||||
@ -82,14 +82,14 @@ pub trait InferCtxtExt<'tcx> {
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
);
|
||||
|
||||
fn suggest_change_mut(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
points_at_arg: bool,
|
||||
);
|
||||
|
||||
@ -98,7 +98,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
span: Span,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
);
|
||||
|
||||
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span>;
|
||||
@ -108,7 +108,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
span: Span,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
) -> bool;
|
||||
|
||||
fn point_at_returns_when_relevant(
|
||||
@ -170,7 +170,7 @@ pub trait InferCtxtExt<'tcx> {
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
span: Span,
|
||||
);
|
||||
}
|
||||
@ -583,7 +583,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
points_at_arg: bool,
|
||||
) {
|
||||
let self_ty = match trait_ref.self_ty().no_bound_vars() {
|
||||
@ -676,7 +676,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: &ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
points_at_arg: bool,
|
||||
has_custom_message: bool,
|
||||
) -> bool {
|
||||
@ -761,7 +761,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
) {
|
||||
let span = obligation.cause.span;
|
||||
|
||||
@ -824,7 +824,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
points_at_arg: bool,
|
||||
) {
|
||||
let span = obligation.cause.span;
|
||||
@ -896,10 +896,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
span: Span,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
) {
|
||||
let is_empty_tuple =
|
||||
|ty: ty::Binder<Ty<'_>>| *ty.skip_binder().kind() == ty::Tuple(ty::List::empty());
|
||||
|ty: ty::Binder<'tcx, Ty<'_>>| *ty.skip_binder().kind() == ty::Tuple(ty::List::empty());
|
||||
|
||||
let hir = self.tcx.hir();
|
||||
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
||||
@ -948,7 +948,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
span: Span,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
) -> bool {
|
||||
match obligation.cause.code.peel_derives() {
|
||||
// Only suggest `impl Trait` if the return type is unsized because it is `dyn Trait`.
|
||||
@ -2190,7 +2190,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::Binder<ty::TraitRef<'tcx>>,
|
||||
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
|
||||
span: Span,
|
||||
) {
|
||||
debug!(
|
||||
|
@ -684,7 +684,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
||||
/// Returns the set of inference variables contained in `substs`.
|
||||
fn substs_infer_vars<'a, 'tcx>(
|
||||
selcx: &mut SelectionContext<'a, 'tcx>,
|
||||
substs: ty::Binder<SubstsRef<'tcx>>,
|
||||
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
|
||||
) -> impl Iterator<Item = TyOrConstInferVar<'tcx>> {
|
||||
selcx
|
||||
.infcx()
|
||||
|
@ -757,7 +757,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
||||
struct IllegalSelfTypeVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
supertraits: Option<Vec<ty::PolyTraitRef<'tcx>>>,
|
||||
supertraits: Option<Vec<DefId>>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for IllegalSelfTypeVisitor<'tcx> {
|
||||
@ -778,8 +778,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
||||
// Compute supertraits of current trait lazily.
|
||||
if self.supertraits.is_none() {
|
||||
let trait_ref =
|
||||
ty::Binder::bind(ty::TraitRef::identity(self.tcx, self.trait_def_id));
|
||||
self.supertraits = Some(traits::supertraits(self.tcx, trait_ref).collect());
|
||||
ty::Binder::dummy(ty::TraitRef::identity(self.tcx, self.trait_def_id));
|
||||
self.supertraits = Some(
|
||||
traits::supertraits(self.tcx, trait_ref).map(|t| t.def_id()).collect(),
|
||||
);
|
||||
}
|
||||
|
||||
// Determine whether the trait reference `Foo as
|
||||
@ -790,9 +792,11 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
|
||||
// direct equality here because all of these types
|
||||
// are part of the formal parameter listing, and
|
||||
// hence there should be no inference variables.
|
||||
let projection_trait_ref = ty::Binder::bind(data.trait_ref(self.tcx));
|
||||
let is_supertrait_of_current_trait =
|
||||
self.supertraits.as_ref().unwrap().contains(&projection_trait_ref);
|
||||
let is_supertrait_of_current_trait = self
|
||||
.supertraits
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.contains(&data.trait_ref(self.tcx).def_id);
|
||||
|
||||
if is_supertrait_of_current_trait {
|
||||
ControlFlow::CONTINUE // do not walk contained types, do not report error, do collect $200
|
||||
|
@ -1275,6 +1275,9 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
||||
let tcx = selcx.tcx();
|
||||
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
// We get here from `poly_project_and_unify_type` which replaces bound vars
|
||||
// with placeholders
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
|
||||
let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
|
||||
@ -1306,7 +1309,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
||||
ty: self_ty.ptr_metadata_ty(tcx),
|
||||
};
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate), false)
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate, tcx), false)
|
||||
}
|
||||
|
||||
fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
||||
|
@ -272,7 +272,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
nested: ty::Binder<Vec<Ty<'tcx>>>,
|
||||
nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
|
||||
) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
|
||||
debug!(?nested, "vtable_auto_impl");
|
||||
ensure_sufficient_stack(|| {
|
||||
@ -748,7 +748,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
cause,
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
ty::Binder::bind(outlives).to_predicate(tcx),
|
||||
obligation.predicate.rebind(outlives).to_predicate(tcx),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -204,7 +204,7 @@ struct EvaluatedCandidate<'tcx> {
|
||||
/// When does the builtin impl for `T: Trait` apply?
|
||||
enum BuiltinImplConditions<'tcx> {
|
||||
/// The impl is conditional on `T1, T2, ...: Trait`.
|
||||
Where(ty::Binder<Vec<Ty<'tcx>>>),
|
||||
Where(ty::Binder<'tcx, Vec<Ty<'tcx>>>),
|
||||
/// There is no built-in impl. There may be some other
|
||||
/// candidate (a where-clause or user-defined impl).
|
||||
None,
|
||||
@ -1673,7 +1673,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
/// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
|
||||
/// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
|
||||
/// ```
|
||||
fn constituent_types_for_ty(&self, t: ty::Binder<Ty<'tcx>>) -> ty::Binder<Vec<Ty<'tcx>>> {
|
||||
fn constituent_types_for_ty(
|
||||
&self,
|
||||
t: ty::Binder<'tcx, Ty<'tcx>>,
|
||||
) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
|
||||
match *t.skip_binder().kind() {
|
||||
ty::Uint(_)
|
||||
| ty::Int(_)
|
||||
@ -1746,7 +1749,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
cause: ObligationCause<'tcx>,
|
||||
recursion_depth: usize,
|
||||
trait_def_id: DefId,
|
||||
types: ty::Binder<Vec<Ty<'tcx>>>,
|
||||
types: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
|
||||
) -> Vec<PredicateObligation<'tcx>> {
|
||||
// Because the types were potentially derived from
|
||||
// higher-ranked obligations they may reference late-bound
|
||||
@ -1767,7 +1770,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
.skip_binder() // binder moved -\
|
||||
.iter()
|
||||
.flat_map(|ty| {
|
||||
let ty: ty::Binder<Ty<'tcx>> = types.rebind(ty); // <----/
|
||||
let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(ty); // <----/
|
||||
|
||||
self.infcx.commit_unconditionally(|_| {
|
||||
let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty);
|
||||
|
@ -328,7 +328,7 @@ pub fn closure_trait_ref_and_return_type(
|
||||
self_ty: Ty<'tcx>,
|
||||
sig: ty::PolyFnSig<'tcx>,
|
||||
tuple_arguments: TupleArgumentsFlag,
|
||||
) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>)> {
|
||||
) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> {
|
||||
let arguments_tuple = match tuple_arguments {
|
||||
TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
|
||||
TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
|
||||
@ -346,7 +346,7 @@ pub fn generator_trait_ref_and_outputs(
|
||||
fn_trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
sig: ty::PolyGenSig<'tcx>,
|
||||
) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
|
||||
) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: fn_trait_def_id,
|
||||
|
@ -704,7 +704,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
fn from_object_ty(
|
||||
&mut self,
|
||||
ty: Ty<'tcx>,
|
||||
data: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
data: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
region: ty::Region<'tcx>,
|
||||
) {
|
||||
// Imagine a type like this:
|
||||
@ -767,7 +767,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
/// `infer::required_region_bounds`, see that for more information.
|
||||
pub fn object_region_bounds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
existential_predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
existential_predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Vec<ty::Region<'tcx>> {
|
||||
// Since we don't actually *know* the self type for an object,
|
||||
// this "open(err)" serves as a kind of dummy standin -- basically
|
||||
|
@ -735,7 +735,10 @@ fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
|
||||
.into(),
|
||||
|
||||
ty::GenericParamDefKind::Lifetime => {
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(substs.len() as u32) };
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(substs.len()),
|
||||
kind: ty::BrAnon(substs.len() as u32),
|
||||
};
|
||||
tcx.mk_region(ty::RegionKind::ReLateBound(ty::INNERMOST, br)).into()
|
||||
}
|
||||
|
||||
|
@ -434,17 +434,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
|
||||
ReEarlyBound(_) => {
|
||||
panic!("Should have already been substituted.");
|
||||
}
|
||||
ReLateBound(db, br) => match br.kind {
|
||||
ty::BoundRegionKind::BrAnon(var) => {
|
||||
chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new(
|
||||
chalk_ir::DebruijnIndex::new(db.as_u32()),
|
||||
var as usize,
|
||||
))
|
||||
.intern(interner)
|
||||
}
|
||||
ty::BoundRegionKind::BrNamed(_def_id, _name) => unimplemented!(),
|
||||
ty::BrEnv => unimplemented!(),
|
||||
},
|
||||
ReLateBound(db, br) => chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new(
|
||||
chalk_ir::DebruijnIndex::new(db.as_u32()),
|
||||
br.var.as_usize(),
|
||||
))
|
||||
.intern(interner),
|
||||
ReFree(_) => unimplemented!(),
|
||||
ReStatic => chalk_ir::LifetimeData::Static.intern(interner),
|
||||
ReVar(_) => unimplemented!(),
|
||||
@ -467,7 +461,10 @@ impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime<RustInterner<'t
|
||||
let kind = match self.data(interner) {
|
||||
chalk_ir::LifetimeData::BoundVar(var) => ty::RegionKind::ReLateBound(
|
||||
ty::DebruijnIndex::from_u32(var.debruijn.depth()),
|
||||
ty::BoundRegion { kind: ty::BrAnon(var.index as u32) },
|
||||
ty::BoundRegion {
|
||||
var: ty::BoundVar::from_usize(var.index),
|
||||
kind: ty::BrAnon(var.index as u32),
|
||||
},
|
||||
),
|
||||
chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(),
|
||||
chalk_ir::LifetimeData::Placeholder(p) => {
|
||||
@ -606,7 +603,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
|
||||
}
|
||||
|
||||
impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<RustInterner<'tcx>>>>
|
||||
for &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>
|
||||
for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
|
||||
{
|
||||
fn lower_into(
|
||||
self,
|
||||
@ -677,7 +674,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LowerInto<'tcx, chalk_ir::FnSig<RustInterner<'tcx>>> for ty::Binder<ty::FnSig<'tcx>> {
|
||||
impl<'tcx> LowerInto<'tcx, chalk_ir::FnSig<RustInterner<'tcx>>>
|
||||
for ty::Binder<'tcx, ty::FnSig<'tcx>>
|
||||
{
|
||||
fn lower_into(self, _interner: &RustInterner<'_>) -> FnSig<RustInterner<'tcx>> {
|
||||
chalk_ir::FnSig {
|
||||
abi: self.abi(),
|
||||
@ -801,7 +800,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>
|
||||
crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
|
||||
interner: &RustInterner<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ty: Binder<T>,
|
||||
ty: Binder<'tcx, T>,
|
||||
) -> (T, chalk_ir::VariableKinds<RustInterner<'tcx>>, BTreeMap<DefId, u32>) {
|
||||
let mut bound_vars_collector = BoundVarsCollector::new();
|
||||
ty.as_ref().skip_binder().visit_with(&mut bound_vars_collector);
|
||||
@ -849,7 +848,10 @@ impl<'tcx> BoundVarsCollector<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> ControlFlow<Self::BreakTy> {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.binder_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
@ -895,7 +897,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
|
||||
},
|
||||
},
|
||||
|
||||
ty::BrEnv => unimplemented!(),
|
||||
ty::BoundRegionKind::BrEnv => unimplemented!(),
|
||||
},
|
||||
|
||||
ty::ReEarlyBound(_re) => {
|
||||
@ -931,7 +933,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<T>) -> Binder<T> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
|
||||
self.binder_index.shift_in(1);
|
||||
let result = t.super_fold_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
@ -943,7 +945,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
|
||||
ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind {
|
||||
ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) {
|
||||
Some(idx) => {
|
||||
let new_br = ty::BoundRegion { kind: ty::BrAnon(*idx) };
|
||||
let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx) };
|
||||
return self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br));
|
||||
}
|
||||
None => panic!("Missing `BrNamed`."),
|
||||
@ -987,7 +989,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<T>) -> Binder<T> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
|
||||
self.binder_index.shift_in(1);
|
||||
let result = t.super_fold_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
@ -1026,12 +1028,16 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
||||
// This covers any region variables in a goal, right?
|
||||
ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) {
|
||||
Some(idx) => {
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(*idx) };
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(*idx),
|
||||
kind: ty::BrAnon(*idx),
|
||||
};
|
||||
self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))
|
||||
}
|
||||
None => {
|
||||
let idx = self.named_regions.len() as u32;
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(idx) };
|
||||
let br =
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(idx), kind: ty::BrAnon(idx) };
|
||||
self.named_regions.insert(_re.def_id, idx);
|
||||
self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ fn resolve_associated_item<'tcx>(
|
||||
);
|
||||
|
||||
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
|
||||
let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)))?;
|
||||
let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref, tcx)))?;
|
||||
|
||||
// Now that we know which impl is being used, we can dispatch to
|
||||
// the actual function:
|
||||
|
@ -166,7 +166,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
parent_substs: &[subst::GenericArg<'tcx>],
|
||||
has_self: bool,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
arg_count: GenericArgCountResult,
|
||||
arg_count: &GenericArgCountResult,
|
||||
ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
// Collect the segments of the path; we need to substitute arguments
|
||||
|
@ -210,14 +210,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let r = match tcx.named_region(lifetime.hir_id) {
|
||||
Some(rl::Region::Static) => tcx.lifetimes.re_static,
|
||||
|
||||
Some(rl::Region::LateBound(debruijn, id, _)) => {
|
||||
let name = lifetime_name(id.expect_local());
|
||||
let br = ty::BoundRegion { kind: ty::BrNamed(id, name) };
|
||||
Some(rl::Region::LateBound(debruijn, index, def_id, _)) => {
|
||||
let name = lifetime_name(def_id.expect_local());
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(index),
|
||||
kind: ty::BrNamed(def_id, name),
|
||||
};
|
||||
tcx.mk_region(ty::ReLateBound(debruijn, br))
|
||||
}
|
||||
|
||||
Some(rl::Region::LateBoundAnon(debruijn, index)) => {
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(index) };
|
||||
Some(rl::Region::LateBoundAnon(debruijn, index, anon_index)) => {
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(index),
|
||||
kind: ty::BrAnon(anon_index),
|
||||
};
|
||||
tcx.mk_region(ty::ReLateBound(debruijn, br))
|
||||
}
|
||||
|
||||
@ -266,7 +272,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
def_id: DefId,
|
||||
item_segment: &hir::PathSegment<'_>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
let (substs, assoc_bindings, _) = self.create_substs_for_ast_path(
|
||||
let (substs, _) = self.create_substs_for_ast_path(
|
||||
span,
|
||||
def_id,
|
||||
&[],
|
||||
@ -275,6 +281,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
item_segment.infer_args,
|
||||
None,
|
||||
);
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args());
|
||||
|
||||
if let Some(b) = assoc_bindings.first() {
|
||||
Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
|
||||
@ -314,6 +321,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated
|
||||
/// type itself: `['a]`. The returned `SubstsRef` concatenates these two
|
||||
/// lists: `[Vec<u8>, u8, 'a]`.
|
||||
#[tracing::instrument(level = "debug", skip(self, span))]
|
||||
fn create_substs_for_ast_path<'a>(
|
||||
&self,
|
||||
span: Span,
|
||||
@ -323,15 +331,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
generic_args: &'a hir::GenericArgs<'_>,
|
||||
infer_args: bool,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, GenericArgCountResult) {
|
||||
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
|
||||
// If the type is parameterized by this region, then replace this
|
||||
// region with the current anon region binding (in other words,
|
||||
// whatever & would get replaced with).
|
||||
debug!(
|
||||
"create_substs_for_ast_path(def_id={:?}, self_ty={:?}, \
|
||||
generic_args={:?})",
|
||||
def_id, self_ty, generic_args
|
||||
);
|
||||
|
||||
let tcx = self.tcx();
|
||||
let generics = tcx.generics_of(def_id);
|
||||
@ -367,7 +370,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// here and so associated type bindings will be handled regardless of whether there are any
|
||||
// non-`Self` generic parameters.
|
||||
if generics.params.len() == 0 {
|
||||
return (tcx.intern_substs(&[]), vec![], arg_count);
|
||||
return (tcx.intern_substs(&[]), arg_count);
|
||||
}
|
||||
|
||||
let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self);
|
||||
@ -540,7 +543,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
parent_substs,
|
||||
self_ty.is_some(),
|
||||
self_ty,
|
||||
arg_count.clone(),
|
||||
&arg_count,
|
||||
&mut substs_ctx,
|
||||
);
|
||||
|
||||
@ -551,6 +554,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
generic_args.args.is_empty(),
|
||||
);
|
||||
|
||||
debug!(
|
||||
"create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}",
|
||||
generics, self_ty, substs
|
||||
);
|
||||
|
||||
(substs, arg_count)
|
||||
}
|
||||
|
||||
fn create_assoc_bindings_for_generic_args<'a>(
|
||||
&self,
|
||||
generic_args: &'a hir::GenericArgs<'_>,
|
||||
) -> Vec<ConvertedBinding<'a, 'tcx>> {
|
||||
// Convert associated-type bindings or constraints into a separate vector.
|
||||
// Example: Given this:
|
||||
//
|
||||
@ -581,12 +596,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
})
|
||||
.collect();
|
||||
|
||||
debug!(
|
||||
"create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}",
|
||||
generics, self_ty, substs
|
||||
);
|
||||
|
||||
(substs, assoc_bindings, arg_count)
|
||||
assoc_bindings
|
||||
}
|
||||
|
||||
crate fn create_substs_for_associated_item(
|
||||
@ -636,55 +646,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
)
|
||||
}
|
||||
|
||||
/// The given trait-ref must actually be a trait.
|
||||
pub(super) fn instantiate_poly_trait_ref_inner(
|
||||
&self,
|
||||
trait_ref: &hir::TraitRef<'_>,
|
||||
span: Span,
|
||||
constness: Constness,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
speculative: bool,
|
||||
) -> GenericArgCountResult {
|
||||
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
||||
|
||||
debug!("instantiate_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
|
||||
|
||||
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
|
||||
|
||||
let (substs, assoc_bindings, arg_count) = self.create_substs_for_ast_trait_ref(
|
||||
trait_ref.path.span,
|
||||
trait_def_id,
|
||||
self_ty,
|
||||
trait_ref.path.segments.last().unwrap(),
|
||||
);
|
||||
let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs));
|
||||
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, constness));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
for binding in &assoc_bindings {
|
||||
// Specify type to assert that error was already reported in `Err` case.
|
||||
let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding(
|
||||
trait_ref.hir_ref_id,
|
||||
poly_trait_ref,
|
||||
binding,
|
||||
bounds,
|
||||
speculative,
|
||||
&mut dup_bindings,
|
||||
binding.span,
|
||||
);
|
||||
// Okay to ignore `Err` because of `ErrorReported` (see above).
|
||||
}
|
||||
|
||||
debug!(
|
||||
"instantiate_poly_trait_ref({:?}, bounds={:?}) -> {:?}",
|
||||
trait_ref, bounds, poly_trait_ref
|
||||
);
|
||||
|
||||
arg_count
|
||||
}
|
||||
|
||||
/// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
|
||||
/// a full trait reference. The resulting trait reference is returned. This may also generate
|
||||
/// auxiliary bounds, which are added to `bounds`.
|
||||
@ -704,21 +665,55 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
|
||||
/// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
|
||||
/// however.
|
||||
#[tracing::instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
|
||||
pub fn instantiate_poly_trait_ref(
|
||||
&self,
|
||||
poly_trait_ref: &hir::PolyTraitRef<'_>,
|
||||
trait_ref: &hir::TraitRef<'_>,
|
||||
span: Span,
|
||||
constness: Constness,
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
speculative: bool,
|
||||
) -> GenericArgCountResult {
|
||||
self.instantiate_poly_trait_ref_inner(
|
||||
&poly_trait_ref.trait_ref,
|
||||
poly_trait_ref.span,
|
||||
constness,
|
||||
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
||||
|
||||
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
|
||||
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
|
||||
debug!(?bound_vars);
|
||||
|
||||
let (substs, arg_count) = self.create_substs_for_ast_trait_ref(
|
||||
trait_ref.path.span,
|
||||
trait_def_id,
|
||||
self_ty,
|
||||
bounds,
|
||||
false,
|
||||
)
|
||||
trait_ref.path.segments.last().unwrap(),
|
||||
);
|
||||
let assoc_bindings = self
|
||||
.create_assoc_bindings_for_generic_args(trait_ref.path.segments.last().unwrap().args());
|
||||
|
||||
let poly_trait_ref =
|
||||
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
||||
|
||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, constness));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
for binding in &assoc_bindings {
|
||||
// Specify type to assert that error was already reported in `Err` case.
|
||||
let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding(
|
||||
trait_ref.hir_ref_id,
|
||||
poly_trait_ref,
|
||||
binding,
|
||||
bounds,
|
||||
speculative,
|
||||
&mut dup_bindings,
|
||||
binding.span,
|
||||
);
|
||||
// Okay to ignore `Err` because of `ErrorReported` (see above).
|
||||
}
|
||||
|
||||
arg_count
|
||||
}
|
||||
|
||||
pub fn instantiate_lang_item_trait_ref(
|
||||
@ -732,7 +727,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
) {
|
||||
let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
|
||||
|
||||
let (substs, assoc_bindings, _) = self.create_substs_for_ast_path(
|
||||
let (substs, _) = self.create_substs_for_ast_path(
|
||||
span,
|
||||
trait_def_id,
|
||||
&[],
|
||||
@ -741,7 +736,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
false,
|
||||
Some(self_ty),
|
||||
);
|
||||
let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs));
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
let poly_trait_ref =
|
||||
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, Constness::NotConst));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
@ -765,23 +764,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_segment: &hir::PathSegment<'_>,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
let (substs, assoc_bindings, _) =
|
||||
let (substs, _) =
|
||||
self.create_substs_for_ast_trait_ref(span, trait_def_id, self_ty, trait_segment);
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(trait_segment.args());
|
||||
if let Some(b) = assoc_bindings.first() {
|
||||
Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
|
||||
}
|
||||
ty::TraitRef::new(trait_def_id, substs)
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self, span))]
|
||||
fn create_substs_for_ast_trait_ref<'a>(
|
||||
&self,
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
trait_segment: &'a hir::PathSegment<'a>,
|
||||
) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, GenericArgCountResult) {
|
||||
debug!("create_substs_for_ast_trait_ref(trait_segment={:?})", trait_segment);
|
||||
|
||||
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
|
||||
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment);
|
||||
|
||||
self.create_substs_for_ast_path(
|
||||
@ -803,7 +802,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
|
||||
// Returns `true` if a bounds list includes `?Sized`.
|
||||
pub fn is_unsized(&self, ast_bounds: &[&hir::GenericBound<'_>], span: Span) -> bool {
|
||||
pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound<'_>], span: Span) -> bool {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// Try to find an unbound in bounds.
|
||||
@ -858,29 +857,46 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// **A note on binders:** there is an implied binder around
|
||||
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
|
||||
/// for more details.
|
||||
#[tracing::instrument(level = "debug", skip(self, bounds))]
|
||||
fn add_bounds(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[&hir::GenericBound<'_>],
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||
) {
|
||||
let constness = self.default_constness_for_trait_bounds();
|
||||
for ast_bound in ast_bounds {
|
||||
match *ast_bound {
|
||||
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => {
|
||||
self.instantiate_poly_trait_ref(b, constness, param_ty, bounds);
|
||||
self.instantiate_poly_trait_ref(
|
||||
&b.trait_ref,
|
||||
b.span,
|
||||
constness,
|
||||
param_ty,
|
||||
bounds,
|
||||
false,
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::MaybeConst) => {
|
||||
self.instantiate_poly_trait_ref(b, Constness::NotConst, param_ty, bounds);
|
||||
self.instantiate_poly_trait_ref(
|
||||
&b.trait_ref,
|
||||
b.span,
|
||||
Constness::NotConst,
|
||||
param_ty,
|
||||
bounds,
|
||||
false,
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
|
||||
hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self
|
||||
.instantiate_lang_item_trait_ref(
|
||||
*lang_item, *span, *hir_id, args, param_ty, bounds,
|
||||
lang_item, span, hir_id, args, param_ty, bounds,
|
||||
),
|
||||
hir::GenericBound::Outlives(ref l) => bounds
|
||||
.region_bounds
|
||||
.push((ty::Binder::bind(self.ast_region_to_region(l, None)), l.span)),
|
||||
hir::GenericBound::Outlives(ref l) => bounds.region_bounds.push((
|
||||
ty::Binder::bind_with_vars(self.ast_region_to_region(l, None), bound_vars),
|
||||
l.span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -908,7 +924,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
sized_by_default: SizedByDefault,
|
||||
span: Span,
|
||||
) -> Bounds<'tcx> {
|
||||
let ast_bounds: Vec<_> = ast_bounds.iter().collect();
|
||||
self.compute_bounds_inner(param_ty, &ast_bounds, sized_by_default, span)
|
||||
}
|
||||
|
||||
@ -928,7 +943,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
if let Some(trait_ref) = ast_bound.trait_ref() {
|
||||
if let Some(trait_did) = trait_ref.trait_def_id() {
|
||||
if self.tcx().trait_may_define_assoc_type(trait_did, assoc_name) {
|
||||
result.push(ast_bound);
|
||||
result.push(ast_bound.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -940,13 +955,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
fn compute_bounds_inner(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[&hir::GenericBound<'_>],
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
sized_by_default: SizedByDefault,
|
||||
span: Span,
|
||||
) -> Bounds<'tcx> {
|
||||
let mut bounds = Bounds::default();
|
||||
|
||||
self.add_bounds(param_ty, ast_bounds, &mut bounds);
|
||||
self.add_bounds(param_ty, ast_bounds, &mut bounds, ty::List::empty());
|
||||
|
||||
bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
|
||||
if !self.is_unsized(ast_bounds, span) { Some(span) } else { None }
|
||||
@ -963,6 +978,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
|
||||
/// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
|
||||
/// the binder (e.g., `&'a u32`) and hence may reference bound regions.
|
||||
#[tracing::instrument(
|
||||
level = "debug",
|
||||
skip(self, bounds, speculative, dup_bindings, path_span)
|
||||
)]
|
||||
fn add_predicates_for_ast_type_binding(
|
||||
&self,
|
||||
hir_ref_id: hir::HirId,
|
||||
@ -989,7 +1008,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
//
|
||||
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
|
||||
|
||||
debug!(?hir_ref_id, ?trait_ref, ?binding, ?bounds, "add_predicates_for_ast_type_binding",);
|
||||
let tcx = self.tcx();
|
||||
|
||||
let candidate =
|
||||
@ -1090,7 +1108,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
let late_bound_in_trait_ref =
|
||||
tcx.collect_constrained_late_bound_regions(&projection_ty);
|
||||
let late_bound_in_ty =
|
||||
tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty));
|
||||
tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty));
|
||||
debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
|
||||
debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
|
||||
|
||||
@ -1139,10 +1157,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
//
|
||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||
// parameter to have a skipped binder.
|
||||
let param_ty =
|
||||
tcx.mk_projection(assoc_ty.def_id, projection_ty.skip_binder().substs);
|
||||
let ast_bounds: Vec<_> = ast_bounds.iter().collect();
|
||||
self.add_bounds(param_ty, &ast_bounds, bounds);
|
||||
let param_ty = tcx.mk_ty(ty::Projection(projection_ty.skip_binder()));
|
||||
self.add_bounds(param_ty, ast_bounds, bounds, candidate.bound_vars());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -1176,10 +1192,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
|
||||
..
|
||||
} = self.instantiate_poly_trait_ref(
|
||||
trait_bound,
|
||||
&trait_bound.trait_ref,
|
||||
trait_bound.span,
|
||||
Constness::NotConst,
|
||||
dummy_self,
|
||||
&mut bounds,
|
||||
false,
|
||||
) {
|
||||
potential_assoc_types.extend(cur_potential_assoc_types);
|
||||
}
|
||||
@ -1664,7 +1682,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
};
|
||||
|
||||
self.one_bound_for_assoc_type(
|
||||
|| traits::supertraits(tcx, ty::Binder::bind(trait_ref)),
|
||||
|| traits::supertraits(tcx, ty::Binder::bind(trait_ref, tcx)),
|
||||
|| "Self".to_string(),
|
||||
assoc_ident,
|
||||
span,
|
||||
@ -2199,6 +2217,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
|
||||
|
||||
tcx.mk_fn_ptr(self.ty_of_fn(
|
||||
ast_ty.hir_id,
|
||||
bf.unsafety,
|
||||
bf.abi,
|
||||
&bf.decl,
|
||||
@ -2241,7 +2260,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
hir::TyKind::Path(hir::QPath::LangItem(lang_item, span)) => {
|
||||
let def_id = tcx.require_lang_item(lang_item, Some(span));
|
||||
let (substs, _, _) = self.create_substs_for_ast_path(
|
||||
let (substs, _) = self.create_substs_for_ast_path(
|
||||
span,
|
||||
def_id,
|
||||
&[],
|
||||
@ -2278,7 +2297,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
result_ty
|
||||
}
|
||||
|
||||
pub fn impl_trait_ty_to_ty(
|
||||
fn impl_trait_ty_to_ty(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
lifetimes: &[hir::GenericArg<'_>],
|
||||
@ -2339,6 +2358,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
pub fn ty_of_fn(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
unsafety: hir::Unsafety,
|
||||
abi: abi::Abi,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
@ -2349,6 +2369,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
debug!("ty_of_fn");
|
||||
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
debug!(?bound_vars);
|
||||
|
||||
// We proactively collect all the inferred type params to emit a single error per fn def.
|
||||
let mut visitor = PlaceholderHirTyCollector::default();
|
||||
@ -2368,8 +2390,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
debug!("ty_of_fn: output_ty={:?}", output_ty);
|
||||
|
||||
let bare_fn_ty =
|
||||
ty::Binder::bind(tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi));
|
||||
let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi);
|
||||
let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
|
||||
|
||||
if !self.allow_ty_infer() {
|
||||
// We always collect the spans for placeholder types when evaluating `fn`s, but we
|
||||
@ -2450,7 +2472,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
fn compute_object_lifetime_bound(
|
||||
&self,
|
||||
span: Span,
|
||||
existential_predicates: &'tcx ty::List<ty::Binder<ty::ExistentialPredicate<'tcx>>>,
|
||||
existential_predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
|
||||
) -> Option<ty::Region<'tcx>> // if None, use the default
|
||||
{
|
||||
let tcx = self.tcx();
|
||||
|
@ -26,7 +26,7 @@ pub struct Bounds<'tcx> {
|
||||
/// A list of region bounds on the (implicit) self type. So if you
|
||||
/// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but
|
||||
/// the `T` is not explicitly included).
|
||||
pub region_bounds: Vec<(ty::Binder<ty::Region<'tcx>>, Span)>,
|
||||
pub region_bounds: Vec<(ty::Binder<'tcx, ty::Region<'tcx>>, Span)>,
|
||||
|
||||
/// A list of trait bounds. So if you had `T: Debug` this would be
|
||||
/// `T: Debug`. Note that the self-type is explicit here.
|
||||
@ -57,7 +57,7 @@ impl<'tcx> Bounds<'tcx> {
|
||||
// If it could be sized, and is, add the `Sized` predicate.
|
||||
let sized_predicate = self.implicitly_sized.and_then(|span| {
|
||||
tcx.lang_items().sized_trait().map(|sized| {
|
||||
let trait_ref = ty::Binder::bind(ty::TraitRef {
|
||||
let trait_ref = ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: sized,
|
||||
substs: tcx.mk_substs_trait(param_ty, &[]),
|
||||
});
|
||||
|
@ -69,7 +69,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let expr_def_id = self.tcx.hir().local_def_id(expr.hir_id);
|
||||
|
||||
let ClosureSignatures { bound_sig, liberated_sig } =
|
||||
self.sig_of_closure(expr_def_id.to_def_id(), decl, body, expected_sig);
|
||||
self.sig_of_closure(expr.hir_id, expr_def_id.to_def_id(), decl, body, expected_sig);
|
||||
|
||||
debug!("check_closure: ty_of_closure returns {:?}", liberated_sig);
|
||||
|
||||
@ -288,15 +288,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
fn sig_of_closure(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
expected_sig: Option<ExpectedSig<'tcx>>,
|
||||
) -> ClosureSignatures<'tcx> {
|
||||
if let Some(e) = expected_sig {
|
||||
self.sig_of_closure_with_expectation(expr_def_id, decl, body, e)
|
||||
self.sig_of_closure_with_expectation(hir_id, expr_def_id, decl, body, e)
|
||||
} else {
|
||||
self.sig_of_closure_no_expectation(expr_def_id, decl, body)
|
||||
self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body)
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,13 +305,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// types that the user gave into a signature.
|
||||
fn sig_of_closure_no_expectation(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
) -> ClosureSignatures<'tcx> {
|
||||
debug!("sig_of_closure_no_expectation()");
|
||||
|
||||
let bound_sig = self.supplied_sig_of_closure(expr_def_id, decl, body);
|
||||
let bound_sig = self.supplied_sig_of_closure(hir_id, expr_def_id, decl, body);
|
||||
|
||||
self.closure_sigs(expr_def_id, body, bound_sig)
|
||||
}
|
||||
@ -364,6 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// regions with depth 1, which are bound then by the closure.
|
||||
fn sig_of_closure_with_expectation(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
@ -375,7 +378,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// expectation if things don't see to match up with what we
|
||||
// expect.
|
||||
if expected_sig.sig.c_variadic() != decl.c_variadic {
|
||||
return self.sig_of_closure_no_expectation(expr_def_id, decl, body);
|
||||
return self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body);
|
||||
} else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 {
|
||||
return self.sig_of_closure_with_mismatched_number_of_arguments(
|
||||
expr_def_id,
|
||||
@ -411,9 +414,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Along the way, it also writes out entries for types that the user
|
||||
// wrote into our typeck results, which are then later used by the privacy
|
||||
// check.
|
||||
match self.check_supplied_sig_against_expectation(expr_def_id, decl, body, &closure_sigs) {
|
||||
match self.check_supplied_sig_against_expectation(
|
||||
hir_id,
|
||||
expr_def_id,
|
||||
decl,
|
||||
body,
|
||||
&closure_sigs,
|
||||
) {
|
||||
Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok),
|
||||
Err(_) => return self.sig_of_closure_no_expectation(expr_def_id, decl, body),
|
||||
Err(_) => return self.sig_of_closure_no_expectation(hir_id, expr_def_id, decl, body),
|
||||
}
|
||||
|
||||
closure_sigs
|
||||
@ -460,6 +469,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// strategy.
|
||||
fn check_supplied_sig_against_expectation(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
@ -469,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
//
|
||||
// (See comment on `sig_of_closure_with_expectation` for the
|
||||
// meaning of these letters.)
|
||||
let supplied_sig = self.supplied_sig_of_closure(expr_def_id, decl, body);
|
||||
let supplied_sig = self.supplied_sig_of_closure(hir_id, expr_def_id, decl, body);
|
||||
|
||||
debug!("check_supplied_sig_against_expectation: supplied_sig={:?}", supplied_sig);
|
||||
|
||||
@ -534,6 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// Also, record this closure signature for later.
|
||||
fn supplied_sig_of_closure(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
expr_def_id: DefId,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
body: &hir::Body<'_>,
|
||||
@ -545,6 +556,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
decl, body.generator_kind,
|
||||
);
|
||||
|
||||
let bound_vars = self.tcx.late_bound_vars(hir_id);
|
||||
|
||||
// First, convert the types that the user supplied (if any).
|
||||
let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a));
|
||||
let supplied_return = match decl.output {
|
||||
@ -571,13 +584,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
},
|
||||
};
|
||||
|
||||
let result = ty::Binder::bind(self.tcx.mk_fn_sig(
|
||||
supplied_arguments,
|
||||
supplied_return,
|
||||
decl.c_variadic,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::RustCall,
|
||||
));
|
||||
let result = ty::Binder::bind_with_vars(
|
||||
self.tcx.mk_fn_sig(
|
||||
supplied_arguments,
|
||||
supplied_return,
|
||||
decl.c_variadic,
|
||||
hir::Unsafety::Normal,
|
||||
Abi::RustCall,
|
||||
),
|
||||
bound_vars,
|
||||
);
|
||||
|
||||
debug!("supplied_sig_of_closure: result={:?}", result);
|
||||
|
||||
|
@ -1487,7 +1487,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
if let (Some((expr, _)), Some((fn_decl, _, _))) =
|
||||
(expression, fcx.get_node_fn_decl(parent_item))
|
||||
{
|
||||
fcx.suggest_missing_return_expr(&mut err, expr, fn_decl, expected, found);
|
||||
fcx.suggest_missing_return_expr(&mut err, expr, fn_decl, expected, found, parent_id);
|
||||
}
|
||||
|
||||
if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) {
|
||||
|
@ -225,7 +225,7 @@ fn compare_predicate_entailment<'tcx>(
|
||||
let (impl_m_own_bounds, _) = infcx.replace_bound_vars_with_fresh_vars(
|
||||
impl_m_span,
|
||||
infer::HigherRankedType,
|
||||
ty::Binder::bind(impl_m_own_bounds.predicates),
|
||||
ty::Binder::bind(impl_m_own_bounds.predicates, tcx),
|
||||
);
|
||||
for predicate in impl_m_own_bounds {
|
||||
let traits::Normalized { value: predicate, obligations } =
|
||||
@ -258,14 +258,14 @@ fn compare_predicate_entailment<'tcx>(
|
||||
);
|
||||
let impl_sig =
|
||||
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, impl_sig);
|
||||
let impl_fty = tcx.mk_fn_ptr(ty::Binder::bind(impl_sig));
|
||||
let impl_fty = tcx.mk_fn_ptr(ty::Binder::bind(impl_sig, tcx));
|
||||
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
|
||||
|
||||
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(trait_m.def_id));
|
||||
let trait_sig = trait_sig.subst(tcx, trait_to_placeholder_substs);
|
||||
let trait_sig =
|
||||
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, trait_sig);
|
||||
let trait_fty = tcx.mk_fn_ptr(ty::Binder::bind(trait_sig));
|
||||
let trait_fty = tcx.mk_fn_ptr(ty::Binder::bind(trait_sig, tcx));
|
||||
|
||||
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
|
||||
|
||||
|
@ -354,9 +354,9 @@ impl TypeRelation<'tcx> for SimpleEqRelation<'tcx> {
|
||||
|
||||
fn binders<T>(
|
||||
&mut self,
|
||||
a: ty::Binder<T>,
|
||||
b: ty::Binder<T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<T>>
|
||||
a: ty::Binder<'tcx, T>,
|
||||
b: ty::Binder<'tcx, T>,
|
||||
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
|
||||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
|
@ -1462,7 +1462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&[][..],
|
||||
has_self,
|
||||
self_ty,
|
||||
arg_count,
|
||||
&arg_count,
|
||||
&mut CreateCtorSubstsContext {
|
||||
fcx: self,
|
||||
span,
|
||||
|
@ -55,7 +55,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
|
||||
pointing_at_return_type =
|
||||
self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
|
||||
self.suggest_missing_return_expr(err, expr, &fn_decl, expected, found);
|
||||
let fn_id = self.tcx.hir().get_return_block(blk_id).unwrap();
|
||||
self.suggest_missing_return_expr(err, expr, &fn_decl, expected, found, fn_id);
|
||||
}
|
||||
pointing_at_return_type
|
||||
}
|
||||
@ -479,6 +480,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
fn_decl: &hir::FnDecl<'_>,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
id: hir::HirId,
|
||||
) {
|
||||
if !expected.is_unit() {
|
||||
return;
|
||||
@ -486,7 +488,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let found = self.resolve_vars_with_obligations(found);
|
||||
if let hir::FnRetTy::Return(ty) = fn_decl.output {
|
||||
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty);
|
||||
let ty = self.tcx.erase_late_bound_regions(Binder::bind(ty));
|
||||
let bound_vars = self.tcx.late_bound_vars(id);
|
||||
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
|
||||
let ty = self.normalize_associated_types_in(expr.span, ty);
|
||||
if self.can_coerce(found, ty) {
|
||||
err.multipart_suggestion(
|
||||
|
@ -186,7 +186,10 @@ pub fn resolve_interior<'a, 'tcx>(
|
||||
// which means that none of the regions inside relate to any other, even if
|
||||
// typeck had previously found constraints that would cause them to be related.
|
||||
let folded = fcx.tcx.fold_regions(erased, &mut false, |_, current_depth| {
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(counter) };
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(counter),
|
||||
kind: ty::BrAnon(counter),
|
||||
};
|
||||
let r = fcx.tcx.mk_region(ty::ReLateBound(current_depth, br));
|
||||
counter += 1;
|
||||
r
|
||||
@ -202,11 +205,15 @@ pub fn resolve_interior<'a, 'tcx>(
|
||||
|
||||
// Extract type components to build the witness type.
|
||||
let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty));
|
||||
let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list));
|
||||
let bound_vars = fcx.tcx.mk_bound_variable_kinds(
|
||||
(0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i))),
|
||||
);
|
||||
let witness =
|
||||
fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone()));
|
||||
|
||||
// Store the generator types and spans into the typeck results for this generator.
|
||||
visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types =
|
||||
ty::Binder::bind(type_causes);
|
||||
ty::Binder::bind_with_vars(type_causes, bound_vars);
|
||||
|
||||
debug!(
|
||||
"types in generator after region replacement {:?}, span = {:?}",
|
||||
|
@ -101,12 +101,21 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||
let intrinsic_name = tcx.item_name(it.def_id.to_def_id());
|
||||
let name_str = intrinsic_name.as_str();
|
||||
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(
|
||||
[ty::BoundVariableKind::Region(ty::BrAnon(0)), ty::BoundVariableKind::Region(ty::BrEnv)]
|
||||
.iter()
|
||||
.copied(),
|
||||
);
|
||||
let mk_va_list_ty = |mutbl| {
|
||||
tcx.lang_items().va_list().map(|did| {
|
||||
let region = tcx
|
||||
.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrAnon(0) }));
|
||||
let env_region =
|
||||
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { kind: ty::BrEnv }));
|
||||
let region = tcx.mk_region(ty::ReLateBound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) },
|
||||
));
|
||||
let env_region = tcx.mk_region(ty::ReLateBound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrEnv },
|
||||
));
|
||||
let va_list_ty = tcx.type_of(did).subst(tcx, &[region.into()]);
|
||||
(tcx.mk_ref(env_region, ty::TypeAndMut { ty: va_list_ty, mutbl }), va_list_ty)
|
||||
})
|
||||
@ -305,7 +314,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||
tcx.associated_items(tcx.lang_items().discriminant_kind_trait().unwrap());
|
||||
let discriminant_def_id = assoc_items.in_definition_order().next().unwrap().def_id;
|
||||
|
||||
let br = ty::BoundRegion { kind: ty::BrAnon(0) };
|
||||
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(0) };
|
||||
(
|
||||
1,
|
||||
vec![
|
||||
@ -366,7 +375,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||
(n_tps, inputs, output, unsafety)
|
||||
};
|
||||
let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic);
|
||||
let sig = ty::Binder::bind(sig);
|
||||
let sig = ty::Binder::bind_with_vars(sig, bound_vars);
|
||||
equate_intrinsic_type(tcx, it, n_tps, sig)
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
// We won't add these if we encountered an illegal sized bound, so that we can use
|
||||
// a custom error in that case.
|
||||
if illegal_sized_bound.is_none() {
|
||||
let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig));
|
||||
let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig, self.tcx));
|
||||
self.add_obligations(method_ty, all_substs, method_predicates);
|
||||
}
|
||||
|
||||
@ -381,7 +381,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
parent_substs,
|
||||
false,
|
||||
None,
|
||||
arg_count_correct,
|
||||
&arg_count_correct,
|
||||
&mut MethodSubstsCtxt { cfcx: self, pick, seg },
|
||||
)
|
||||
}
|
||||
@ -550,7 +550,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
upcast_trait_refs.into_iter().next().unwrap()
|
||||
}
|
||||
|
||||
fn replace_bound_vars_with_fresh_vars<T>(&self, value: ty::Binder<T>) -> T
|
||||
fn replace_bound_vars_with_fresh_vars<T>(&self, value: ty::Binder<'tcx, T>) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
|
@ -399,7 +399,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds));
|
||||
|
||||
// Also add an obligation for the method type being well-formed.
|
||||
let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig));
|
||||
let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig, tcx));
|
||||
debug!(
|
||||
"lookup_in_trait_adjusted: matched method method_ty={:?} obligation={:?}",
|
||||
method_ty, obligation
|
||||
|
@ -1753,7 +1753,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
/// region got replaced with the same variable, which requires a bit more coordination
|
||||
/// and/or tracking the substitution and
|
||||
/// so forth.
|
||||
fn erase_late_bound_regions<T>(&self, value: ty::Binder<T>) -> T
|
||||
fn erase_late_bound_regions<T>(&self, value: ty::Binder<'tcx, T>) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
|
@ -497,6 +497,7 @@ fn typeck_with_fallback<'tcx>(
|
||||
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
||||
<dyn AstConv<'_>>::ty_of_fn(
|
||||
&fcx,
|
||||
id,
|
||||
header.unsafety,
|
||||
header.abi,
|
||||
decl,
|
||||
|
@ -1067,13 +1067,14 @@ fn check_method_receiver<'fcx, 'tcx>(
|
||||
debug!("check_method_receiver: sig={:?}", sig);
|
||||
|
||||
let self_ty = fcx.normalize_associated_types_in(span, self_ty);
|
||||
let self_ty = fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(self_ty));
|
||||
let self_ty =
|
||||
fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(self_ty, fcx.tcx));
|
||||
|
||||
let receiver_ty = sig.inputs()[0];
|
||||
|
||||
let receiver_ty = fcx.normalize_associated_types_in(span, receiver_ty);
|
||||
let receiver_ty =
|
||||
fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(receiver_ty));
|
||||
fcx.tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(receiver_ty, fcx.tcx));
|
||||
|
||||
if fcx.tcx.features().arbitrary_self_types {
|
||||
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
|
||||
|
@ -1244,7 +1244,8 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
|
||||
match self.tcx.named_region(lt.hir_id) {
|
||||
Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {}
|
||||
Some(
|
||||
rl::Region::LateBound(debruijn, _, _) | rl::Region::LateBoundAnon(debruijn, _),
|
||||
rl::Region::LateBound(debruijn, _, _, _)
|
||||
| rl::Region::LateBoundAnon(debruijn, _, _),
|
||||
) if debruijn < self.outer_index => {}
|
||||
Some(
|
||||
rl::Region::LateBound(..)
|
||||
@ -1707,10 +1708,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||
}
|
||||
diag.emit();
|
||||
|
||||
ty::Binder::bind(fn_sig)
|
||||
ty::Binder::bind(fn_sig, tcx)
|
||||
}
|
||||
None => <dyn AstConv<'_>>::ty_of_fn(
|
||||
&icx,
|
||||
hir_id,
|
||||
sig.header.unsafety,
|
||||
sig.header.abi,
|
||||
&sig.decl,
|
||||
@ -1728,6 +1730,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||
..
|
||||
}) => <dyn AstConv<'_>>::ty_of_fn(
|
||||
&icx,
|
||||
hir_id,
|
||||
header.unsafety,
|
||||
header.abi,
|
||||
decl,
|
||||
@ -1749,13 +1752,10 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
|
||||
let ty = tcx.type_of(tcx.hir().get_parent_did(hir_id).to_def_id());
|
||||
let inputs =
|
||||
data.fields().iter().map(|f| tcx.type_of(tcx.hir().local_def_id(f.hir_id)));
|
||||
ty::Binder::bind(tcx.mk_fn_sig(
|
||||
inputs,
|
||||
ty,
|
||||
false,
|
||||
hir::Unsafety::Normal,
|
||||
abi::Abi::Rust,
|
||||
))
|
||||
ty::Binder::bind(
|
||||
tcx.mk_fn_sig(inputs, ty, false, hir::Unsafety::Normal, abi::Abi::Rust),
|
||||
tcx,
|
||||
)
|
||||
}
|
||||
|
||||
Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
|
||||
@ -2039,7 +2039,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||
param.bounds.iter().for_each(|bound| match bound {
|
||||
hir::GenericBound::Outlives(lt) => {
|
||||
let bound = <dyn AstConv<'_>>::ast_region_to_region(&icx, <, None);
|
||||
let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound));
|
||||
let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound), tcx);
|
||||
predicates.insert((outlives.to_predicate(tcx), lt.span));
|
||||
}
|
||||
_ => bug!(),
|
||||
@ -2084,6 +2084,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||
match predicate {
|
||||
hir::WherePredicate::BoundPredicate(bound_pred) => {
|
||||
let ty = icx.to_ty(&bound_pred.bounded_ty);
|
||||
let bound_vars = icx.tcx.late_bound_vars(bound_pred.bounded_ty.hir_id);
|
||||
|
||||
// Keep the type around in a dummy predicate, in case of no bounds.
|
||||
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
|
||||
@ -2099,9 +2100,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||
} else {
|
||||
let span = bound_pred.bounded_ty.span;
|
||||
let re_root_empty = tcx.lifetimes.re_root_empty;
|
||||
let predicate = ty::Binder::bind(ty::PredicateKind::TypeOutlives(
|
||||
ty::OutlivesPredicate(ty, re_root_empty),
|
||||
));
|
||||
let predicate = ty::Binder::bind_with_vars(
|
||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
|
||||
ty,
|
||||
re_root_empty,
|
||||
)),
|
||||
bound_vars,
|
||||
);
|
||||
predicates.insert((predicate.to_predicate(tcx), span));
|
||||
}
|
||||
}
|
||||
@ -2118,10 +2123,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||
let mut bounds = Bounds::default();
|
||||
let _ = <dyn AstConv<'_>>::instantiate_poly_trait_ref(
|
||||
&icx,
|
||||
&poly_trait_ref,
|
||||
&poly_trait_ref.trait_ref,
|
||||
poly_trait_ref.span,
|
||||
constness,
|
||||
ty,
|
||||
&mut bounds,
|
||||
false,
|
||||
);
|
||||
predicates.extend(bounds.predicates(tcx, ty));
|
||||
}
|
||||
@ -2144,9 +2151,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||
let region =
|
||||
<dyn AstConv<'_>>::ast_region_to_region(&icx, lifetime, None);
|
||||
predicates.insert((
|
||||
ty::Binder::bind(ty::PredicateKind::TypeOutlives(
|
||||
ty::OutlivesPredicate(ty, region),
|
||||
))
|
||||
ty::Binder::bind_with_vars(
|
||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
|
||||
ty, region,
|
||||
)),
|
||||
bound_vars,
|
||||
)
|
||||
.to_predicate(tcx),
|
||||
lifetime.span,
|
||||
));
|
||||
@ -2368,7 +2378,14 @@ fn predicates_from_bound<'tcx>(
|
||||
};
|
||||
|
||||
let mut bounds = Bounds::default();
|
||||
let _ = astconv.instantiate_poly_trait_ref(tr, constness, param_ty, &mut bounds);
|
||||
let _ = astconv.instantiate_poly_trait_ref(
|
||||
&tr.trait_ref,
|
||||
tr.span,
|
||||
constness,
|
||||
param_ty,
|
||||
&mut bounds,
|
||||
false,
|
||||
);
|
||||
bounds.predicates(astconv.tcx(), param_ty)
|
||||
}
|
||||
hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
||||
@ -2404,8 +2421,10 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
|
||||
} else {
|
||||
hir::Unsafety::Unsafe
|
||||
};
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||
let fty = <dyn AstConv<'_>>::ty_of_fn(
|
||||
&ItemCtxt::new(tcx, def_id),
|
||||
hir_id,
|
||||
unsafety,
|
||||
abi,
|
||||
decl,
|
||||
|
@ -430,7 +430,7 @@ pub fn hir_ty_to_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> {
|
||||
let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id);
|
||||
let env_def_id = tcx.hir().local_def_id(env_node_id);
|
||||
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id());
|
||||
item_cx.to_ty(hir_ty)
|
||||
<dyn AstConv<'_>>::ast_ty_to_ty(&item_cx, hir_ty)
|
||||
}
|
||||
|
||||
pub fn hir_trait_to_predicates<'tcx>(
|
||||
@ -445,7 +445,7 @@ pub fn hir_trait_to_predicates<'tcx>(
|
||||
let env_def_id = tcx.hir().local_def_id(env_hir_id);
|
||||
let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id.to_def_id());
|
||||
let mut bounds = Bounds::default();
|
||||
let _ = <dyn AstConv<'_>>::instantiate_poly_trait_ref_inner(
|
||||
let _ = <dyn AstConv<'_>>::instantiate_poly_trait_ref(
|
||||
&item_cx,
|
||||
hir_trait,
|
||||
DUMMY_SP,
|
||||
|
@ -352,7 +352,7 @@ impl Clean<Lifetime> for hir::Lifetime {
|
||||
match def {
|
||||
Some(
|
||||
rl::Region::EarlyBound(_, node_id, _)
|
||||
| rl::Region::LateBound(_, node_id, _)
|
||||
| rl::Region::LateBound(_, _, node_id, _)
|
||||
| rl::Region::Free(_, node_id),
|
||||
) => {
|
||||
if let Some(lt) = cx.lt_substs.get(&node_id).cloned() {
|
||||
@ -411,7 +411,7 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
|
||||
fn clean(&self, _cx: &mut DocContext<'_>) -> Option<Lifetime> {
|
||||
match *self {
|
||||
ty::ReStatic => Some(Lifetime::statik()),
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) => {
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) => {
|
||||
Some(Lifetime(name))
|
||||
}
|
||||
ty::ReEarlyBound(ref data) => Some(Lifetime(data.name)),
|
||||
|
@ -97,7 +97,7 @@ fn external_generic_args(
|
||||
.iter()
|
||||
.filter_map(|kind| match kind.unpack() {
|
||||
GenericArgKind::Lifetime(lt) => match lt {
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrAnon(_) }) => {
|
||||
ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrAnon(_), .. }) => {
|
||||
Some(GenericArg::Lifetime(Lifetime::elided()))
|
||||
}
|
||||
_ => lt.clean(cx).map(GenericArg::Lifetime),
|
||||
|
@ -118,7 +118,7 @@ pub fn type_parameter<T>() {}
|
||||
pub fn lifetime_parameter() {}
|
||||
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, generics_of")]
|
||||
#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, generics_of,fn_sig")]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn lifetime_parameter<'a>() {}
|
||||
|
||||
@ -150,7 +150,7 @@ pub fn lifetime_bound<'a, T>() {}
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of"
|
||||
except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn lifetime_bound<'a, T: 'a>() {}
|
||||
@ -183,7 +183,7 @@ pub fn second_lifetime_bound<'a, 'b, T: 'a>() {}
|
||||
#[cfg(not(cfail1))]
|
||||
#[rustc_clean(
|
||||
cfg = "cfail2",
|
||||
except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of"
|
||||
except = "hir_owner, hir_owner_nodes, generics_of, type_of, predicates_of,fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg = "cfail3")]
|
||||
pub fn second_lifetime_bound<'a, 'b, T: 'a + 'b>() {}
|
||||
|
@ -312,7 +312,7 @@ impl Foo {
|
||||
// if we lower generics before the body, then the `HirId` for
|
||||
// things in the body will be affected. So if you start to see
|
||||
// `typeck` appear dirty, that might be the cause. -nmatsakis
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")]
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,fn_sig")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_lifetime_parameter_to_method<'a>(&self) { }
|
||||
}
|
||||
@ -360,7 +360,7 @@ impl Foo {
|
||||
impl Foo {
|
||||
#[rustc_clean(
|
||||
cfg="cfail2",
|
||||
except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of"
|
||||
except="hir_owner,hir_owner_nodes,generics_of,predicates_of,type_of,fn_sig"
|
||||
)]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
|
||||
@ -388,7 +388,7 @@ impl Foo {
|
||||
// body will be affected. So if you start to see `typeck`
|
||||
// appear dirty, that might be the cause. -nmatsakis
|
||||
#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of,\
|
||||
type_of")]
|
||||
type_of,fn_sig")]
|
||||
#[rustc_clean(cfg="cfail3")]
|
||||
pub fn add_lifetime_bound_to_type_param_of_method<'a, T: 'a>(&self) { }
|
||||
}
|
||||
|
65
src/test/ui/associated-type-bounds/hrtb.rs
Normal file
65
src/test/ui/associated-type-bounds/hrtb.rs
Normal file
@ -0,0 +1,65 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(associated_type_bounds)]
|
||||
|
||||
trait A<'a> {}
|
||||
trait B<'b> {}
|
||||
fn foo<T>()
|
||||
where
|
||||
for<'a> T: A<'a> + 'a,
|
||||
{
|
||||
}
|
||||
trait C<'c>: for<'a> A<'a> + for<'b> B<'b> {
|
||||
type As;
|
||||
}
|
||||
struct D<T>
|
||||
where
|
||||
T: for<'c> C<'c, As: A<'c>>,
|
||||
{
|
||||
t: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
trait E<'e> {
|
||||
type As;
|
||||
}
|
||||
trait F<'f>: for<'a> A<'a> + for<'e> E<'e> {}
|
||||
struct G<T>
|
||||
where
|
||||
for<'f> T: F<'f, As: E<'f>> + 'f,
|
||||
{
|
||||
t: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
trait I<'a, 'b, 'c> {
|
||||
type As;
|
||||
}
|
||||
trait H<'d, 'e>: for<'f> I<'d, 'f, 'e> + 'd {}
|
||||
fn foo2<T>()
|
||||
where
|
||||
T: for<'g> H<'g, 'g, As: for<'h> H<'h, 'g> + 'g>,
|
||||
{
|
||||
}
|
||||
|
||||
fn foo3<T>()
|
||||
where
|
||||
T: for<'i> H<'i, 'i, As: for<'j> H<'j, 'i, As: for<'k> I<'i, 'k, 'j> + 'j> + 'i>,
|
||||
{
|
||||
}
|
||||
fn foo4<T>()
|
||||
where
|
||||
T: for<'l, 'i> H<'l, 'i, As: for<'j> H<'j, 'i, As: for<'k> I<'l, 'k, 'j> + 'j> + 'i>,
|
||||
{
|
||||
}
|
||||
|
||||
struct X<'x, 'y> {
|
||||
x: std::marker::PhantomData<&'x ()>,
|
||||
y: std::marker::PhantomData<&'y ()>,
|
||||
}
|
||||
|
||||
fn foo5<T>()
|
||||
where
|
||||
T: for<'l, 'i> H<'l, 'i, As: for<'j> H<'j, 'i, As: for<'k> H<'j, 'k, As = X<'j, 'k>> + 'j> + 'i>
|
||||
{
|
||||
}
|
||||
|
||||
fn main() {}
|
28
src/test/ui/hrtb/complex.rs
Normal file
28
src/test/ui/hrtb/complex.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// check-pass
|
||||
|
||||
trait A<'a> {}
|
||||
trait B<'b> {}
|
||||
fn foo<T>() where for<'a> T: A<'a> + 'a {}
|
||||
trait C<'c>: for<'a> A<'a> + for<'b> B<'b> {
|
||||
type As;
|
||||
}
|
||||
struct D<T> where T: for<'c> C<'c, As=&'c ()> {
|
||||
t: std::marker::PhantomData<T>,
|
||||
}
|
||||
trait E<'e, 'g> {
|
||||
type As;
|
||||
}
|
||||
trait F<'f>: for<'a> A<'a> + for<'e> E<'e, 'f> {}
|
||||
struct G<T> where T: for<'f> F<'f, As=&'f ()> {
|
||||
t: std::marker::PhantomData<T>,
|
||||
}
|
||||
trait H<'a, 'b> {
|
||||
type As;
|
||||
}
|
||||
trait I<'a>: for<'b> H<'a, 'b> {}
|
||||
|
||||
struct J<T> where T: for<'i> I<'i, As=&'i ()> {
|
||||
t: std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -7,7 +7,7 @@ fn foo(x: &u32) {
|
||||
|
||||
fn foo2(x: &u32) {}
|
||||
fn bar() {
|
||||
let y: fn(&'test u32) = foo2;
|
||||
let y: fn(&'test u32) = foo2; //~ ERROR use of undeclared lifetime
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -6,6 +6,22 @@ LL | fn foo(x: &u32) {
|
||||
LL | let y: &'test u32 = x;
|
||||
| ^^^^^ undeclared lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0261]: use of undeclared lifetime name `'test`
|
||||
--> $DIR/no_introducing_in_band_in_locals.rs:10:16
|
||||
|
|
||||
LL | let y: fn(&'test u32) = foo2;
|
||||
| ^^^^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider introducing lifetime `'test` here
|
||||
|
|
||||
LL | fn bar<'test>() {
|
||||
| ^^^^^^^
|
||||
help: consider making the type lifetime-generic with a new `'test` lifetime
|
||||
|
|
||||
LL | let y: for<'test> fn(&'test u32) = foo2;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
@ -1,5 +1,3 @@
|
||||
fn main() {
|
||||
0.clone::<'a>(); //~ ERROR use of undeclared lifetime name `'a`
|
||||
//~^ WARNING cannot specify lifetime arguments
|
||||
//~| WARNING this was previously accepted
|
||||
}
|
||||
|
@ -1,18 +1,3 @@
|
||||
warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/method-call-lifetime-args-unresolved.rs:2:15
|
||||
|
|
||||
LL | 0.clone::<'a>();
|
||||
| ^^
|
||||
|
|
||||
::: $SRC_DIR/core/src/clone.rs:LL:COL
|
||||
|
|
||||
LL | fn clone(&self) -> Self;
|
||||
| - the late bound lifetime parameter is introduced here
|
||||
|
|
||||
= note: `#[warn(late_bound_lifetime_arguments)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/method-call-lifetime-args-unresolved.rs:2:15
|
||||
|
|
||||
@ -23,6 +8,6 @@ LL | 0.clone::<'a>();
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
@ -6,7 +6,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
|
||||
|
|
||||
= note: defining type: test::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) i32)),
|
||||
for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) i32)),
|
||||
(),
|
||||
]
|
||||
|
||||
|
@ -6,7 +6,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y);
|
||||
|
|
||||
= note: defining type: test::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) i32)),
|
||||
for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) i32)),
|
||||
(),
|
||||
]
|
||||
|
||||
|
@ -10,7 +10,7 @@ LL | | },
|
||||
|
|
||||
= note: defining type: supply::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)),
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: late-bound region is '_#4r
|
||||
|
@ -11,7 +11,7 @@ LL | | });
|
||||
|
|
||||
= note: defining type: supply::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)),
|
||||
for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: late-bound region is '_#3r
|
||||
|
@ -10,7 +10,7 @@ LL | | })
|
||||
|
|
||||
= note: defining type: case1::{closure#0} with closure substs [
|
||||
i32,
|
||||
for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>)),
|
||||
for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>)),
|
||||
(),
|
||||
]
|
||||
|
||||
@ -49,7 +49,7 @@ LL | | })
|
||||
|
|
||||
= note: defining type: case2::{closure#0} with closure substs [
|
||||
i32,
|
||||
for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>)),
|
||||
for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: number of external vids: 2
|
||||
|
@ -12,7 +12,7 @@ LL | | });
|
||||
|
|
||||
= note: defining type: supply::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) u32>)),
|
||||
for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: late-bound region is '_#2r
|
||||
|
@ -12,7 +12,7 @@ LL | | });
|
||||
|
|
||||
= note: defining type: supply::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)),
|
||||
for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: late-bound region is '_#3r
|
||||
|
@ -11,7 +11,7 @@ LL | | });
|
||||
|
|
||||
= note: defining type: test::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)),
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: late-bound region is '_#3r
|
||||
|
@ -10,7 +10,7 @@ LL | | },
|
||||
|
|
||||
= note: defining type: supply::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)),
|
||||
for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: late-bound region is '_#3r
|
||||
|
@ -11,7 +11,7 @@ LL | | });
|
||||
|
|
||||
= note: defining type: supply::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>)),
|
||||
for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: late-bound region is '_#2r
|
||||
|
@ -11,7 +11,7 @@ LL | | });
|
||||
|
|
||||
= note: defining type: supply::{closure#0} with closure substs [
|
||||
i16,
|
||||
for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { kind: BrNamed('t1) }) u32>)),
|
||||
for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed('r) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrNamed('t0) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrNamed('t2) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrNamed('s) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrNamed('t3) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrNamed('t1) }) u32>)),
|
||||
(),
|
||||
]
|
||||
= note: late-bound region is '_#3r
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user