diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/ich/impls_ty.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/infer/canonical.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/middle/resolve_lifetime.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/fold.rs | 163 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 52 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 67 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/util.rs | 8 |
11 files changed, 270 insertions, 88 deletions
diff --git a/compiler/rustc_middle/src/ich/impls_ty.rs b/compiler/rustc_middle/src/ich/impls_ty.rs index c39ea5825a7..8e53e4ba948 100644 --- a/compiler/rustc_middle/src/ich/impls_ty.rs +++ b/compiler/rustc_middle/src/ich/impls_ty.rs @@ -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 }) => { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 5d0987193fa..5df2f91f09f 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -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 diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 98802721954..aa6488b329e 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -83,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>>>, } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index fbd5af9d0a9..99d063c7eea 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -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 diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1f1840c0e4a..bb2b00cbaea 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -810,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, }, @@ -2672,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> { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 32101b4c8c9..368236b146f 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -634,6 +634,42 @@ 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 @@ -695,16 +731,21 @@ impl<'tcx> TyCtxt<'tcx> { 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, - self, - ) + .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) } } @@ -777,27 +818,105 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> { } fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - use std::collections::btree_map::Entry; match r { - ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind { - ty::BrNamed(_def_id, _name) => { - // FIXME - } + ty::ReLateBound(index, _br) if *index == self.binder_index => { + bug!("{:?} {:?}", index, _br) + } - ty::BrAnon(var) => match self.vars.entry(var) { - Entry::Vacant(entry) => { - entry.insert(ty::BoundVariableKind::Region(br.kind)); + _ => (), + }; + + 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() { + panic!("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 { + panic!( + "Mismatched type kinds: {:?} doesn't var in list {:?}", + bound_ty.kind, list_var + ); + } } - Entry::Occupied(entry) => match entry.get() { - ty::BoundVariableKind::Region(_) => {} - _ => bug!("Conflicting bound vars"), - }, - }, + _ => panic!( + "Mismatched bound variable kinds! Expected type, found {:?}", + list_var + ), + } + } + + _ => (), + }; + + t.super_visit_with(self) + } - ty::BrEnv => { - // FIXME + 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() { + panic!("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 { + panic!( + "Mismatched region kinds: {:?} doesn't match var ({:?}) in list ({:?})", + br.kind, list_var, self.bound_vars + ); + } + } + _ => panic!( + "Mismatched bound variable kinds! Expected region, found {:?}", + list_var + ), + } + } _ => (), }; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 0d03cf4575f..e7bbdc3cceb 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -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), } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a09573fac02..6574c938260 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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, tcx)) + + // 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)) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index acb5c474164..b8f39fce21d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -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 { @@ -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, "", "> ")?; @@ -1865,7 +1866,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { 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) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1884df0c67b..e352d0bc756 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -6,6 +6,7 @@ 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::{ @@ -63,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 { @@ -987,13 +976,17 @@ where value.visit_with(&mut collector); Binder(value, collector.into_vars(tcx)) } -} -impl<'tcx, T> Binder<'tcx, T> { 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 @@ -1022,18 +1015,31 @@ impl<'tcx, T> Binder<'tcx, T> { Binder(&self.0, self.1) } - pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<'tcx, U> + 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<'tcx, U> + pub fn map_bound<F, U: TypeFoldable<'tcx>>(self, f: F) -> Binder<'tcx, U> where F: FnOnce(T) -> U, { - Binder(f(self.0), self.1) + 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 @@ -1045,7 +1051,14 @@ impl<'tcx, T> Binder<'tcx, 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<'tcx, U> { + 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) } @@ -1066,20 +1079,6 @@ impl<'tcx, T> Binder<'tcx, T> { 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<'tcx, U>, f: F) -> Binder<'tcx, R> - where - F: FnOnce(T, U) -> R, - { - Binder(f(self.0, u.0), self.1) - } - /// Splits the contents into two things that share the same binder /// level as the original, returning two distinct binders. /// @@ -1204,7 +1203,7 @@ pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>; impl<'tcx> PolyFnSig<'tcx> { #[inline] pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> { - self.map_bound_ref(|fn_sig| fn_sig.inputs()) + self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs()) } #[inline] pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 93fbc1f53b2..b211ac2a79f 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -499,18 +499,18 @@ impl<'tcx> TyCtxt<'tcx> { self, closure_def_id: DefId, closure_substs: SubstsRef<'tcx>, - ) -> Option<ty::Binder<'tcx, 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()?; + debug_assert!(!closure_ty.has_escaping_bound_vars()); let env_ty = match closure_kind { ty::ClosureKind::Fn => self.mk_imm_ref(self.mk_region(env_region), closure_ty), 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, self)) + Some(env_ty) } /// Returns `true` if the node pointed to by `def_id` is a `static` item. |
