提交 94d142b5 编写于 作者: N Niko Matsakis

Add in the bounds into the typeparameterdefs for assoc types

上级 319d778e
...@@ -1661,35 +1661,30 @@ fn ty_generics_for_type(ccx: &CrateCtxt, ...@@ -1661,35 +1661,30 @@ fn ty_generics_for_type(ccx: &CrateCtxt,
fn ty_generics_for_trait(ccx: &CrateCtxt, fn ty_generics_for_trait(ccx: &CrateCtxt,
trait_id: ast::NodeId, trait_id: ast::NodeId,
substs: &subst::Substs, substs: &subst::Substs,
generics: &ast::Generics, ast_generics: &ast::Generics,
items: &[ast::TraitItem]) items: &[ast::TraitItem])
-> ty::Generics { -> ty::Generics {
let mut generics = let mut generics =
ty_generics(ccx, ty_generics(ccx,
subst::TypeSpace, subst::TypeSpace,
generics.lifetimes.as_slice(), ast_generics.lifetimes.as_slice(),
generics.ty_params.as_slice(), ast_generics.ty_params.as_slice(),
ty::Generics::empty(), ty::Generics::empty(),
&generics.where_clause, &ast_generics.where_clause,
DontCreateTypeParametersForAssociatedTypes); DontCreateTypeParametersForAssociatedTypes);
// Add in type parameters for any associated types. // Add in type parameters for any associated types.
for item in items.iter() { for item in items.iter() {
match *item { match *item {
ast::TypeTraitItem(ref associated_type) => { ast::TypeTraitItem(ref associated_type) => {
let def = ty::TypeParameterDef { let def =
space: subst::TypeSpace, get_or_create_type_parameter_def(
index: generics.types.len(subst::TypeSpace), ccx,
name: associated_type.ty_param.ident.name, subst::TypeSpace,
def_id: local_def(associated_type.ty_param.id), &associated_type.ty_param,
bounds: ty::ParamBounds { generics.types.len(subst::TypeSpace),
builtin_bounds: ty::empty_builtin_bounds(), &ast_generics.where_clause,
trait_bounds: Vec::new(), Some(local_def(trait_id)));
region_bounds: Vec::new(),
},
associated_with: Some(local_def(trait_id)),
default: None,
};
ccx.tcx.ty_param_defs.borrow_mut().insert(associated_type.ty_param.id, ccx.tcx.ty_param_defs.borrow_mut().insert(associated_type.ty_param.id,
def.clone()); def.clone());
generics.types.push(subst::TypeSpace, def); generics.types.push(subst::TypeSpace, def);
...@@ -1960,7 +1955,8 @@ fn ty_generics<'tcx,AC>(this: &AC, ...@@ -1960,7 +1955,8 @@ fn ty_generics<'tcx,AC>(this: &AC,
space, space,
param, param,
i, i,
where_clause); where_clause,
None);
debug!("ty_generics: def for type param: {}, {}", debug!("ty_generics: def for type param: {}, {}",
def.repr(this.tcx()), def.repr(this.tcx()),
space); space);
...@@ -1980,63 +1976,64 @@ fn ty_generics<'tcx,AC>(this: &AC, ...@@ -1980,63 +1976,64 @@ fn ty_generics<'tcx,AC>(this: &AC,
} }
return result; return result;
}
fn get_or_create_type_parameter_def<'tcx,AC>( fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC,
this: &AC, space: subst::ParamSpace,
space: subst::ParamSpace, param: &ast::TyParam,
param: &ast::TyParam, index: uint,
index: uint, where_clause: &ast::WhereClause,
where_clause: &ast::WhereClause) associated_with: Option<ast::DefId>)
-> ty::TypeParameterDef -> ty::TypeParameterDef
where AC: AstConv<'tcx> { where AC: AstConv<'tcx>
match this.tcx().ty_param_defs.borrow().find(&param.id) { {
Some(d) => { return (*d).clone(); } match this.tcx().ty_param_defs.borrow().find(&param.id) {
None => { } Some(d) => { return (*d).clone(); }
} None => { }
}
let param_ty = ty::ParamTy::new(space, index, local_def(param.id));
let bounds = compute_bounds(this, let param_ty = ty::ParamTy::new(space, index, local_def(param.id));
param.ident.name, let bounds = compute_bounds(this,
param_ty, param.ident.name,
param.bounds.as_slice(), param_ty,
&param.unbound, param.bounds.as_slice(),
param.span, &param.unbound,
where_clause); param.span,
let default = match param.default { where_clause);
None => None, let default = match param.default {
Some(ref path) => { None => None,
let ty = ast_ty_to_ty(this, &ExplicitRscope, &**path); Some(ref path) => {
let cur_idx = index; let ty = ast_ty_to_ty(this, &ExplicitRscope, &**path);
let cur_idx = index;
ty::walk_ty(ty, |t| {
match ty::get(t).sty { ty::walk_ty(ty, |t| {
ty::ty_param(p) => if p.idx > cur_idx { match ty::get(t).sty {
ty::ty_param(p) => if p.idx > cur_idx {
span_err!(this.tcx().sess, path.span, E0128, span_err!(this.tcx().sess, path.span, E0128,
"type parameters with a default cannot use \ "type parameters with a default cannot use \
forward declared identifiers"); forward declared identifiers");
}, },
_ => {} _ => {}
} }
}); });
Some(ty) Some(ty)
} }
}; };
let def = ty::TypeParameterDef { let def = ty::TypeParameterDef {
space: space, space: space,
index: index, index: index,
name: param.ident.name, name: param.ident.name,
def_id: local_def(param.id), def_id: local_def(param.id),
associated_with: None, associated_with: associated_with,
bounds: bounds, bounds: bounds,
default: default default: default
}; };
this.tcx().ty_param_defs.borrow_mut().insert(param.id, def.clone()); this.tcx().ty_param_defs.borrow_mut().insert(param.id, def.clone());
def def
}
} }
fn compute_bounds<'tcx,AC>(this: &AC, fn compute_bounds<'tcx,AC>(this: &AC,
......
...@@ -2203,12 +2203,12 @@ fn clean(&self, _: &DocContext) -> Stability { ...@@ -2203,12 +2203,12 @@ fn clean(&self, _: &DocContext) -> Stability {
impl Clean<Item> for ast::AssociatedType { impl Clean<Item> for ast::AssociatedType {
fn clean(&self, cx: &DocContext) -> Item { fn clean(&self, cx: &DocContext) -> Item {
Item { Item {
source: self.span.clean(cx), source: self.ty_param.span.clean(cx),
name: Some(self.ident.clean(cx)), name: Some(self.ty_param.ident.clean(cx)),
attrs: self.attrs.clean(cx), attrs: self.attrs.clean(cx),
inner: AssociatedTypeItem, inner: AssociatedTypeItem,
visibility: None, visibility: None,
def_id: ast_util::local_def(self.id), def_id: ast_util::local_def(self.ty_param.id),
stability: None, stability: None,
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册