introduce from_ref helper for replacement
This commit is contained in:
parent
d046ffddc4
commit
8ab82c147a
@ -220,7 +220,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
|
||||
let ty_msg = match local_visitor.found_ty {
|
||||
Some(ty::TyS { kind: ty::Closure(def_id, substs), .. }) => {
|
||||
let fn_sig = substs.closure_sig(*def_id, self.tcx);
|
||||
let fn_sig = ty::ClosureSubsts::from_ref(substs).closure_sig(*def_id, self.tcx);
|
||||
let args = closure_args(&fn_sig);
|
||||
let ret = fn_sig.output().skip_binder().to_string();
|
||||
format!(" for the closure `fn({}) -> {}`", args, ret)
|
||||
|
@ -722,7 +722,7 @@ where
|
||||
ty::Closure(def_id, ref substs) => {
|
||||
// Skip lifetime parameters of the enclosing item(s)
|
||||
|
||||
for upvar_ty in substs.upvar_tys(def_id, self.tcx) {
|
||||
for upvar_ty in ty::ClosureSubsts::from_ref(substs).upvar_tys(def_id, self.tcx) {
|
||||
upvar_ty.visit_with(self);
|
||||
}
|
||||
|
||||
@ -886,7 +886,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
let substs =
|
||||
self.tcx.mk_substs(substs.substs.iter().enumerate().map(|(index, &kind)| {
|
||||
self.tcx.mk_substs(substs.iter().enumerate().map(|(index, &kind)| {
|
||||
if index < generics.parent_count {
|
||||
// Accommodate missing regions in the parent kinds...
|
||||
self.fold_kind_mapping_missing_regions_to_empty(kind)
|
||||
|
@ -745,7 +745,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||
// During upvar inference we may not know the
|
||||
// closure kind, just use the LATTICE_BOTTOM value.
|
||||
Some(infcx) =>
|
||||
infcx.closure_kind(closure_def_id, closure_substs)
|
||||
infcx.closure_kind(closure_def_id, ty::ClosureSubsts::from_ref(closure_substs))
|
||||
.unwrap_or(ty::ClosureKind::LATTICE_BOTTOM),
|
||||
|
||||
None =>
|
||||
|
@ -3370,17 +3370,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
)?);
|
||||
|
||||
// FIXME: chalk
|
||||
|
||||
if !self.tcx().sess.opts.debugging_opts.chalk {
|
||||
obligations.push(Obligation::new(
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
ty::Predicate::ClosureKind(closure_def_id, substs, kind),
|
||||
ty::Predicate::ClosureKind(closure_def_id, ty::ClosureSubsts::from_ref(substs.clone()), kind),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(VtableClosureData {
|
||||
closure_def_id,
|
||||
substs: substs.clone(),
|
||||
substs: ty::ClosureSubsts::from_ref(substs),
|
||||
nested: obligations,
|
||||
})
|
||||
}
|
||||
@ -3869,7 +3870,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
substs: ty::ClosureSubsts<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> ty::PolyTraitRef<'tcx> {
|
||||
debug!(
|
||||
"closure_trait_ref_unnormalized(obligation={:?}, closure_def_id={:?}, substs={:?})",
|
||||
|
@ -158,7 +158,7 @@ pub enum TyKind<'tcx> {
|
||||
|
||||
/// The anonymous type of a closure. Used to represent the type of
|
||||
/// `|a| a`.
|
||||
Closure(DefId, ClosureSubsts<'tcx>),
|
||||
Closure(DefId, SubstsRef<'tcx>),
|
||||
|
||||
/// The anonymous type of a generator. Used to represent the type of
|
||||
/// `|a| yield a`.
|
||||
@ -317,13 +317,18 @@ pub struct ClosureSubsts<'tcx> {
|
||||
|
||||
/// Struct returned by `split()`. Note that these are subslices of the
|
||||
/// parent slice and not canonical substs themselves.
|
||||
struct SplitClosureSubsts<'tcx> {
|
||||
closure_kind_ty: Ty<'tcx>,
|
||||
closure_sig_ty: Ty<'tcx>,
|
||||
upvar_kinds: &'tcx [GenericArg<'tcx>],
|
||||
pub(crate) struct SplitClosureSubsts<'tcx> {
|
||||
pub(crate) closure_kind_ty: Ty<'tcx>,
|
||||
pub(crate) closure_sig_ty: Ty<'tcx>,
|
||||
pub(crate) upvar_kinds: &'tcx [GenericArg<'tcx>],
|
||||
}
|
||||
|
||||
impl<'tcx> ClosureSubsts<'tcx> {
|
||||
// FIXME(csmoe): remove this method once the migration is done.
|
||||
pub fn from_ref(substs: SubstsRef<'tcx>) -> Self {
|
||||
Self { substs }
|
||||
}
|
||||
|
||||
/// Divides the closure substs into their respective
|
||||
/// components. Single source of truth with respect to the
|
||||
/// ordering.
|
||||
@ -2147,7 +2152,7 @@ impl<'tcx> TyS<'tcx> {
|
||||
Adt(_, substs) | Opaque(_, substs) => {
|
||||
out.extend(substs.regions())
|
||||
}
|
||||
Closure(_, ClosureSubsts { ref substs }) |
|
||||
Closure(_, ref substs ) |
|
||||
Generator(_, GeneratorSubsts { ref substs }, _) => {
|
||||
out.extend(substs.regions())
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use crate::infer::canonical::Canonical;
|
||||
use crate::ty::{self, Lift, List, Ty, TyCtxt, InferConst, ParamConst};
|
||||
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use crate::ty::sty::SplitClosureSubsts;
|
||||
|
||||
use rustc_serialize::{self, Encodable, Encoder, Decodable, Decoder};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
@ -379,6 +380,72 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
|
||||
pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
|
||||
tcx.mk_substs(self.iter().take(generics.count()).cloned())
|
||||
}
|
||||
|
||||
/// Divides the closure substs into their respective
|
||||
/// components. Single source of truth with respect to the
|
||||
/// ordering.
|
||||
fn split(self, def_id: DefId, tcx: TyCtxt<'_>) -> SplitClosureSubsts<'tcx> {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
let parent_len = generics.parent_count;
|
||||
SplitClosureSubsts {
|
||||
closure_kind_ty: self.substs.type_at(parent_len),
|
||||
closure_sig_ty: self.substs.type_at(parent_len + 1),
|
||||
upvar_kinds: &self.substs[parent_len + 2..],
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn upvar_tys(
|
||||
&self,
|
||||
def_id: DefId,
|
||||
tcx: TyCtxt<'_>,
|
||||
) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
|
||||
let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
|
||||
upvar_kinds.iter().map(|t| {
|
||||
if let UnpackedKind::Type(ty) = t.unpack() {
|
||||
ty
|
||||
} else {
|
||||
bug!("upvar should be type")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the closure kind for this closure; may return a type
|
||||
/// variable during inference. To get the closure kind during
|
||||
/// inference, use `infcx.closure_kind(def_id, substs)`.
|
||||
pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
|
||||
self.split(def_id, tcx).closure_kind_ty
|
||||
}
|
||||
|
||||
/// Returns the type representing the closure signature for this
|
||||
/// closure; may contain type variables during inference. To get
|
||||
/// the closure signature during inference, use
|
||||
/// `infcx.fn_sig(def_id)`.
|
||||
pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
|
||||
self.split(def_id, tcx).closure_sig_ty
|
||||
}
|
||||
|
||||
/// Returns the closure kind for this closure; only usable outside
|
||||
/// of an inference context, because in that context we know that
|
||||
/// there are no type variables.
|
||||
///
|
||||
/// If you have an inference context, use `infcx.closure_kind()`.
|
||||
pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::ClosureKind {
|
||||
self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap()
|
||||
}
|
||||
|
||||
/// Extracts the signature from the closure; only usable outside
|
||||
/// of an inference context, because in that context we know that
|
||||
/// there are no type variables.
|
||||
///
|
||||
/// If you have an inference context, use `infcx.closure_sig()`.
|
||||
pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
|
||||
let ty = self.closure_sig_ty(def_id, tcx);
|
||||
match ty.kind {
|
||||
ty::FnPtr(sig) => sig,
|
||||
_ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty.kind),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user