Refactor Substs methods on generic parameters
This commit is contained in:
parent
030f10f752
commit
d9190da982
15 changed files with 395 additions and 308 deletions
|
@ -21,9 +21,9 @@ use hir::def_id::DefId;
|
|||
use middle::free_region::RegionRelations;
|
||||
use middle::region;
|
||||
use middle::lang_items;
|
||||
use ty::subst::Substs;
|
||||
use ty::subst::{UnpackedKind, Substs};
|
||||
use ty::{TyVid, IntVid, FloatVid};
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::{self, Ty, TyCtxt, GenericParamDefKind};
|
||||
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::relate::RelateResult;
|
||||
|
@ -941,10 +941,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
span: Span,
|
||||
def_id: DefId)
|
||||
-> &'tcx Substs<'tcx> {
|
||||
Substs::for_item(self.tcx, def_id, |def, _| {
|
||||
self.region_var_for_def(span, def)
|
||||
}, |def, _| {
|
||||
self.type_var_for_def(span, def)
|
||||
Substs::for_item(self.tcx, def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
UnpackedKind::Lifetime(self.region_var_for_def(span, param))
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
UnpackedKind::Type(self.type_var_for_def(span, param))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ use hir::def_id::DefId;
|
|||
use infer::outlives::env::OutlivesEnvironment;
|
||||
use middle::region;
|
||||
use middle::const_val::ConstEvalErr;
|
||||
use ty::subst::Substs;
|
||||
use ty::{self, AdtKind, Slice, Ty, TyCtxt, TypeFoldable, ToPredicate};
|
||||
use ty::subst::{UnpackedKind, Substs};
|
||||
use ty::{self, AdtKind, Slice, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
|
||||
use ty::error::{ExpectedFound, TypeError};
|
||||
use infer::{InferCtxt};
|
||||
|
||||
|
@ -841,10 +841,16 @@ fn vtable_methods<'a, 'tcx>(
|
|||
// the method may have some early-bound lifetimes, add
|
||||
// regions for those
|
||||
let substs = trait_ref.map_bound(|trait_ref| {
|
||||
Substs::for_item(
|
||||
tcx, def_id,
|
||||
|_, _| tcx.types.re_erased,
|
||||
|def, _| trait_ref.substs.type_for_def(def))
|
||||
Substs::for_item(tcx, def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
UnpackedKind::Lifetime(tcx.types.re_erased)
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
UnpackedKind::Type(trait_ref.substs.type_for_def(param))
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// the trait type may have higher-ranked lifetimes in it;
|
||||
|
|
|
@ -32,7 +32,7 @@ use middle::lang_items;
|
|||
use middle::resolve_lifetime::{self, ObjectLifetimeDefault};
|
||||
use middle::stability;
|
||||
use mir::{self, Mir, interpret};
|
||||
use ty::subst::{Kind, Substs, Subst};
|
||||
use ty::subst::{Kind, UnpackedKind, Substs, Subst};
|
||||
use ty::ReprOptions;
|
||||
use ty::Instance;
|
||||
use traits;
|
||||
|
@ -44,6 +44,7 @@ use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predic
|
|||
use ty::RegionKind;
|
||||
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
|
||||
use ty::TypeVariants::*;
|
||||
use ty::GenericParamDefKind;
|
||||
use ty::layout::{LayoutDetails, TargetDataLayout};
|
||||
use ty::maps;
|
||||
use ty::steal::Steal;
|
||||
|
@ -2325,16 +2326,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
|
||||
let adt_def = self.adt_def(def_id);
|
||||
let substs = Substs::for_item(self, def_id, |_, _| bug!(), |def, substs| {
|
||||
if def.index == 0 {
|
||||
ty
|
||||
} else {
|
||||
match def.kind {
|
||||
ty::GenericParamDefKind::Type(ty_param) => {
|
||||
assert!(ty_param.has_default);
|
||||
self.type_of(def.def_id).subst(self, substs)
|
||||
let substs = Substs::for_item(self, def_id, |param, substs| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => bug!(),
|
||||
GenericParamDefKind::Type(_) => {
|
||||
if param.index == 0 {
|
||||
UnpackedKind::Type(ty)
|
||||
} else {
|
||||
match param.kind {
|
||||
ty::GenericParamDefKind::Type(ty_param) => {
|
||||
assert!(ty_param.has_default);
|
||||
UnpackedKind::Type(
|
||||
self.type_of(param.def_id).subst(self, substs))
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// Type substitutions.
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use ty::{self, Lift, Slice, Region, Ty, TyCtxt};
|
||||
use ty::{self, Lift, Slice, Region, Ty, TyCtxt, GenericParamDefKind};
|
||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
|
||||
use serialize::{self, Encodable, Encoder, Decodable, Decoder};
|
||||
|
@ -174,80 +174,80 @@ impl<'tcx> Decodable for Kind<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A substitution mapping type/region parameters to new values.
|
||||
/// A substitution mapping generic parameters to new values.
|
||||
pub type Substs<'tcx> = Slice<Kind<'tcx>>;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> Substs<'tcx> {
|
||||
/// Creates a Substs that maps each generic parameter to itself.
|
||||
pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
|
||||
-> &'tcx Substs<'tcx> {
|
||||
Substs::for_item(tcx, def_id, |def, _| {
|
||||
tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
|
||||
}, |def, _| tcx.mk_ty_param_from_def(def))
|
||||
Substs::for_item(tcx, def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
UnpackedKind::Lifetime(
|
||||
tcx.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())))
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
UnpackedKind::Type(tcx.mk_ty_param_from_def(param))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a Substs for generic parameter definitions,
|
||||
/// by calling closures to obtain each region and type.
|
||||
/// by calling closures to obtain each kind.
|
||||
/// The closures get to observe the Substs as they're
|
||||
/// being built, which can be used to correctly
|
||||
/// substitute defaults of type parameters.
|
||||
pub fn for_item<FR, FT>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mut mk_region: FR,
|
||||
mut mk_type: FT)
|
||||
-> &'tcx Substs<'tcx>
|
||||
where FR: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||
FT: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
||||
/// substitute defaults of generic parameters.
|
||||
pub fn for_item<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mut mk_kind: F)
|
||||
-> &'tcx Substs<'tcx>
|
||||
where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> UnpackedKind<'tcx>
|
||||
{
|
||||
let defs = tcx.generics_of(def_id);
|
||||
let mut substs = Vec::with_capacity(defs.count());
|
||||
Substs::fill_item(&mut substs, tcx, defs, &mut mk_region, &mut mk_type);
|
||||
Substs::fill_item(&mut substs, tcx, defs, &mut mk_kind);
|
||||
tcx.intern_substs(&substs)
|
||||
}
|
||||
|
||||
pub fn extend_to<FR, FT>(&self,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mut mk_region: FR,
|
||||
mut mk_type: FT)
|
||||
-> &'tcx Substs<'tcx>
|
||||
where FR: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||
FT: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Ty<'tcx>
|
||||
pub fn extend_to<F>(&self,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mut mk_kind: F)
|
||||
-> &'tcx Substs<'tcx>
|
||||
where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> UnpackedKind<'tcx>
|
||||
{
|
||||
let defs = tcx.generics_of(def_id);
|
||||
let mut result = Vec::with_capacity(defs.count());
|
||||
result.extend(self[..].iter().cloned());
|
||||
Substs::fill_single(&mut result, defs, &mut mk_region, &mut mk_type);
|
||||
Substs::fill_single(&mut result, defs, &mut mk_kind);
|
||||
tcx.intern_substs(&result)
|
||||
}
|
||||
|
||||
pub fn fill_item<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
|
||||
pub fn fill_item<F>(substs: &mut Vec<Kind<'tcx>>,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
defs: &ty::Generics,
|
||||
mk_region: &mut FR,
|
||||
mk_type: &mut FT)
|
||||
where FR: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||
FT: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
||||
mk_kind: &mut F)
|
||||
where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> UnpackedKind<'tcx>
|
||||
{
|
||||
|
||||
if let Some(def_id) = defs.parent {
|
||||
let parent_defs = tcx.generics_of(def_id);
|
||||
Substs::fill_item(substs, tcx, parent_defs, mk_region, mk_type);
|
||||
Substs::fill_item(substs, tcx, parent_defs, mk_kind);
|
||||
}
|
||||
Substs::fill_single(substs, defs, mk_region, mk_type)
|
||||
Substs::fill_single(substs, defs, mk_kind)
|
||||
}
|
||||
|
||||
fn fill_single<FR, FT>(substs: &mut Vec<Kind<'tcx>>,
|
||||
fn fill_single<F>(substs: &mut Vec<Kind<'tcx>>,
|
||||
defs: &ty::Generics,
|
||||
mk_region: &mut FR,
|
||||
mk_type: &mut FT)
|
||||
where FR: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> ty::Region<'tcx>,
|
||||
FT: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Ty<'tcx> {
|
||||
mk_kind: &mut F)
|
||||
where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> UnpackedKind<'tcx>
|
||||
{
|
||||
for param in &defs.params {
|
||||
let kind = match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => mk_region(param, substs).into(),
|
||||
ty::GenericParamDefKind::Type(_) => mk_type(param, substs).into(),
|
||||
};
|
||||
let kind = mk_kind(param, substs);
|
||||
assert_eq!(param.index as usize, substs.len());
|
||||
substs.push(kind);
|
||||
substs.push(kind.pack());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@ use hir;
|
|||
use ich::NodeIdHashingMode;
|
||||
use middle::const_val::ConstVal;
|
||||
use traits::{self, ObligationCause};
|
||||
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
|
||||
use ty::fold::TypeVisitor;
|
||||
use ty::subst::UnpackedKind;
|
||||
use ty::subst::{Substs, UnpackedKind};
|
||||
use ty::maps::TyCtxtAt;
|
||||
use ty::TypeVariants::*;
|
||||
use ty::layout::{Integer, IntegerExt};
|
||||
|
@ -573,11 +573,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
/// Given the def-id of some item that has no type parameters, make
|
||||
/// a suitable "empty substs" for it.
|
||||
pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> &'tcx ty::Substs<'tcx> {
|
||||
ty::Substs::for_item(self, item_def_id,
|
||||
|_, _| self.types.re_erased,
|
||||
|_, _| {
|
||||
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
|
||||
pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
|
||||
Substs::for_item(self, item_def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => UnpackedKind::Lifetime(self.types.re_erased),
|
||||
GenericParamDefKind::Type(_) => {
|
||||
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -196,8 +196,8 @@ use rustc::hir::def_id::DefId;
|
|||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::interpret::{AllocId, ConstValue};
|
||||
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
|
||||
use rustc::ty::subst::{Substs, Kind};
|
||||
use rustc::ty::{self, TypeFoldable, Ty, TyCtxt};
|
||||
use rustc::ty::subst::{Substs, Kind, UnpackedKind};
|
||||
use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
|
||||
use rustc::ty::adjustment::CustomCoerceUnsized;
|
||||
use rustc::session::config;
|
||||
use rustc::mir::{self, Location, Promoted};
|
||||
|
@ -1112,10 +1112,16 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
continue;
|
||||
}
|
||||
|
||||
let substs = Substs::for_item(tcx,
|
||||
method.def_id,
|
||||
|_, _| tcx.types.re_erased,
|
||||
|def, _| trait_ref.substs.type_for_def(def));
|
||||
let substs = Substs::for_item(tcx, method.def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
UnpackedKind::Lifetime(tcx.types.re_erased)
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
UnpackedKind::Type(trait_ref.substs.type_for_def(param))
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let instance = ty::Instance::resolve(tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
|
|
|
@ -12,8 +12,8 @@ use rustc::hir;
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::subst::{Kind, Subst, Substs};
|
||||
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind};
|
||||
use rustc::ty::subst::{Kind, UnpackedKind, Subst, Substs};
|
||||
use rustc::ty::maps::Providers;
|
||||
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
|
@ -427,12 +427,12 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
|
|||
) {
|
||||
let tcx = self.tcx;
|
||||
|
||||
let substs = Substs::for_item(
|
||||
tcx,
|
||||
self.def_id,
|
||||
|_, _| tcx.types.re_erased,
|
||||
|_, _| ty
|
||||
);
|
||||
let substs = Substs::for_item(tcx, self.def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => UnpackedKind::Lifetime(tcx.types.re_erased),
|
||||
GenericParamDefKind::Type(_) => UnpackedKind::Type(ty),
|
||||
}
|
||||
});
|
||||
|
||||
// `func == Clone::clone(&ty) -> ty`
|
||||
let func_ty = tcx.mk_fn_def(self.def_id, substs);
|
||||
|
|
|
@ -20,7 +20,8 @@ use middle::resolve_lifetime as rl;
|
|||
use namespace::Namespace;
|
||||
use rustc::ty::subst::{Kind, UnpackedKind, Subst, Substs};
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, RegionKind, Ty, TyCtxt, GenericParamDefKind, ToPredicate, TypeFoldable};
|
||||
use rustc::ty::{self, RegionKind, Ty, TyCtxt, ToPredicate, TypeFoldable};
|
||||
use rustc::ty::GenericParamDefKind;
|
||||
use rustc::ty::wf::object_region_bounds;
|
||||
use rustc_target::spec::abi;
|
||||
use std::slice;
|
||||
|
@ -264,66 +265,76 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
};
|
||||
|
||||
let own_self = self_ty.is_some() as usize;
|
||||
let substs = Substs::for_item(tcx, def_id, |def, _| {
|
||||
let i = def.index as usize - own_self;
|
||||
if let Some(lifetime) = parameters.lifetimes.get(i) {
|
||||
self.ast_region_to_region(lifetime, Some(def))
|
||||
} else {
|
||||
tcx.types.re_static
|
||||
}
|
||||
}, |def, substs| {
|
||||
let i = def.index as usize;
|
||||
|
||||
// Handle Self first, so we can adjust the index to match the AST.
|
||||
if let (0, Some(ty)) = (i, self_ty) {
|
||||
return ty;
|
||||
}
|
||||
|
||||
let has_default = match def.kind {
|
||||
GenericParamDefKind::Type(ty) => ty.has_default,
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let i = i - (lt_accepted + own_self);
|
||||
if i < ty_provided {
|
||||
// A provided type parameter.
|
||||
self.ast_ty_to_ty(¶meters.types[i])
|
||||
} else if infer_types {
|
||||
// No type parameters were provided, we can infer all.
|
||||
let ty_var = if !default_needs_object_self(def) {
|
||||
self.ty_infer_for_def(def, span)
|
||||
} else {
|
||||
self.ty_infer(span)
|
||||
};
|
||||
ty_var
|
||||
} else if has_default {
|
||||
// No type parameter provided, but a default exists.
|
||||
|
||||
// If we are converting an object type, then the
|
||||
// `Self` parameter is unknown. However, some of the
|
||||
// other type parameters may reference `Self` in their
|
||||
// defaults. This will lead to an ICE if we are not
|
||||
// careful!
|
||||
if default_needs_object_self(def) {
|
||||
struct_span_err!(tcx.sess, span, E0393,
|
||||
"the type parameter `{}` must be explicitly specified",
|
||||
def.name)
|
||||
.span_label(span, format!("missing reference to `{}`", def.name))
|
||||
.note(&format!("because of the default `Self` reference, \
|
||||
type parameters must be specified on object types"))
|
||||
.emit();
|
||||
tcx.types.err
|
||||
} else {
|
||||
// This is a default type parameter.
|
||||
self.normalize_ty(
|
||||
span,
|
||||
tcx.at(span).type_of(def.def_id)
|
||||
.subst_spanned(tcx, substs, Some(span))
|
||||
)
|
||||
let substs = Substs::for_item(tcx, def_id, |param, substs| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
let i = param.index as usize - own_self;
|
||||
let lt = if let Some(lifetime) = parameters.lifetimes.get(i) {
|
||||
self.ast_region_to_region(lifetime, Some(param))
|
||||
} else {
|
||||
tcx.types.re_static
|
||||
};
|
||||
UnpackedKind::Lifetime(lt)
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
let i = param.index as usize;
|
||||
|
||||
// Handle Self first, so we can adjust the index to match the AST.
|
||||
if let (0, Some(ty)) = (i, self_ty) {
|
||||
return UnpackedKind::Type(ty);
|
||||
}
|
||||
|
||||
let has_default = match param.kind {
|
||||
GenericParamDefKind::Type(ty) => ty.has_default,
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let i = i - (lt_accepted + own_self);
|
||||
let ty = if i < ty_provided {
|
||||
// A provided type parameter.
|
||||
self.ast_ty_to_ty(¶meters.types[i])
|
||||
} else if infer_types {
|
||||
// No type parameters were provided, we can infer all.
|
||||
let ty_var = if !default_needs_object_self(param) {
|
||||
self.ty_infer_for_def(param, span)
|
||||
} else {
|
||||
self.ty_infer(span)
|
||||
};
|
||||
ty_var
|
||||
} else if has_default {
|
||||
// No type parameter provided, but a default exists.
|
||||
|
||||
// If we are converting an object type, then the
|
||||
// `Self` parameter is unknown. However, some of the
|
||||
// other type parameters may reference `Self` in their
|
||||
// defaults. This will lead to an ICE if we are not
|
||||
// careful!
|
||||
if default_needs_object_self(param) {
|
||||
struct_span_err!(tcx.sess, span, E0393,
|
||||
"the type parameter `{}` must be explicitly \
|
||||
specified",
|
||||
param.name)
|
||||
.span_label(span,
|
||||
format!("missing reference to `{}`", param.name))
|
||||
.note(&format!("because of the default `Self` reference, \
|
||||
type parameters must be specified on object \
|
||||
types"))
|
||||
.emit();
|
||||
tcx.types.err
|
||||
} else {
|
||||
// This is a default type parameter.
|
||||
self.normalize_ty(
|
||||
span,
|
||||
tcx.at(span).type_of(param.def_id)
|
||||
.subst_spanned(tcx, substs, Some(span))
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// We've already errored above about the mismatch.
|
||||
tcx.types.err
|
||||
};
|
||||
UnpackedKind::Type(ty)
|
||||
}
|
||||
} else {
|
||||
// We've already errored above about the mismatch.
|
||||
tcx.types.err
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1154,12 +1165,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
let mut substs = Vec::with_capacity(generics.count());
|
||||
if let Some(parent_id) = generics.parent {
|
||||
let parent_generics = tcx.generics_of(parent_id);
|
||||
Substs::fill_item(
|
||||
&mut substs, tcx, parent_generics,
|
||||
&mut |def, _| tcx.mk_region(
|
||||
ty::ReEarlyBound(def.to_early_bound_region_data())),
|
||||
&mut |def, _| tcx.mk_ty_param_from_def(def)
|
||||
);
|
||||
Substs::fill_item(&mut substs, tcx, parent_generics, &mut |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
UnpackedKind::Lifetime(
|
||||
tcx.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())))
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
UnpackedKind::Type(tcx.mk_ty_param_from_def(param))
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Replace all lifetimes with 'static
|
||||
for subst in &mut substs {
|
||||
|
|
|
@ -18,8 +18,8 @@ use rustc::infer::{InferOk, InferResult};
|
|||
use rustc::infer::LateBoundRegionConversionTime;
|
||||
use rustc::infer::type_variable::TypeVariableOrigin;
|
||||
use rustc::traits::error_reporting::ArgKind;
|
||||
use rustc::ty::{self, ToPolyTraitRef, Ty};
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, ToPolyTraitRef, Ty, GenericParamDefKind};
|
||||
use rustc::ty::subst::{UnpackedKind, Substs};
|
||||
use rustc::ty::TypeFoldable;
|
||||
use std::cmp;
|
||||
use std::iter;
|
||||
|
@ -104,15 +104,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// inference phase (`upvar.rs`).
|
||||
let base_substs =
|
||||
Substs::identity_for_item(self.tcx, self.tcx.closure_base_def_id(expr_def_id));
|
||||
let substs = base_substs.extend_to(
|
||||
self.tcx,
|
||||
expr_def_id,
|
||||
|_, _| span_bug!(expr.span, "closure has region param"),
|
||||
|_, _| {
|
||||
self.infcx
|
||||
.next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span))
|
||||
},
|
||||
);
|
||||
let substs = base_substs.extend_to(self.tcx,expr_def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
span_bug!(expr.span, "closure has region param")
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
UnpackedKind::Type(self.infcx
|
||||
.next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span)))
|
||||
}
|
||||
}
|
||||
});
|
||||
if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types {
|
||||
let substs = ty::GeneratorSubsts { substs };
|
||||
self.demand_eqtype(
|
||||
|
|
|
@ -15,8 +15,8 @@ use check::{FnCtxt, PlaceOp, callee, Needs};
|
|||
use hir::def_id::DefId;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::{self, Ty, GenericParamDefKind};
|
||||
use rustc::ty::subst::{UnpackedKind, Subst};
|
||||
use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
|
||||
use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
|
@ -317,30 +317,37 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||
assert_eq!(method_generics.parent_count, parent_substs.len());
|
||||
let provided = &segment.parameters;
|
||||
let own_counts = method_generics.own_counts();
|
||||
Substs::for_item(self.tcx, pick.item.def_id, |def, _| {
|
||||
let i = def.index as usize;
|
||||
if i < parent_substs.len() {
|
||||
parent_substs.region_at(i)
|
||||
} else if let Some(lifetime)
|
||||
= provided.as_ref().and_then(|p| p.lifetimes.get(i - parent_substs.len())) {
|
||||
AstConv::ast_region_to_region(self.fcx, lifetime, Some(def))
|
||||
} else {
|
||||
self.region_var_for_def(self.span, def)
|
||||
}
|
||||
}, |def, _cur_substs| {
|
||||
let i = def.index as usize;
|
||||
if i < parent_substs.len() {
|
||||
parent_substs.type_at(i)
|
||||
} else if let Some(ast_ty)
|
||||
= provided.as_ref().and_then(|p| {
|
||||
let idx =
|
||||
i - parent_substs.len() - own_counts.lifetimes;
|
||||
p.types.get(idx)
|
||||
})
|
||||
{
|
||||
self.to_ty(ast_ty)
|
||||
} else {
|
||||
self.type_var_for_def(self.span, def)
|
||||
Substs::for_item(self.tcx, pick.item.def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
let i = param.index as usize;
|
||||
let lt = if i < parent_substs.len() {
|
||||
parent_substs.region_at(i)
|
||||
} else if let Some(lifetime)
|
||||
= provided.as_ref().and_then(|p| p.lifetimes.get(i - parent_substs.len())) {
|
||||
AstConv::ast_region_to_region(self.fcx, lifetime, Some(param))
|
||||
} else {
|
||||
self.region_var_for_def(self.span, param)
|
||||
};
|
||||
UnpackedKind::Lifetime(lt)
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
let i = param.index as usize;
|
||||
let ty = if i < parent_substs.len() {
|
||||
parent_substs.type_at(i)
|
||||
} else if let Some(ast_ty)
|
||||
= provided.as_ref().and_then(|p| {
|
||||
let idx =
|
||||
i - parent_substs.len() - own_counts.lifetimes;
|
||||
p.types.get(idx)
|
||||
})
|
||||
{
|
||||
self.to_ty(ast_ty)
|
||||
} else {
|
||||
self.type_var_for_def(self.span, param)
|
||||
};
|
||||
UnpackedKind::Type(ty)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ use namespace::Namespace;
|
|||
use rustc::ty::subst::Substs;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable};
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::ty::GenericParamDefKind;
|
||||
use rustc::ty::subst::{UnpackedKind, Subst};
|
||||
use rustc::infer::{self, InferOk};
|
||||
|
||||
use syntax::ast;
|
||||
|
@ -253,16 +254,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
trait_def_id);
|
||||
|
||||
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
||||
let substs = Substs::for_item(self.tcx,
|
||||
trait_def_id,
|
||||
|def, _| self.region_var_for_def(span, def),
|
||||
|def, _substs| {
|
||||
if def.index == 0 {
|
||||
self_ty
|
||||
} else if let Some(ref input_types) = opt_input_types {
|
||||
input_types[def.index as usize - 1]
|
||||
} else {
|
||||
self.type_var_for_def(span, def)
|
||||
let substs = Substs::for_item(self.tcx, trait_def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
UnpackedKind::Lifetime(self.region_var_for_def(span, param))
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
let ty = if param.index == 0 {
|
||||
self_ty
|
||||
} else if let Some(ref input_types) = opt_input_types {
|
||||
input_types[param.index as usize - 1]
|
||||
} else {
|
||||
self.type_var_for_def(span, param)
|
||||
};
|
||||
UnpackedKind::Type(ty)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -17,9 +17,10 @@ use check::FnCtxt;
|
|||
use hir::def_id::DefId;
|
||||
use hir::def::Def;
|
||||
use namespace::Namespace;
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::ty::subst::{UnpackedKind, Subst, Substs};
|
||||
use rustc::traits::{self, ObligationCause};
|
||||
use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TraitRef, TypeFoldable};
|
||||
use rustc::ty::GenericParamDefKind;
|
||||
use rustc::infer::type_variable::TypeVariableOrigin;
|
||||
use rustc::util::nodemap::FxHashSet;
|
||||
use rustc::infer::{self, InferOk};
|
||||
|
@ -1387,21 +1388,28 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
if generics.params.is_empty() {
|
||||
xform_fn_sig.subst(self.tcx, substs)
|
||||
} else {
|
||||
let substs = Substs::for_item(self.tcx, method, |def, _| {
|
||||
let i = def.index as usize;
|
||||
if i < substs.len() {
|
||||
substs.region_at(i)
|
||||
} else {
|
||||
// In general, during probe we erase regions. See
|
||||
// `impl_self_ty()` for an explanation.
|
||||
self.tcx.types.re_erased
|
||||
}
|
||||
}, |def, _cur_substs| {
|
||||
let i = def.index as usize;
|
||||
if i < substs.len() {
|
||||
substs.type_at(i)
|
||||
} else {
|
||||
self.type_var_for_def(self.span, def)
|
||||
let substs = Substs::for_item(self.tcx, method, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
let i = param.index as usize;
|
||||
let lt = if i < substs.len() {
|
||||
substs.region_at(i)
|
||||
} else {
|
||||
// In general, during probe we erase regions. See
|
||||
// `impl_self_ty()` for an explanation.
|
||||
self.tcx.types.re_erased
|
||||
};
|
||||
UnpackedKind::Lifetime(lt)
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
let i = param.index as usize;
|
||||
let ty = if i < substs.len() {
|
||||
substs.type_at(i)
|
||||
} else {
|
||||
self.type_var_for_def(self.span, param)
|
||||
};
|
||||
UnpackedKind::Type(ty)
|
||||
}
|
||||
}
|
||||
});
|
||||
xform_fn_sig.subst(self.tcx, substs)
|
||||
|
@ -1414,12 +1422,18 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
fn fresh_item_substs(&self, def_id: DefId) -> &'tcx Substs<'tcx> {
|
||||
Substs::for_item(self.tcx,
|
||||
def_id,
|
||||
|_, _| self.tcx.types.re_erased,
|
||||
|_, _| self.next_ty_var(
|
||||
TypeVariableOrigin::SubstitutionPlaceholder(
|
||||
self.tcx.def_span(def_id))))
|
||||
Substs::for_item(self.tcx, def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
UnpackedKind::Lifetime(self.tcx.types.re_erased)
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
UnpackedKind::Type(self.next_ty_var(
|
||||
TypeVariableOrigin::SubstitutionPlaceholder(
|
||||
self.tcx.def_span(def_id))))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Replace late-bound-regions bound by `value` with `'static` using
|
||||
|
|
|
@ -94,7 +94,7 @@ use rustc::infer::anon_types::AnonTypeDecl;
|
|||
use rustc::infer::type_variable::{TypeVariableOrigin};
|
||||
use rustc::middle::region;
|
||||
use rustc::mir::interpret::{GlobalId};
|
||||
use rustc::ty::subst::{Kind, Subst, Substs};
|
||||
use rustc::ty::subst::{Kind, UnpackedKind, Subst, Substs};
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
|
||||
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate};
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
|
@ -4758,71 +4758,78 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
(None, None) => (0, false)
|
||||
};
|
||||
let substs = Substs::for_item(self.tcx, def.def_id(), |def, _| {
|
||||
let mut i = def.index as usize;
|
||||
let substs = Substs::for_item(self.tcx, def.def_id(), |param, substs| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
let mut i = param.index as usize;
|
||||
|
||||
let segment = if i < fn_start {
|
||||
i -= has_self as usize;
|
||||
type_segment
|
||||
} else {
|
||||
i -= fn_start;
|
||||
fn_segment
|
||||
};
|
||||
let lifetimes = segment.map_or(&[][..], |(s, _)| {
|
||||
s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
|
||||
});
|
||||
|
||||
if let Some(lifetime) = lifetimes.get(i) {
|
||||
AstConv::ast_region_to_region(self, lifetime, Some(def))
|
||||
} else {
|
||||
self.re_infer(span, Some(def)).unwrap()
|
||||
}
|
||||
}, |def, substs| {
|
||||
let mut i = def.index as usize;
|
||||
|
||||
let segment = if i < fn_start {
|
||||
// Handle Self first, so we can adjust the index to match the AST.
|
||||
if has_self && i == 0 {
|
||||
return opt_self_ty.unwrap_or_else(|| {
|
||||
self.type_var_for_def(span, def)
|
||||
let segment = if i < fn_start {
|
||||
i -= has_self as usize;
|
||||
type_segment
|
||||
} else {
|
||||
i -= fn_start;
|
||||
fn_segment
|
||||
};
|
||||
let lifetimes = segment.map_or(&[][..], |(s, _)| {
|
||||
s.parameters.as_ref().map_or(&[][..], |p| &p.lifetimes[..])
|
||||
});
|
||||
|
||||
let lt = if let Some(lifetime) = lifetimes.get(i) {
|
||||
AstConv::ast_region_to_region(self, lifetime, Some(param))
|
||||
} else {
|
||||
self.re_infer(span, Some(param)).unwrap()
|
||||
};
|
||||
UnpackedKind::Lifetime(lt)
|
||||
}
|
||||
i -= has_self as usize;
|
||||
type_segment
|
||||
} else {
|
||||
i -= fn_start;
|
||||
fn_segment
|
||||
};
|
||||
let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
|
||||
(s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
|
||||
});
|
||||
GenericParamDefKind::Type(_) => {
|
||||
let mut i = param.index as usize;
|
||||
|
||||
// Skip over the lifetimes in the same segment.
|
||||
if let Some((_, generics)) = segment {
|
||||
i -= generics.own_counts().lifetimes;
|
||||
}
|
||||
let segment = if i < fn_start {
|
||||
// Handle Self first, so we can adjust the index to match the AST.
|
||||
if has_self && i == 0 {
|
||||
return UnpackedKind::Type(opt_self_ty.unwrap_or_else(|| {
|
||||
self.type_var_for_def(span, param)
|
||||
}));
|
||||
}
|
||||
i -= has_self as usize;
|
||||
type_segment
|
||||
} else {
|
||||
i -= fn_start;
|
||||
fn_segment
|
||||
};
|
||||
let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
|
||||
(s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
|
||||
});
|
||||
|
||||
let has_default = match def.kind {
|
||||
GenericParamDefKind::Type(ty) => ty.has_default,
|
||||
_ => unreachable!()
|
||||
};
|
||||
// Skip over the lifetimes in the same segment.
|
||||
if let Some((_, generics)) = segment {
|
||||
i -= generics.own_counts().lifetimes;
|
||||
}
|
||||
|
||||
if let Some(ast_ty) = types.get(i) {
|
||||
// A provided type parameter.
|
||||
self.to_ty(ast_ty)
|
||||
} else if !infer_types && has_default {
|
||||
// No type parameter provided, but a default exists.
|
||||
let default = self.tcx.type_of(def.def_id);
|
||||
self.normalize_ty(
|
||||
span,
|
||||
default.subst_spanned(self.tcx, substs, Some(span))
|
||||
)
|
||||
} else {
|
||||
// No type parameters were provided, we can infer all.
|
||||
// This can also be reached in some error cases:
|
||||
// We prefer to use inference variables instead of
|
||||
// TyError to let type inference recover somewhat.
|
||||
self.type_var_for_def(span, def)
|
||||
let has_default = match param.kind {
|
||||
GenericParamDefKind::Type(ty) => ty.has_default,
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let ty = if let Some(ast_ty) = types.get(i) {
|
||||
// A provided type parameter.
|
||||
self.to_ty(ast_ty)
|
||||
} else if !infer_types && has_default {
|
||||
// No type parameter provided, but a default exists.
|
||||
let default = self.tcx.type_of(param.def_id);
|
||||
self.normalize_ty(
|
||||
span,
|
||||
default.subst_spanned(self.tcx, substs, Some(span))
|
||||
)
|
||||
} else {
|
||||
// No type parameters were provided, we can infer all.
|
||||
// This can also be reached in some error cases:
|
||||
// We prefer to use inference variables instead of
|
||||
// TyError to let type inference recover somewhat.
|
||||
self.type_var_for_def(span, param)
|
||||
};
|
||||
UnpackedKind::Type(ty)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
use check::{Inherited, FnCtxt};
|
||||
use constrained_type_params::{identify_constrained_type_params, Parameter};
|
||||
|
||||
use ty::GenericParamDefKind;
|
||||
|
||||
use hir::def_id::DefId;
|
||||
use rustc::traits::{self, ObligationCauseCode};
|
||||
use rustc::ty::{self, Lift, Ty, TyCtxt};
|
||||
use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind};
|
||||
use rustc::ty::subst::{UnpackedKind, Substs};
|
||||
use rustc::ty::util::ExplicitSelf;
|
||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
||||
use rustc::middle::lang_items;
|
||||
|
@ -406,22 +405,28 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
|||
// For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
|
||||
//
|
||||
// First we build the defaulted substitution.
|
||||
let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| {
|
||||
// All regions are identity.
|
||||
fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
|
||||
}, |def, _| {
|
||||
// If the param has a default,
|
||||
if is_our_default(def) {
|
||||
let default_ty = fcx.tcx.type_of(def.def_id);
|
||||
// and it's not a dependent default
|
||||
if !default_ty.needs_subst() {
|
||||
// then substitute with the default.
|
||||
return default_ty;
|
||||
}
|
||||
let substs = Substs::for_item(fcx.tcx, def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
// All regions are identity.
|
||||
UnpackedKind::Lifetime(
|
||||
fcx.tcx.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())))
|
||||
}
|
||||
// Mark unwanted params as err.
|
||||
fcx.tcx.types.err
|
||||
});
|
||||
GenericParamDefKind::Type(_) => {
|
||||
// If the param has a default,
|
||||
if is_our_default(param) {
|
||||
let default_ty = fcx.tcx.type_of(param.def_id);
|
||||
// and it's not a dependent default
|
||||
if !default_ty.needs_subst() {
|
||||
// then substitute with the default.
|
||||
return UnpackedKind::Type(default_ty);
|
||||
}
|
||||
}
|
||||
// Mark unwanted params as err.
|
||||
UnpackedKind::Type(fcx.tcx.types.err)
|
||||
}
|
||||
}
|
||||
});
|
||||
// Now we build the substituted predicates.
|
||||
for &pred in predicates.predicates.iter() {
|
||||
struct CountParams { params: FxHashSet<u32> }
|
||||
|
|
|
@ -30,7 +30,8 @@ use constrained_type_params as ctp;
|
|||
use middle::lang_items::SizedTraitLangItem;
|
||||
use middle::resolve_lifetime as rl;
|
||||
use rustc::mir::mono::Linkage;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::subst::{UnpackedKind, Substs};
|
||||
use rustc::ty::GenericParamDefKind;
|
||||
use rustc::ty::{ToPredicate, ReprOptions};
|
||||
use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
|
||||
use rustc::ty::maps::Providers;
|
||||
|
@ -1096,15 +1097,17 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
|
||||
let substs = ty::ClosureSubsts {
|
||||
substs: Substs::for_item(
|
||||
tcx,
|
||||
def_id,
|
||||
|def, _| {
|
||||
let region = def.to_early_bound_region_data();
|
||||
tcx.mk_region(ty::ReEarlyBound(region))
|
||||
},
|
||||
|def, _| tcx.mk_ty_param_from_def(def)
|
||||
)
|
||||
substs: Substs::for_item(tcx, def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
let region = param.to_early_bound_region_data();
|
||||
UnpackedKind::Lifetime(tcx.mk_region(ty::ReEarlyBound(region)))
|
||||
}
|
||||
GenericParamDefKind::Type(_) => {
|
||||
UnpackedKind::Type(tcx.mk_ty_param_from_def(param))
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
tcx.mk_closure(def_id, substs)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue