rustc: split Generics of a method from its parent Generics.

This commit is contained in:
Eduard Burtescu 2016-08-10 20:39:09 +03:00
parent c1cfd58cbd
commit 3e74e5bffe
25 changed files with 291 additions and 265 deletions

View File

@ -82,7 +82,6 @@ use hir::def::Def;
use hir::def_id::DefId;
use infer::{self, TypeOrigin};
use middle::region;
use ty::subst;
use ty::{self, TyCtxt, TypeFoldable};
use ty::{Region, ReFree};
use ty::error::TypeError;
@ -1369,7 +1368,7 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
let generics = self.tcx.lookup_generics(did);
let expected =
generics.regions.len(subst::TypeSpace) as u32;
generics.regions.len() as u32;
let lifetimes =
path.segments.last().unwrap().parameters.lifetimes();
let mut insert = Vec::new();

View File

@ -271,14 +271,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let def = self.tcx.lookup_trait_def(trait_ref.def_id);
let trait_str = def.trait_ref.to_string();
if let Some(ref istring) = item.value_str() {
let mut generic_map = def.generics.types.iter_enumerated()
.map(|(param, i, gen)| {
(gen.name.as_str().to_string(),
trait_ref.substs.types.get(param, i)
.to_string())
}).collect::<FnvHashMap<String, String>>();
generic_map.insert("Self".to_string(),
trait_ref.self_ty().to_string());
let generic_map = def.generics.types.iter().map(|param| {
(param.name.as_str().to_string(),
trait_ref.substs.type_for_def(param).to_string())
}).collect::<FnvHashMap<String, String>>();
let parser = Parser::new(&istring);
let mut errored = false;
let err: String = parser.filter_map(|p| {

View File

@ -20,7 +20,6 @@
use super::elaborate_predicates;
use hir::def_id::DefId;
use ty::subst;
use traits;
use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
use std::rc::Rc;
@ -266,7 +265,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
// We can't monomorphize things like `fn foo<A>(...)`.
if !method.generics.types.is_empty_in(subst::FnSpace) {
if !method.generics.types.is_empty() {
return Some(MethodViolationCode::Generic);
}

View File

@ -757,33 +757,14 @@ impl RegionParameterDef {
/// with an item or method. Analogous to hir::Generics.
#[derive(Clone, Debug)]
pub struct Generics<'tcx> {
pub types: VecPerParamSpace<TypeParameterDef<'tcx>>,
pub regions: VecPerParamSpace<RegionParameterDef>,
pub parent: Option<DefId>,
pub parent_regions: u32,
pub parent_types: u32,
pub regions: Vec<RegionParameterDef>,
pub types: Vec<TypeParameterDef<'tcx>>,
pub has_self: bool,
}
impl<'tcx> Generics<'tcx> {
pub fn empty() -> Generics<'tcx> {
Generics {
types: VecPerParamSpace::empty(),
regions: VecPerParamSpace::empty(),
has_self: false,
}
}
pub fn is_empty(&self) -> bool {
self.types.is_empty() && self.regions.is_empty()
}
pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
!self.types.is_empty_in(space)
}
pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
!self.regions.is_empty_in(space)
}
}
/// Bounds on generics.
#[derive(Clone)]
pub struct GenericPredicates<'tcx> {

View File

@ -832,20 +832,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::Generics {
types: self.types.fold_with(folder),
regions: self.regions.fold_with(folder),
has_self: self.has_self
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.types.visit_with(visitor) || self.regions.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
ty::GenericPredicates {

View File

@ -89,42 +89,55 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
let defs = tcx.lookup_generics(def_id);
let num_regions = defs.parent_regions as usize + defs.regions.len();
let num_types = defs.parent_types as usize + defs.types.len();
let mut substs = Substs {
types: VecPerParamSpace {
type_limit: 0,
content: Vec::with_capacity(defs.types.content.len())
},
regions: VecPerParamSpace {
type_limit: 0,
content: Vec::with_capacity(defs.regions.content.len())
content: Vec::with_capacity(num_regions)
},
types: VecPerParamSpace {
type_limit: 0,
content: Vec::with_capacity(num_types)
}
};
for &space in &ParamSpace::all() {
for def in defs.regions.get_slice(space) {
assert_eq!(def.space, space);
substs.fill_item(tcx, defs, &mut mk_region, &mut mk_type);
let region = mk_region(def, &substs);
substs.regions.content.push(region);
Substs::new(tcx, substs.types, substs.regions)
}
if space == TypeSpace {
substs.regions.type_limit += 1;
}
}
fn fill_item<FR, FT>(&mut self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
defs: &ty::Generics<'tcx>,
mk_region: &mut FR,
mk_type: &mut FT)
where FR: FnMut(&ty::RegionParameterDef, &Substs<'tcx>) -> ty::Region,
FT: FnMut(&ty::TypeParameterDef<'tcx>, &Substs<'tcx>) -> Ty<'tcx> {
if let Some(def_id) = defs.parent {
let parent_defs = tcx.lookup_generics(def_id);
self.fill_item(tcx, parent_defs, mk_region, mk_type);
}
for def in defs.types.get_slice(space) {
assert_eq!(def.space, space);
for def in &defs.regions {
let region = mk_region(def, self);
self.regions.content.push(region);
let ty = mk_type(def, &substs);
substs.types.content.push(ty);
if space == TypeSpace {
substs.types.type_limit += 1;
}
if def.space == TypeSpace {
self.regions.type_limit += 1;
assert_eq!(self.regions.content.len(), self.regions.type_limit);
}
}
Substs::new(tcx, substs.types, substs.regions)
for def in &defs.types {
let ty = mk_type(def, self);
self.types.content.push(ty);
if def.space == TypeSpace {
self.types.type_limit += 1;
assert_eq!(self.types.content.len(), self.types.type_limit);
}
}
}
pub fn is_noop(&self) -> bool {
@ -149,16 +162,14 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
target_substs: &Substs<'tcx>)
-> &'tcx Substs<'tcx> {
let defs = tcx.lookup_generics(source_ancestor);
assert_eq!(self.types.len(TypeSpace), defs.types.len(TypeSpace));
assert_eq!(self.types.len(TypeSpace), defs.types.len());
assert_eq!(target_substs.types.len(FnSpace), 0);
assert_eq!(defs.types.len(FnSpace), 0);
assert_eq!(self.regions.len(TypeSpace), defs.regions.len(TypeSpace));
assert_eq!(self.regions.len(TypeSpace), defs.regions.len());
assert_eq!(target_substs.regions.len(FnSpace), 0);
assert_eq!(defs.regions.len(FnSpace), 0);
let Substs { mut types, mut regions } = target_substs.clone();
types.content.extend(&self.types.as_full_slice()[defs.types.content.len()..]);
regions.content.extend(&self.regions.as_full_slice()[defs.regions.content.len()..]);
types.content.extend(&self.types.as_full_slice()[defs.types.len()..]);
regions.content.extend(&self.regions.as_full_slice()[defs.regions.len()..]);
Substs::new(tcx, types, regions)
}
}
@ -597,8 +608,8 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
-> ty::TraitRef<'tcx> {
let Substs { mut types, mut regions } = substs.clone();
let defs = tcx.lookup_generics(trait_id);
types.content.truncate(defs.types.type_limit);
regions.content.truncate(defs.regions.type_limit);
types.content.truncate(defs.types.len());
regions.content.truncate(defs.regions.len());
ty::TraitRef {
def_id: trait_id,

View File

@ -73,13 +73,15 @@ pub fn parameterized(f: &mut fmt::Formatter,
let mut has_self = false;
let (fn_trait_kind, item_name) = ty::tls::with(|tcx| {
verbose = tcx.sess.verbose();
let generics = tcx.lookup_generics(did);
let mut generics = tcx.lookup_generics(did);
if let Some(def_id) = generics.parent {
generics = tcx.lookup_generics(def_id);
}
if !verbose {
let ty_params = generics.types.get_slice(subst::TypeSpace);
if ty_params.last().map_or(false, |def| def.default.is_some()) {
if generics.types.last().map_or(false, |def| def.default.is_some()) {
if let Some(substs) = tcx.lift(&substs) {
let tps = substs.types.get_slice(subst::TypeSpace);
for (def, actual) in ty_params.iter().zip(tps).rev() {
for (def, actual) in generics.types.iter().zip(tps).rev() {
if def.default.subst(tcx, substs) != Some(actual) {
break;
}

View File

@ -620,9 +620,9 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
if let Some(impl_item) = impl_item_opt {
if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
encode_attributes(rbml_w, &impl_item.attrs);
let scheme = ecx.tcx.lookup_item_type(m.def_id);
let any_types = !scheme.generics.types.is_empty();
let needs_inline = any_types || is_default_impl ||
let generics = ecx.tcx.lookup_generics(m.def_id);
let types = generics.parent_types as usize + generics.types.len();
let needs_inline = types > 0 || is_default_impl ||
attr::requests_inline(&impl_item.attrs);
if needs_inline || sig.constness == hir::Constness::Const {
encode_inlined_item(ecx,

View File

@ -149,9 +149,29 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
pub fn parse_generics(&mut self) -> &'tcx ty::Generics<'tcx> {
let regions = self.parse_vec_per_param_space(|this| this.parse_region_param_def());
let types = self.parse_vec_per_param_space(|this| this.parse_type_param_def());
let parent = self.parse_opt(|this| this.parse_def());
let parent_regions = self.parse_u32();
assert_eq!(self.next(), '|');
let parent_types = self.parse_u32();
let mut regions = vec![];
assert_eq!(self.next(), '[');
while self.peek() != ']' {
regions.push(self.parse_region_param_def());
}
assert_eq!(self.next(), ']');
let mut types = vec![];
assert_eq!(self.next(), '[');
while self.peek() != ']' {
types.push(self.parse_type_param_def());
}
assert_eq!(self.next(), ']');
self.tcx.alloc_generics(ty::Generics {
parent: parent,
parent_regions: parent_regions,
parent_types: parent_types,
regions: regions,
types: types,
has_self: self.next() == 'S'

View File

@ -274,10 +274,21 @@ pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
pub fn enc_generics<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
generics: &ty::Generics<'tcx>) {
enc_vec_per_param_space(w, cx, &generics.regions,
|w, cx, r| enc_region_param_def(w, cx, r));
enc_vec_per_param_space(w, cx, &generics.types,
|w, cx, ty| enc_type_param_def(w, cx, ty));
enc_opt(w, generics.parent, |w, def_id| {
write!(w, "{}|", (cx.ds)(cx.tcx, def_id));
});
write!(w, "{}|{}[",
generics.parent_regions,
generics.parent_types);
for r in &generics.regions {
enc_region_param_def(w, cx, r)
}
write!(w, "][");
for t in &generics.types {
enc_type_param_def(w, cx, t);
}
write!(w, "]");
if generics.has_self {
write!(w, "S");

View File

@ -2470,8 +2470,8 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
hir_map::NodeImplItem(&hir::ImplItem {
node: hir::ImplItemKind::Method(..), .. }) => {
let def_id = tcx.map.local_def_id(id);
let scheme = tcx.lookup_item_type(def_id);
scheme.generics.types.is_empty()
let generics = tcx.lookup_generics(def_id);
generics.parent_types == 0 && generics.types.is_empty()
}
_ => false

View File

@ -195,7 +195,7 @@ use rustc::hir::map as hir_map;
use rustc::hir::def_id::DefId;
use rustc::middle::lang_items::{ExchangeFreeFnLangItem, ExchangeMallocFnLangItem};
use rustc::traits;
use rustc::ty::subst::{self, Substs, Subst};
use rustc::ty::subst::{Substs, Subst};
use rustc::ty::{self, TypeFoldable, TyCtxt};
use rustc::ty::adjustment::CustomCoerceUnsized;
use rustc::mir::repr as mir;
@ -1219,17 +1219,16 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id_to_string(tcx, impl_def_id));
if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) {
let default_impls = tcx.provided_trait_methods(trait_ref.def_id);
let callee_substs = tcx.erase_regions(&trait_ref.substs);
let overridden_methods: FnvHashSet<_> = items.iter()
.map(|item| item.name)
.collect();
for default_impl in default_impls {
if overridden_methods.contains(&default_impl.name) {
for method in tcx.provided_trait_methods(trait_ref.def_id) {
if overridden_methods.contains(&method.name) {
continue;
}
if default_impl.generics.has_type_params(subst::FnSpace) {
if !method.generics.types.is_empty() {
continue;
}
@ -1242,7 +1241,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
callee_substs,
impl_def_id,
impl_substs,
default_impl.name);
method.name);
assert!(mth.is_provided);
@ -1251,10 +1250,10 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
continue;
}
if can_have_local_instance(tcx, default_impl.def_id) {
if can_have_local_instance(tcx, method.def_id) {
let empty_substs = tcx.erase_regions(&mth.substs);
let item = create_fn_trans_item(tcx,
default_impl.def_id,
method.def_id,
callee_substs,
empty_substs);
output.push(item);

View File

@ -381,10 +381,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
// Again, only create type information if full debuginfo is enabled
let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo {
generics.types.as_full_slice().iter().enumerate().map(|(i, param)| {
let actual_type = cx.tcx().normalize_associated_type(&actual_types[i]);
let names = get_type_parameter_names(cx, generics);
actual_types.iter().zip(names).map(|(ty, name)| {
let actual_type = cx.tcx().normalize_associated_type(ty);
let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
let name = CString::new(param.name.as_str().as_bytes()).unwrap();
let name = CString::new(name.as_str().as_bytes()).unwrap();
unsafe {
llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
DIB(cx),
@ -403,6 +404,16 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
return create_DIArray(DIB(cx), &template_params[..]);
}
fn get_type_parameter_names<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
generics: &ty::Generics<'tcx>)
-> Vec<ast::Name> {
let mut names = generics.parent.map_or(vec![], |def_id| {
get_type_parameter_names(cx, cx.tcx().lookup_generics(def_id))
});
names.extend(generics.types.iter().map(|param| param.name));
names
}
fn get_containing_scope_and_span<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>,
instance: Instance<'tcx>)
-> (DIScope, Span) {

View File

@ -429,7 +429,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
bug!("ErrorReported returned, but no errors reports?")
}
};
let expected_num_region_params = decl_generics.regions.len(TypeSpace);
let expected_num_region_params = decl_generics.regions.len();
let supplied_num_region_params = lifetimes.len();
let regions = if expected_num_region_params == supplied_num_region_params {
lifetimes.iter().map(|l| ast_region_to_region(tcx, l)).collect()
@ -454,8 +454,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
// Check the number of type parameters supplied by the user.
if let Some(num_provided) = num_types_provided {
let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
let ty_param_defs = &ty_param_defs[self_ty.is_some() as usize..];
let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..];
check_type_argument_count(tcx, span, num_provided, ty_param_defs);
}

View File

@ -13,7 +13,7 @@ use rustc::infer::{self, InferOk, TypeOrigin};
use rustc::ty;
use rustc::traits::{self, Reveal};
use rustc::ty::error::ExpectedFound;
use rustc::ty::subst::{self, Subst, Substs};
use rustc::ty::subst::{Subst, Substs};
use rustc::hir::map::Node;
use rustc::hir::{ImplItemKind, TraitItem_};
@ -95,8 +95,8 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
}
let num_impl_m_type_params = impl_m.generics.types.len(subst::FnSpace);
let num_trait_m_type_params = trait_m.generics.types.len(subst::FnSpace);
let num_impl_m_type_params = impl_m.generics.types.len();
let num_trait_m_type_params = trait_m.generics.types.len();
if num_impl_m_type_params != num_trait_m_type_params {
span_err!(tcx.sess, impl_m_span, E0049,
"method `{}` has {} type parameter{} \
@ -389,8 +389,8 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-> bool
{
let trait_params = trait_generics.regions.get_slice(subst::FnSpace);
let impl_params = impl_generics.regions.get_slice(subst::FnSpace);
let trait_params = &trait_generics.regions[..];
let impl_params = &impl_generics.regions[..];
debug!("check_region_bounds_on_impl_method: \
trait_generics={:?} \

View File

@ -49,7 +49,7 @@ fn equate_intrinsic_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
variadic: false,
}),
}));
let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
let i_n_tps = i_ty.generics.types.len();
if i_n_tps != n_tps {
struct_span_err!(tcx.sess, it.span, E0094,
"intrinsic has wrong number of type \
@ -321,7 +321,7 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
let tcx = ccx.tcx;
let i_ty = tcx.lookup_item_type(tcx.map.local_def_id(it.id));
let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
let i_n_tps = i_ty.generics.types.len();
let name = it.name.as_str();
let (n_tps, inputs, output) = match &*name {

View File

@ -308,7 +308,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
// variables.
let num_supplied_types = supplied_method_types.len();
let method = pick.item.as_opt_method().unwrap();
let num_method_types = method.generics.types.len(subst::FnSpace);
let num_method_types = method.generics.types.len();
if num_supplied_types > 0 && num_supplied_types != num_method_types {
if num_method_types == 0 {

View File

@ -183,15 +183,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let trait_def = self.tcx.lookup_trait_def(trait_def_id);
if let Some(ref input_types) = opt_input_types {
assert_eq!(trait_def.generics.types.len(subst::TypeSpace) - 1, input_types.len());
assert_eq!(trait_def.generics.types.len() - 1, input_types.len());
}
assert_eq!(trait_def.generics.types.len(subst::FnSpace), 0);
assert!(trait_def.generics.regions.is_empty());
// 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| {
assert_eq!(def.space, subst::TypeSpace);
if def.index == 0 {
self_ty
} else if let Some(ref input_types) = opt_input_types {
@ -221,8 +221,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let tcx = self.tcx;
let method_item = self.trait_item(trait_def_id, m_name).unwrap();
let method_ty = method_item.as_opt_method().unwrap();
assert_eq!(method_ty.generics.types.len(subst::FnSpace), 0);
assert_eq!(method_ty.generics.regions.len(subst::FnSpace), 0);
assert_eq!(method_ty.generics.types.len(), 0);
assert_eq!(method_ty.generics.regions.len(), 0);
debug!("lookup_in_trait_adjusted: method_item={:?} method_ty={:?}",
method_item, method_ty);

View File

@ -518,9 +518,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
trait_ref,
trait_ref.substs,
m);
assert_eq!(m.generics.types.len(subst::TypeSpace),
assert_eq!(m.generics.parent_types as usize,
trait_ref.substs.types.len(subst::TypeSpace));
assert_eq!(m.generics.regions.len(subst::TypeSpace),
assert_eq!(m.generics.parent_regions as usize,
trait_ref.substs.regions.len(subst::TypeSpace));
}
@ -1232,8 +1232,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
let xform_self_ty = method.fty.sig.input(0);
let xform_self_ty = self.erase_late_bound_regions(&xform_self_ty);
if method.generics.types.is_empty_in(subst::FnSpace) &&
method.generics.regions.is_empty_in(subst::FnSpace) {
if method.generics.types.is_empty() && method.generics.regions.is_empty() {
xform_self_ty.subst(self.tcx, substs)
} else {
let substs = Substs::for_item(self.tcx, method.def_id, |def, _| {
@ -1260,17 +1259,13 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
impl_def_id: DefId)
-> (Ty<'tcx>, &'tcx Substs<'tcx>)
{
let impl_pty = self.tcx.lookup_item_type(impl_def_id);
let impl_ty = self.tcx.lookup_item_type(impl_def_id).ty;
let type_vars =
impl_pty.generics.types.map(
|_| self.next_ty_var());
let substs = Substs::for_item(self.tcx, impl_def_id,
|_, _| ty::ReErased,
|_, _| self.next_ty_var());
let region_placeholders =
impl_pty.generics.regions.map(
|_| ty::ReErased); // see erase_late_bound_regions() for an expl of why 'erased
(impl_pty.ty, Substs::new(self.tcx, type_vars, region_placeholders))
(impl_ty, substs)
}
/// Replace late-bound-regions bound by `value` with `'static` using

View File

@ -881,8 +881,7 @@ fn check_on_unimplemented<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// `{Self}` is allowed
Position::ArgumentNamed(s) if s == "Self" => (),
// So is `{A}` if A is a type parameter
Position::ArgumentNamed(s) => match types.as_full_slice()
.iter().find(|t| {
Position::ArgumentNamed(s) => match types.iter().find(|t| {
t.name.as_str() == s
}) {
Some(_) => (),
@ -1693,7 +1692,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let mut ty = self.tcx.lookup_item_type(did).ty;
if ty.is_fn() {
// Tuple variants have fn type even in type namespace, extract true variant type from it
ty = self.tcx.no_late_bound_regions(&type_scheme.ty.fn_ret()).unwrap();
ty = self.tcx.no_late_bound_regions(&ty.fn_ret()).unwrap();
}
let type_predicates = self.tcx.lookup_predicates(did);
let substs = AstConv::ast_path_substs_for_ty(self, self,
@ -3222,13 +3221,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.set_tainted_by_errors();
return None;
}
Def::Variant(..) | Def::Struct(..) => {
Some(self.tcx.expect_variant_def(def))
Def::Variant(type_did, _) | Def::Struct(type_did) => {
Some((type_did, self.tcx.expect_variant_def(def)))
}
Def::TyAlias(did) | Def::AssociatedTy(_, did) => {
Def::TyAlias(did) => {
if let Some(&ty::TyStruct(adt, _)) = self.tcx.opt_lookup_item_type(did)
.map(|scheme| &scheme.ty.sty) {
Some(adt.struct_variant())
Some((did, adt.struct_variant()))
} else {
None
}
@ -3236,14 +3235,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
_ => None
};
if let Some(variant) = variant {
if let Some((def_id, variant)) = variant {
if variant.kind == ty::VariantKind::Tuple &&
!self.tcx.sess.features.borrow().relaxed_adts {
emit_feature_err(&self.tcx.sess.parse_sess.span_diagnostic,
"relaxed_adts", span, GateIssue::Language,
"tuple structs and variants in struct patterns are unstable");
}
let ty = self.instantiate_type_path(def.def_id(), path, node_id);
let ty = self.instantiate_type_path(def_id, path, node_id);
Some((variant, ty))
} else {
struct_span_err!(self.tcx.sess, path.span, E0071,
@ -4122,25 +4121,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let mut fn_segment = None;
match def {
// Case 1 and 1b. Reference to a *type* or *enum variant*.
Def::SelfTy(..) |
Def::Struct(..) |
Def::Variant(..) |
Def::Enum(..) |
Def::TyAlias(..) |
Def::AssociatedTy(..) |
Def::Trait(..) |
Def::PrimTy(..) |
Def::TyParam(..) => {
Def::Struct(def_id) |
Def::Variant(_, def_id) |
Def::Enum(def_id) |
Def::TyAlias(def_id) |
Def::AssociatedTy(_, def_id) |
Def::Trait(def_id) => {
// Everything but the final segment should have no
// parameters at all.
type_segment = segments.last();
let mut generics = self.tcx.lookup_generics(def_id);
if let Some(def_id) = generics.parent {
// Variant and struct constructors use the
// generics of their parent type definition.
generics = self.tcx.lookup_generics(def_id);
}
type_segment = Some((segments.last().unwrap(), generics));
}
// Case 2. Reference to a top-level value.
Def::Fn(..) |
Def::Const(..) |
Def::Static(..) => {
fn_segment = segments.last();
Def::Fn(def_id) |
Def::Const(def_id) |
Def::Static(def_id, _) => {
fn_segment = Some((segments.last().unwrap(),
self.tcx.lookup_generics(def_id)));
}
// Case 3. Reference to a method or associated const.
@ -4154,14 +4157,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty::ImplContainer(_) => {}
}
let generics = self.tcx.lookup_generics(def_id);
if segments.len() >= 2 {
type_segment = Some(&segments[segments.len() - 2]);
let parent_generics = self.tcx.lookup_generics(generics.parent.unwrap());
type_segment = Some((&segments[segments.len() - 2], parent_generics));
} else {
// `<T>::assoc` will end up here, and so can `T::assoc`.
let self_ty = opt_self_ty.expect("UFCS sugared assoc missing Self");
ufcs_associated = Some((container, self_ty));
}
fn_segment = segments.last();
fn_segment = Some((segments.last().unwrap(), generics));
}
// Other cases. Various nonsense that really shouldn't show up
@ -4169,6 +4174,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// elsewhere. (I hope)
Def::Mod(..) |
Def::ForeignMod(..) |
Def::PrimTy(..) |
Def::SelfTy(..) |
Def::TyParam(..) |
Def::Local(..) |
Def::Label(..) |
Def::Upvar(..) |
@ -4213,12 +4221,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// a problem.
self.check_path_parameter_count(subst::TypeSpace,
span,
scheme.generics,
!require_type_space,
&mut type_segment);
self.check_path_parameter_count(subst::FnSpace,
span,
scheme.generics,
true,
&mut fn_segment);
@ -4228,7 +4234,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
subst::TypeSpace => type_segment,
subst::FnSpace => fn_segment
};
let lifetimes = match segment.map(|s| &s.parameters) {
let lifetimes = match segment.map(|(s, _)| &s.parameters) {
Some(&hir::AngleBracketedParameters(ref data)) => &data.lifetimes[..],
Some(&hir::ParenthesizedParameters(_)) => bug!(),
None => &[]
@ -4242,25 +4248,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}, |def, substs| {
let mut i = def.index as usize;
let segment = match def.space {
subst::TypeSpace => type_segment,
subst::TypeSpace => {
// Handle Self first, so we can adjust the index to match the AST.
match (type_segment, fn_segment) {
(Some((_, generics)), _) | (_, Some((_, generics))) => {
if generics.has_self {
if i == 0 {
return opt_self_ty.unwrap_or_else(|| {
self.type_var_for_def(span, def, substs)
});
}
i -= 1;
}
}
_ => {}
}
type_segment
}
subst::FnSpace => fn_segment
};
let types = match segment.map(|s| &s.parameters) {
let types = match segment.map(|(s, _)| &s.parameters) {
Some(&hir::AngleBracketedParameters(ref data)) => &data.types[..],
Some(&hir::ParenthesizedParameters(_)) => bug!(),
None => &[]
};
// Handle Self first, so we can adjust the index to match the AST.
if scheme.generics.has_self && def.space == subst::TypeSpace {
if i == 0 {
return opt_self_ty.unwrap_or_else(|| {
self.type_var_for_def(span, def, substs)
});
}
i -= 1;
}
let can_omit = def.space != subst::TypeSpace || !require_type_space;
let default = if can_omit && types.len() == 0 {
def.default
@ -4306,9 +4318,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// with the substituted impl type.
let impl_scheme = self.tcx.lookup_item_type(impl_def_id);
assert_eq!(substs.types.len(subst::TypeSpace),
impl_scheme.generics.types.len(subst::TypeSpace));
impl_scheme.generics.types.len());
assert_eq!(substs.regions.len(subst::TypeSpace),
impl_scheme.generics.regions.len(subst::TypeSpace));
impl_scheme.generics.regions.len());
let impl_ty = self.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
match self.sub_types(false, TypeOrigin::Misc(span), self_ty, impl_ty) {
@ -4339,10 +4351,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn check_path_parameter_count(&self,
space: subst::ParamSpace,
span: Span,
generics: &ty::Generics<'tcx>,
can_omit: bool,
segment: &mut Option<&hir::PathSegment>) {
let (lifetimes, types, bindings) = match segment.map(|s| &s.parameters) {
segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) {
let (lifetimes, types, bindings) = match segment.map(|(s, _)| &s.parameters) {
Some(&hir::AngleBracketedParameters(ref data)) => {
(&data.lifetimes[..], &data.types[..], &data.bindings[..])
}
@ -4357,7 +4368,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
// Check provided lifetime parameters.
let lifetime_defs = generics.regions.get_slice(space);
let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions);
if lifetimes.len() > lifetime_defs.len() {
let span = lifetimes[lifetime_defs.len()].span;
span_err!(self.tcx.sess, span, E0088,
@ -4374,12 +4385,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
// Check provided type parameters.
let type_defs = generics.types.get_slice(space);
let type_defs = if space == subst::TypeSpace {
&type_defs[generics.has_self as usize..]
} else {
type_defs
};
let type_defs = segment.map_or(&[][..], |(_, generics)| {
if space == subst::TypeSpace {
&generics.types[generics.has_self as usize..]
} else {
&generics.types
}
});
let required_len = type_defs.iter()
.take_while(|d| d.default.is_none())
.count();

View File

@ -523,10 +523,10 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
}
fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) {
let impl_params = generics.types.get_slice(subst::TypeSpace).iter()
.map(|tp| tp.name).collect::<HashSet<_>>();
let parent = tcx.lookup_generics(generics.parent.unwrap());
let impl_params: HashSet<_> = parent.types.iter().map(|tp| tp.name).collect();
for method_param in generics.types.get_slice(subst::FnSpace) {
for method_param in &generics.types {
if impl_params.contains(&method_param.name) {
error_194(tcx, span, method_param.name);
}

View File

@ -65,7 +65,7 @@ use middle::lang_items::SizedTraitLangItem;
use middle::const_val::ConstVal;
use rustc_const_eval::EvalHint::UncheckedExprHint;
use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, TypeSpace, VecPerParamSpace};
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, TypeSpace};
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
use rustc::ty::{VariantKind};
@ -793,9 +793,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
}
if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {
let const_def_id = ccx.tcx.map.local_def_id(impl_item.id);
let ty_generics = generics_of_def_id(ccx, const_def_id);
let ty = ccx.icx(&ty_predicates)
.to_ty(&ExplicitRscope, &ty);
tcx.register_item_type(ccx.tcx.map.local_def_id(impl_item.id),
tcx.register_item_type(const_def_id,
TypeScheme {
generics: ty_generics,
ty: ty,
@ -858,11 +860,13 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
// Convert all the associated constants.
for trait_item in trait_items {
if let hir::ConstTraitItem(ref ty, ref default) = trait_item.node {
let const_def_id = ccx.tcx.map.local_def_id(trait_item.id);
let ty_generics = generics_of_def_id(ccx, const_def_id);
let ty = ccx.icx(&trait_predicates)
.to_ty(&ExplicitRscope, ty);
tcx.register_item_type(ccx.tcx.map.local_def_id(trait_item.id),
tcx.register_item_type(const_def_id,
TypeScheme {
generics: trait_def.generics,
generics: ty_generics,
ty: ty,
});
convert_associated_const(ccx,
@ -957,7 +961,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
predicates: ty::GenericPredicates<'tcx>) {
let tcx = ccx.tcx;
let def_id = tcx.map.local_def_id(ctor_id);
tcx.generics.borrow_mut().insert(def_id, scheme.generics);
generics_of_def_id(ccx, def_id);
let ctor_ty = match variant.kind {
VariantKind::Unit | VariantKind::Struct => scheme.ty,
VariantKind::Tuple => {
@ -1389,24 +1393,35 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
use rustc::hir::map::*;
use rustc::hir::*;
let node = tcx.map.get(node_id);
let parent_def_id = match node {
NodeImplItem(_) |
NodeTraitItem(_) |
NodeVariant(_) |
NodeStructCtor(_) => {
let parent_id = tcx.map.get_parent(node_id);
Some(tcx.map.local_def_id(parent_id))
}
_ => None
};
let mut opt_self = None;
let mut base_def_id = None;
let mut allow_defaults = false;
let no_generics = hir::Generics::empty();
let (space, ast_generics) = match tcx.map.get(node_id) {
NodeImplItem(&ImplItem { node: ImplItemKind::Method(ref sig, _), .. }) |
NodeTraitItem(&TraitItem { node: MethodTraitItem(ref sig, _), .. }) => {
let parent_id = tcx.map.get_parent(node_id);
base_def_id = Some(tcx.map.local_def_id(parent_id));
(FnSpace, &sig.generics)
let (space, ast_generics) = match node {
NodeTraitItem(item) => {
match item.node {
MethodTraitItem(ref sig, _) => (FnSpace, &sig.generics),
_ => (FnSpace, &no_generics)
}
}
NodeImplItem(_) |
NodeTraitItem(_) => {
let parent_id = tcx.map.get_parent(node_id);
base_def_id = Some(tcx.map.local_def_id(parent_id));
(FnSpace, &no_generics)
NodeImplItem(item) => {
match item.node {
ImplItemKind::Method(ref sig, _) => (FnSpace, &sig.generics),
_ => (FnSpace, &no_generics)
}
}
NodeItem(item) => {
@ -1457,9 +1472,16 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
_ => (TypeSpace, &no_generics)
};
let empty_generics = ty::Generics::empty();
let base_generics = base_def_id.map_or(&empty_generics, |def_id| {
generics_of_def_id(ccx, def_id)
let has_self = opt_self.is_some();
let mut parent_has_self = false;
let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| {
let generics = generics_of_def_id(ccx, def_id);
assert_eq!(generics.parent, None);
assert_eq!(generics.parent_regions, 0);
assert_eq!(generics.parent_types, 0);
assert_eq!(has_self, false);
parent_has_self = generics.has_self;
(generics.regions.len(), generics.types.len())
});
let early_lifetimes = early_bound_lifetimes_from_generics(ccx, ast_generics);
@ -1477,32 +1499,15 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
// Now create the real type parameters.
let types = ast_generics.ty_params.iter().enumerate().map(|(i, p)| {
let i = opt_self.is_some() as u32 + i as u32;
let i = has_self as u32 + i as u32;
get_or_create_type_parameter_def(ccx, ast_generics, space, i, p, allow_defaults)
}).collect();
let has_self = base_generics.has_self || opt_self.is_some();
let (regions, types) = match space {
TypeSpace => {
assert_eq!(base_generics.regions.as_full_slice().len(), 0);
assert_eq!(base_generics.types.as_full_slice().len(), 0);
(VecPerParamSpace::new(regions, vec![]),
VecPerParamSpace::new(opt_self.into_iter().chain(types).collect(), vec![]))
}
FnSpace => {
assert_eq!(base_generics.regions.len(FnSpace), 0);
assert_eq!(base_generics.types.len(FnSpace), 0);
(VecPerParamSpace::new(base_generics.regions.get_slice(TypeSpace).to_vec(),
regions),
VecPerParamSpace::new(base_generics.types.get_slice(TypeSpace).to_vec(),
types))
}
};
});
let types: Vec<_> = opt_self.into_iter().chain(types).collect();
// Debugging aid.
if tcx.has_attr(def_id, "rustc_object_lifetime_default") {
let object_lifetime_default_reprs: String =
types.as_full_slice().iter().map(|t| {
types.iter().map(|t| {
match t.object_lifetime_default {
ty::ObjectLifetimeDefault::Specific(r) => r.to_string(),
d => format!("{:?}", d),
@ -1512,9 +1517,12 @@ fn generics_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
tcx.alloc_generics(ty::Generics {
parent: parent_def_id,
parent_regions: parent_regions as u32,
parent_types: parent_types as u32,
regions: regions,
types: types,
has_self: has_self
has_self: has_self || parent_has_self
})
})
}
@ -2148,7 +2156,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
&mut input_parameters);
let ty_generics = generics_of_def_id(ccx, impl_def_id);
for (ty_param, param) in ty_generics.types.as_full_slice().iter().zip(&generics.ty_params) {
for (ty_param, param) in ty_generics.types.iter().zip(&generics.ty_params) {
let param_ty = ty::ParamTy::for_def(ty_param);
if !input_parameters.contains(&ctp::Parameter::Type(param_ty)) {
report_unused_parameter(ccx, param.span, "type", &param_ty.to_string());

View File

@ -301,8 +301,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_substs(
generics,
trait_ref.def_id,
trait_def.generics.types.as_full_slice(),
trait_def.generics.regions.as_full_slice(),
&trait_def.generics.types,
&trait_def.generics.regions,
trait_ref.substs,
variance);
}
@ -359,16 +359,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// README.md for a discussion on dep-graph management.
self.tcx().dep_graph.read(ItemVariances::to_dep_node(&def.did));
// All type parameters on enums and structs should be
// in the TypeSpace.
assert!(item_type.generics.types.is_empty_in(subst::FnSpace));
assert!(item_type.generics.regions.is_empty_in(subst::FnSpace));
self.add_constraints_from_substs(
generics,
def.did,
item_type.generics.types.as_full_slice(),
item_type.generics.regions.as_full_slice(),
&item_type.generics.types,
&item_type.generics.regions,
substs,
variance);
}
@ -385,8 +380,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_substs(
generics,
trait_ref.def_id,
trait_def.generics.types.as_full_slice(),
trait_def.generics.regions.as_full_slice(),
&trait_def.generics.types,
&trait_def.generics.regions,
trait_ref.substs,
variance);
}
@ -406,7 +401,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
ty::TyParam(ref data) => {
let def_id = generics.types.get(data.space, data.idx as usize).def_id;
assert_eq!(data.space, subst::TypeSpace);
assert_eq!(generics.parent, None);
let def_id = generics.types[data.idx as usize].def_id;
let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
match self.terms_cx.inferred_map.get(&node_id) {
Some(&index) => {
@ -493,8 +490,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
variance: VarianceTermPtr<'a>) {
match region {
ty::ReEarlyBound(ref data) => {
let def_id =
generics.regions.get(data.space, data.index as usize).def_id;
assert_eq!(data.space, subst::TypeSpace);
assert_eq!(generics.parent, None);
let def_id = generics.regions[data.index as usize].def_id;
let node_id = self.tcx().map.as_local_node_id(def_id).unwrap();
if self.is_to_be_inferred(node_id) {
let index = self.inferred_index(node_id);

View File

@ -21,7 +21,6 @@ use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::hir::print as pprust;
use rustc::ty::{self, TyCtxt};
use rustc::ty::subst;
use rustc_const_eval::lookup_const_by_id;
@ -161,7 +160,7 @@ pub fn build_external_trait<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tc
let def = tcx.lookup_trait_def(did);
let trait_items = tcx.trait_items(did).clean(cx);
let predicates = tcx.lookup_predicates(did);
let generics = (def.generics, &predicates, subst::TypeSpace).clean(cx);
let generics = (def.generics, &predicates).clean(cx);
let generics = filter_non_trait_generics(did, generics);
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
clean::Trait {
@ -189,7 +188,7 @@ fn build_external_function<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx
let predicates = tcx.lookup_predicates(did);
clean::Function {
decl: decl,
generics: (t.generics, &predicates, subst::FnSpace).clean(cx),
generics: (t.generics, &predicates).clean(cx),
unsafety: style,
constness: constness,
abi: abi,
@ -209,7 +208,7 @@ fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
&[..] if variant.kind == ty::VariantKind::Tuple => doctree::Tuple,
_ => doctree::Plain,
},
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
generics: (t.generics, &predicates).clean(cx),
fields: variant.fields.clean(cx),
fields_stripped: false,
}
@ -222,7 +221,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
match t.ty.sty {
ty::TyEnum(edef, _) if !tcx.sess.cstore.is_typedef(did) => {
return clean::EnumItem(clean::Enum {
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
generics: (t.generics, &predicates).clean(cx),
variants_stripped: false,
variants: edef.variants.clean(cx),
})
@ -232,7 +231,7 @@ fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
clean::TypedefItem(clean::Typedef {
type_: t.ty.clean(cx),
generics: (t.generics, &predicates, subst::TypeSpace).clean(cx),
generics: (t.generics, &predicates).clean(cx),
}, false)
}
@ -393,9 +392,11 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
// because an associated type won't have generics on the LHS
let typedef = clean::Typedef {
type_: assoc_ty.ty.unwrap().clean(cx),
generics: (&ty::Generics::empty(),
&ty::GenericPredicates::empty(),
subst::TypeSpace).clean(cx)
generics: clean::Generics {
lifetimes: vec![],
type_params: vec![],
where_predicates: vec![]
}
};
Some(clean::Item {
name: Some(assoc_ty.name.clean(cx)),
@ -434,7 +435,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
provided_trait_methods: provided,
trait_: trait_,
for_: for_,
generics: (ty.generics, &predicates, subst::TypeSpace).clean(cx),
generics: (ty.generics, &predicates).clean(cx),
items: trait_items,
polarity: polarity.map(|p| { p.clean(cx) }),
}),

View File

@ -973,17 +973,16 @@ impl Clean<Generics> for hir::Generics {
}
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
&'a ty::GenericPredicates<'tcx>,
subst::ParamSpace) {
&'a ty::GenericPredicates<'tcx>) {
fn clean(&self, cx: &DocContext) -> Generics {
use self::WherePredicate as WP;
let (gens, preds, space) = *self;
let (gens, preds) = *self;
// Bounds in the type_params and lifetimes fields are repeated in the
// predicates field (see rustc_typeck::collect::ty_generics), so remove
// them.
let stripped_typarams = gens.types.get_slice(space).iter().filter_map(|tp| {
let stripped_typarams = gens.types.iter().filter_map(|tp| {
if tp.name == keywords::SelfType.name() {
assert_eq!(tp.index, 0);
None
@ -991,7 +990,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
Some(tp.clean(cx))
}
}).collect::<Vec<_>>();
let stripped_lifetimes = gens.regions.get_slice(space).iter().map(|rp| {
let stripped_lifetimes = gens.regions.iter().map(|rp| {
let mut srp = rp.clone();
srp.bounds = Vec::new();
srp.clean(cx)
@ -1359,8 +1358,7 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
predicates: self.predicates.predicates[method_start..].to_vec()
};
let generics = (self.generics, &method_predicates,
subst::FnSpace).clean(cx);
let generics = (self.generics, &method_predicates).clean(cx);
let mut decl = (self.def_id, &self.fty.sig).clean(cx);
match self.explicit_self {
ty::ExplicitSelfCategory::ByValue => {
@ -2929,7 +2927,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedType<'tcx> {
// applied to this associated type in question.
let def = cx.tcx().lookup_trait_def(did);
let predicates = cx.tcx().lookup_predicates(did);
let generics = (def.generics, &predicates, subst::TypeSpace).clean(cx);
let generics = (def.generics, &predicates).clean(cx);
generics.where_predicates.iter().filter_map(|pred| {
let (name, self_type, trait_, bounds) = match *pred {
WherePredicate::BoundPredicate {