Restructure AST so that the associated type definition carries
bounds like any other "type parameter".
This commit is contained in:
parent
01b81c0ebb
commit
319d778ed3
13 changed files with 105 additions and 98 deletions
|
@ -81,7 +81,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
|
||||||
e::IIForeignRef(i) => i.id,
|
e::IIForeignRef(i) => i.id,
|
||||||
e::IITraitItemRef(_, &ast::ProvidedMethod(ref m)) => m.id,
|
e::IITraitItemRef(_, &ast::ProvidedMethod(ref m)) => m.id,
|
||||||
e::IITraitItemRef(_, &ast::RequiredMethod(ref m)) => m.id,
|
e::IITraitItemRef(_, &ast::RequiredMethod(ref m)) => m.id,
|
||||||
e::IITraitItemRef(_, &ast::TypeTraitItem(ref ti)) => ti.id,
|
e::IITraitItemRef(_, &ast::TypeTraitItem(ref ti)) => ti.ty_param.id,
|
||||||
e::IIImplItemRef(_, &ast::MethodImplItem(ref m)) => m.id,
|
e::IIImplItemRef(_, &ast::MethodImplItem(ref m)) => m.id,
|
||||||
e::IIImplItemRef(_, &ast::TypeImplItem(ref ti)) => ti.id,
|
e::IIImplItemRef(_, &ast::TypeImplItem(ref ti)) => ti.id,
|
||||||
};
|
};
|
||||||
|
@ -156,7 +156,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
|
||||||
match *ti {
|
match *ti {
|
||||||
ast::ProvidedMethod(ref m) => m.pe_ident(),
|
ast::ProvidedMethod(ref m) => m.pe_ident(),
|
||||||
ast::RequiredMethod(ref ty_m) => ty_m.ident,
|
ast::RequiredMethod(ref ty_m) => ty_m.ident,
|
||||||
ast::TypeTraitItem(ref ti) => ti.ident,
|
ast::TypeTraitItem(ref ti) => ti.ty_param.ident,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ast::IIImplItem(_, ref m) => {
|
ast::IIImplItem(_, ref m) => {
|
||||||
|
|
|
@ -296,8 +296,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
||||||
self.exported_items.insert(m.id);
|
self.exported_items.insert(m.id);
|
||||||
}
|
}
|
||||||
ast::TypeTraitItem(ref t) => {
|
ast::TypeTraitItem(ref t) => {
|
||||||
debug!("typedef {}", t.id);
|
debug!("typedef {}", t.ty_param.id);
|
||||||
self.exported_items.insert(t.id);
|
self.exported_items.insert(t.ty_param.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1559,19 +1559,19 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
ast::TypeTraitItem(ref associated_type) => {
|
ast::TypeTraitItem(ref associated_type) => {
|
||||||
let def = DefAssociatedTy(local_def(
|
let def = DefAssociatedTy(local_def(
|
||||||
associated_type.id));
|
associated_type.ty_param.id));
|
||||||
|
|
||||||
let name_bindings =
|
let name_bindings =
|
||||||
self.add_child(associated_type.ident.name,
|
self.add_child(associated_type.ty_param.ident.name,
|
||||||
module_parent.clone(),
|
module_parent.clone(),
|
||||||
ForbidDuplicateTypesAndValues,
|
ForbidDuplicateTypesAndValues,
|
||||||
associated_type.span);
|
associated_type.ty_param.span);
|
||||||
// NB: not IMPORTABLE
|
// NB: not IMPORTABLE
|
||||||
name_bindings.define_type(def,
|
name_bindings.define_type(def,
|
||||||
associated_type.span,
|
associated_type.ty_param.span,
|
||||||
PUBLIC);
|
PUBLIC);
|
||||||
|
|
||||||
(associated_type.ident.name, TypeTraitItemKind)
|
(associated_type.ty_param.ident.name, TypeTraitItemKind)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4218,7 +4218,7 @@ impl<'a> Resolver<'a> {
|
||||||
impl_items.as_slice());
|
impl_items.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => {
|
ItemTrait(ref generics, ref unbound, ref bounds, ref trait_items) => {
|
||||||
// Create a new rib for the self type.
|
// Create a new rib for the self type.
|
||||||
let mut self_type_rib = Rib::new(ItemRibKind);
|
let mut self_type_rib = Rib::new(ItemRibKind);
|
||||||
|
|
||||||
|
@ -4246,13 +4246,13 @@ impl<'a> Resolver<'a> {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
for method in (*methods).iter() {
|
for trait_item in (*trait_items).iter() {
|
||||||
// Create a new rib for the method-specific type
|
// Create a new rib for the trait_item-specific type
|
||||||
// parameters.
|
// parameters.
|
||||||
//
|
//
|
||||||
// FIXME #4951: Do we need a node ID here?
|
// FIXME #4951: Do we need a node ID here?
|
||||||
|
|
||||||
match *method {
|
match *trait_item {
|
||||||
ast::RequiredMethod(ref ty_m) => {
|
ast::RequiredMethod(ref ty_m) => {
|
||||||
this.with_type_parameter_rib
|
this.with_type_parameter_rib
|
||||||
(HasTypeParameters(&ty_m.generics,
|
(HasTypeParameters(&ty_m.generics,
|
||||||
|
@ -4287,8 +4287,9 @@ impl<'a> Resolver<'a> {
|
||||||
ProvidedMethod(m.id)),
|
ProvidedMethod(m.id)),
|
||||||
&**m)
|
&**m)
|
||||||
}
|
}
|
||||||
ast::TypeTraitItem(_) => {
|
ast::TypeTraitItem(ref data) => {
|
||||||
visit::walk_trait_item(this, method);
|
this.resolve_type_parameter(&data.ty_param);
|
||||||
|
visit::walk_trait_item(this, trait_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4477,6 +4478,12 @@ impl<'a> Resolver<'a> {
|
||||||
fn resolve_type_parameters(&mut self,
|
fn resolve_type_parameters(&mut self,
|
||||||
type_parameters: &OwnedSlice<TyParam>) {
|
type_parameters: &OwnedSlice<TyParam>) {
|
||||||
for type_parameter in type_parameters.iter() {
|
for type_parameter in type_parameters.iter() {
|
||||||
|
self.resolve_type_parameter(type_parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_type_parameter(&mut self,
|
||||||
|
type_parameter: &TyParam) {
|
||||||
for bound in type_parameter.bounds.iter() {
|
for bound in type_parameter.bounds.iter() {
|
||||||
self.resolve_type_parameter_bound(type_parameter.id, bound,
|
self.resolve_type_parameter_bound(type_parameter.id, bound,
|
||||||
TraitBoundingTypeParameter);
|
TraitBoundingTypeParameter);
|
||||||
|
@ -4492,7 +4499,6 @@ impl<'a> Resolver<'a> {
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_type_parameter_bounds(&mut self,
|
fn resolve_type_parameter_bounds(&mut self,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl<'v> Visitor<'v> for Annotator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeTraitItem(ref typedef) => (typedef.id, &typedef.attrs),
|
TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs),
|
||||||
};
|
};
|
||||||
self.annotate(id, attrs, |v| visit::walk_trait_item(v, t));
|
self.annotate(id, attrs, |v| visit::walk_trait_item(v, t));
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ fn collect_trait_methods(ccx: &CrateCtxt,
|
||||||
&*m.pe_fn_decl())
|
&*m.pe_fn_decl())
|
||||||
}
|
}
|
||||||
ast::TypeTraitItem(ref at) => {
|
ast::TypeTraitItem(ref at) => {
|
||||||
tcx.sess.span_bug(at.span,
|
tcx.sess.span_bug(at.ty_param.span,
|
||||||
"there shouldn't \
|
"there shouldn't \
|
||||||
be a type trait \
|
be a type trait \
|
||||||
item here")
|
item here")
|
||||||
|
@ -315,9 +315,9 @@ fn collect_trait_methods(ccx: &CrateCtxt,
|
||||||
ast::TypeTraitItem(ref ast_associated_type) => {
|
ast::TypeTraitItem(ref ast_associated_type) => {
|
||||||
let trait_did = local_def(trait_id);
|
let trait_did = local_def(trait_id);
|
||||||
let associated_type = ty::AssociatedType {
|
let associated_type = ty::AssociatedType {
|
||||||
name: ast_associated_type.ident.name,
|
name: ast_associated_type.ty_param.ident.name,
|
||||||
vis: ast::Public,
|
vis: ast::Public,
|
||||||
def_id: local_def(ast_associated_type.id),
|
def_id: local_def(ast_associated_type.ty_param.id),
|
||||||
container: TraitContainer(trait_did),
|
container: TraitContainer(trait_did),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ fn collect_trait_methods(ccx: &CrateCtxt,
|
||||||
method.id))
|
method.id))
|
||||||
}
|
}
|
||||||
ast::TypeTraitItem(ref typedef) => {
|
ast::TypeTraitItem(ref typedef) => {
|
||||||
ty::TypeTraitItemId(local_def(typedef.id))
|
ty::TypeTraitItemId(local_def(typedef.ty_param.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).collect());
|
}).collect());
|
||||||
|
@ -463,12 +463,12 @@ fn convert_associated_type(ccx: &CrateCtxt,
|
||||||
.get_slice(subst::TypeSpace)
|
.get_slice(subst::TypeSpace)
|
||||||
.iter()
|
.iter()
|
||||||
.find(|def| {
|
.find(|def| {
|
||||||
def.def_id == local_def(associated_type.id)
|
def.def_id == local_def(associated_type.ty_param.id)
|
||||||
});
|
});
|
||||||
let type_parameter_def = match type_parameter_def {
|
let type_parameter_def = match type_parameter_def {
|
||||||
Some(type_parameter_def) => type_parameter_def,
|
Some(type_parameter_def) => type_parameter_def,
|
||||||
None => {
|
None => {
|
||||||
ccx.tcx().sess.span_bug(associated_type.span,
|
ccx.tcx().sess.span_bug(associated_type.ty_param.span,
|
||||||
"`convert_associated_type()` didn't find \
|
"`convert_associated_type()` didn't find \
|
||||||
a type parameter ID corresponding to \
|
a type parameter ID corresponding to \
|
||||||
this type")
|
this type")
|
||||||
|
@ -477,18 +477,18 @@ fn convert_associated_type(ccx: &CrateCtxt,
|
||||||
let param_type = ty::mk_param(ccx.tcx,
|
let param_type = ty::mk_param(ccx.tcx,
|
||||||
subst::TypeSpace,
|
subst::TypeSpace,
|
||||||
type_parameter_def.index,
|
type_parameter_def.index,
|
||||||
local_def(associated_type.id));
|
local_def(associated_type.ty_param.id));
|
||||||
ccx.tcx.tcache.borrow_mut().insert(local_def(associated_type.id),
|
ccx.tcx.tcache.borrow_mut().insert(local_def(associated_type.ty_param.id),
|
||||||
Polytype {
|
Polytype {
|
||||||
generics: ty::Generics::empty(),
|
generics: ty::Generics::empty(),
|
||||||
ty: param_type,
|
ty: param_type,
|
||||||
});
|
});
|
||||||
write_ty_to_tcx(ccx.tcx, associated_type.id, param_type);
|
write_ty_to_tcx(ccx.tcx, associated_type.ty_param.id, param_type);
|
||||||
|
|
||||||
let associated_type = Rc::new(ty::AssociatedType {
|
let associated_type = Rc::new(ty::AssociatedType {
|
||||||
name: associated_type.ident.name,
|
name: associated_type.ty_param.ident.name,
|
||||||
vis: ast::Public,
|
vis: ast::Public,
|
||||||
def_id: local_def(associated_type.id),
|
def_id: local_def(associated_type.ty_param.id),
|
||||||
container: TraitContainer(trait_def.trait_ref.def_id),
|
container: TraitContainer(trait_def.trait_ref.def_id),
|
||||||
});
|
});
|
||||||
ccx.tcx
|
ccx.tcx
|
||||||
|
@ -978,7 +978,7 @@ impl<'a,'tcx> AstConv<'tcx> for TraitMethodCtxt<'a,'tcx> {
|
||||||
match *item {
|
match *item {
|
||||||
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
|
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
|
||||||
ast::TypeTraitItem(ref item) => {
|
ast::TypeTraitItem(ref item) => {
|
||||||
if local_def(item.id) == associated_type_id {
|
if local_def(item.ty_param.id) == associated_type_id {
|
||||||
return ty::mk_param(self.tcx(),
|
return ty::mk_param(self.tcx(),
|
||||||
subst::TypeSpace,
|
subst::TypeSpace,
|
||||||
index,
|
index,
|
||||||
|
@ -1480,7 +1480,7 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
|
||||||
types.push(ty::mk_param(ccx.tcx,
|
types.push(ty::mk_param(ccx.tcx,
|
||||||
subst::TypeSpace,
|
subst::TypeSpace,
|
||||||
index,
|
index,
|
||||||
local_def(trait_item.id)))
|
local_def(trait_item.ty_param.id)))
|
||||||
}
|
}
|
||||||
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
|
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
|
||||||
}
|
}
|
||||||
|
@ -1630,11 +1630,11 @@ fn ty_of_trait_item(ccx: &CrateCtxt, trait_item: &ast::TraitItem)
|
||||||
"ty_of_trait_item() on provided method")
|
"ty_of_trait_item() on provided method")
|
||||||
}
|
}
|
||||||
ast::TypeTraitItem(ref associated_type) => {
|
ast::TypeTraitItem(ref associated_type) => {
|
||||||
let parent = ccx.tcx.map.get_parent(associated_type.id);
|
let parent = ccx.tcx.map.get_parent(associated_type.ty_param.id);
|
||||||
let trait_def = match ccx.tcx.map.get(parent) {
|
let trait_def = match ccx.tcx.map.get(parent) {
|
||||||
ast_map::NodeItem(item) => trait_def_of_item(ccx, &*item),
|
ast_map::NodeItem(item) => trait_def_of_item(ccx, &*item),
|
||||||
_ => {
|
_ => {
|
||||||
ccx.tcx.sess.span_bug(associated_type.span,
|
ccx.tcx.sess.span_bug(associated_type.ty_param.span,
|
||||||
"associated type's parent wasn't \
|
"associated type's parent wasn't \
|
||||||
an item?!")
|
an item?!")
|
||||||
}
|
}
|
||||||
|
@ -1680,8 +1680,8 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
|
||||||
let def = ty::TypeParameterDef {
|
let def = ty::TypeParameterDef {
|
||||||
space: subst::TypeSpace,
|
space: subst::TypeSpace,
|
||||||
index: generics.types.len(subst::TypeSpace),
|
index: generics.types.len(subst::TypeSpace),
|
||||||
name: associated_type.ident.name,
|
name: associated_type.ty_param.ident.name,
|
||||||
def_id: local_def(associated_type.id),
|
def_id: local_def(associated_type.ty_param.id),
|
||||||
bounds: ty::ParamBounds {
|
bounds: ty::ParamBounds {
|
||||||
builtin_bounds: ty::empty_builtin_bounds(),
|
builtin_bounds: ty::empty_builtin_bounds(),
|
||||||
trait_bounds: Vec::new(),
|
trait_bounds: Vec::new(),
|
||||||
|
@ -1690,7 +1690,7 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
|
||||||
associated_with: Some(local_def(trait_id)),
|
associated_with: Some(local_def(trait_id)),
|
||||||
default: None,
|
default: None,
|
||||||
};
|
};
|
||||||
ccx.tcx.ty_param_defs.borrow_mut().insert(associated_type.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);
|
||||||
}
|
}
|
||||||
|
@ -1810,9 +1810,9 @@ fn ensure_associated_types<'tcx,AC>(this: &AC, trait_id: ast::DefId)
|
||||||
ast::ProvidedMethod(_) => {}
|
ast::ProvidedMethod(_) => {}
|
||||||
ast::TypeTraitItem(ref associated_type) => {
|
ast::TypeTraitItem(ref associated_type) => {
|
||||||
let info = ty::AssociatedTypeInfo {
|
let info = ty::AssociatedTypeInfo {
|
||||||
def_id: local_def(associated_type.id),
|
def_id: local_def(associated_type.ty_param.id),
|
||||||
index: index,
|
index: index,
|
||||||
name: associated_type.ident.name,
|
name: associated_type.ty_param.ident.name,
|
||||||
};
|
};
|
||||||
result.push(info);
|
result.push(info);
|
||||||
index += 1;
|
index += 1;
|
||||||
|
|
|
@ -861,10 +861,8 @@ pub enum ImplItem {
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||||
pub struct AssociatedType {
|
pub struct AssociatedType {
|
||||||
pub id: NodeId,
|
|
||||||
pub span: Span,
|
|
||||||
pub ident: Ident,
|
|
||||||
pub attrs: Vec<Attribute>,
|
pub attrs: Vec<Attribute>,
|
||||||
|
pub ty_param: TyParam,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||||
|
|
|
@ -405,7 +405,9 @@ impl<'ast> Map<'ast> {
|
||||||
MethMac(_) => panic!("no path elem for {}", node),
|
MethMac(_) => panic!("no path elem for {}", node),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TypeTraitItem(ref m) => PathName(m.ident.name),
|
TypeTraitItem(ref m) => {
|
||||||
|
PathName(m.ty_param.ident.name)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
NodeVariant(v) => PathName(v.node.name.name),
|
NodeVariant(v) => PathName(v.node.name.name),
|
||||||
_ => panic!("no path elem for {}", node)
|
_ => panic!("no path elem for {}", node)
|
||||||
|
@ -510,7 +512,7 @@ impl<'ast> Map<'ast> {
|
||||||
match *trait_method {
|
match *trait_method {
|
||||||
RequiredMethod(ref type_method) => type_method.span,
|
RequiredMethod(ref type_method) => type_method.span,
|
||||||
ProvidedMethod(ref method) => method.span,
|
ProvidedMethod(ref method) => method.span,
|
||||||
TypeTraitItem(ref typedef) => typedef.span,
|
TypeTraitItem(ref typedef) => typedef.ty_param.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(NodeImplItem(ref impl_item)) => {
|
Some(NodeImplItem(ref impl_item)) => {
|
||||||
|
@ -650,7 +652,7 @@ impl Named for TraitItem {
|
||||||
match *self {
|
match *self {
|
||||||
RequiredMethod(ref tm) => tm.ident.name,
|
RequiredMethod(ref tm) => tm.ident.name,
|
||||||
ProvidedMethod(ref m) => m.name(),
|
ProvidedMethod(ref m) => m.name(),
|
||||||
TypeTraitItem(ref at) => at.ident.name,
|
TypeTraitItem(ref at) => at.ty_param.ident.name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -783,7 +785,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||||
self.insert(m.id, NodeTraitItem(tm));
|
self.insert(m.id, NodeTraitItem(tm));
|
||||||
}
|
}
|
||||||
TypeTraitItem(ref typ) => {
|
TypeTraitItem(ref typ) => {
|
||||||
self.insert(typ.id, NodeTraitItem(tm));
|
self.insert(typ.ty_param.id, NodeTraitItem(tm));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -976,7 +978,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
|
||||||
let trait_item_id = match *trait_item {
|
let trait_item_id = match *trait_item {
|
||||||
ProvidedMethod(ref m) => m.id,
|
ProvidedMethod(ref m) => m.id,
|
||||||
RequiredMethod(ref m) => m.id,
|
RequiredMethod(ref m) => m.id,
|
||||||
TypeTraitItem(ref ty) => ty.id,
|
TypeTraitItem(ref ty) => ty.ty_param.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
collector.insert(trait_item_id, NodeTraitItem(trait_item));
|
collector.insert(trait_item_id, NodeTraitItem(trait_item));
|
||||||
|
@ -1080,7 +1082,7 @@ fn node_id_to_string(map: &Map, id: NodeId) -> String {
|
||||||
}
|
}
|
||||||
TypeTraitItem(ref t) => {
|
TypeTraitItem(ref t) => {
|
||||||
format!("type item {} in {} (id={})",
|
format!("type item {} in {} (id={})",
|
||||||
token::get_ident(t.ident),
|
token::get_ident(t.ty_param.ident),
|
||||||
map.path_to_string(id),
|
map.path_to_string(id),
|
||||||
id)
|
id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -525,7 +525,7 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
||||||
match *tm {
|
match *tm {
|
||||||
ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
|
ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
|
||||||
ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
|
ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
|
||||||
ast::TypeTraitItem(ref typ) => self.operation.visit_id(typ.id),
|
ast::TypeTraitItem(ref typ) => self.operation.visit_id(typ.ty_param.id),
|
||||||
}
|
}
|
||||||
visit::walk_trait_item(self, tm);
|
visit::walk_trait_item(self, tm);
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
|
||||||
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
|
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
|
||||||
ast::TypeTraitItem(ref ti) => {
|
ast::TypeTraitItem(ref ti) => {
|
||||||
self.gate_feature("associated_types",
|
self.gate_feature("associated_types",
|
||||||
ti.span,
|
ti.ty_param.span,
|
||||||
"associated types are experimental")
|
"associated types are experimental")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -793,19 +793,16 @@ pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T)
|
||||||
|
|
||||||
pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T)
|
pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T)
|
||||||
-> AssociatedType
|
-> AssociatedType
|
||||||
where T: Folder {
|
where T: Folder
|
||||||
let new_id = folder.new_id(at.id);
|
{
|
||||||
let new_span = folder.new_span(at.span);
|
|
||||||
let new_ident = folder.fold_ident(at.ident);
|
|
||||||
let new_attrs = at.attrs
|
let new_attrs = at.attrs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|attr| folder.fold_attribute((*attr).clone()))
|
.map(|attr| folder.fold_attribute((*attr).clone()))
|
||||||
.collect();
|
.collect();
|
||||||
|
let new_param = folder.fold_ty_param(at.ty_param);
|
||||||
ast::AssociatedType {
|
ast::AssociatedType {
|
||||||
ident: new_ident,
|
|
||||||
attrs: new_attrs,
|
attrs: new_attrs,
|
||||||
id: new_id,
|
ty_param: new_param,
|
||||||
span: new_span,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1229,16 +1229,13 @@ impl<'a> Parser<'a> {
|
||||||
/// Parses `type Foo;` in a trait declaration only. The `type` keyword has
|
/// Parses `type Foo;` in a trait declaration only. The `type` keyword has
|
||||||
/// already been parsed.
|
/// already been parsed.
|
||||||
fn parse_associated_type(&mut self, attrs: Vec<Attribute>)
|
fn parse_associated_type(&mut self, attrs: Vec<Attribute>)
|
||||||
-> AssociatedType {
|
-> AssociatedType
|
||||||
let lo = self.span.lo;
|
{
|
||||||
let ident = self.parse_ident();
|
let ty_param = self.parse_ty_param();
|
||||||
let hi = self.span.hi;
|
|
||||||
self.expect(&token::Semi);
|
self.expect(&token::Semi);
|
||||||
AssociatedType {
|
AssociatedType {
|
||||||
id: ast::DUMMY_NODE_ID,
|
|
||||||
span: mk_sp(lo, hi),
|
|
||||||
ident: ident,
|
|
||||||
attrs: attrs,
|
attrs: attrs,
|
||||||
|
ty_param: ty_param,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -818,9 +818,11 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
|
fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
|
||||||
-> IoResult<()> {
|
-> IoResult<()>
|
||||||
|
{
|
||||||
|
try!(self.print_outer_attributes(typedef.attrs[]));
|
||||||
try!(self.word_space("type"));
|
try!(self.word_space("type"));
|
||||||
try!(self.print_ident(typedef.ident));
|
try!(self.print_ty_param(&typedef.ty_param));
|
||||||
word(&mut self.s, ";")
|
word(&mut self.s, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2434,23 +2436,7 @@ impl<'a> State<'a> {
|
||||||
} else {
|
} else {
|
||||||
let idx = idx - generics.lifetimes.len();
|
let idx = idx - generics.lifetimes.len();
|
||||||
let param = generics.ty_params.get(idx);
|
let param = generics.ty_params.get(idx);
|
||||||
match param.unbound {
|
s.print_ty_param(param)
|
||||||
Some(TraitTyParamBound(ref tref)) => {
|
|
||||||
try!(s.print_trait_ref(tref));
|
|
||||||
try!(s.word_space("?"));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
try!(s.print_ident(param.ident));
|
|
||||||
try!(s.print_bounds(":", ¶m.bounds));
|
|
||||||
match param.default {
|
|
||||||
Some(ref default) => {
|
|
||||||
try!(space(&mut s.s));
|
|
||||||
try!(s.word_space("="));
|
|
||||||
s.print_type(&**default)
|
|
||||||
}
|
|
||||||
_ => Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -2458,6 +2444,26 @@ impl<'a> State<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> {
|
||||||
|
match param.unbound {
|
||||||
|
Some(TraitTyParamBound(ref tref)) => {
|
||||||
|
try!(self.print_trait_ref(tref));
|
||||||
|
try!(self.word_space("?"));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
try!(self.print_ident(param.ident));
|
||||||
|
try!(self.print_bounds(":", ¶m.bounds));
|
||||||
|
match param.default {
|
||||||
|
Some(ref default) => {
|
||||||
|
try!(space(&mut self.s));
|
||||||
|
try!(self.word_space("="));
|
||||||
|
self.print_type(&**default)
|
||||||
|
}
|
||||||
|
_ => Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print_where_clause(&mut self, generics: &ast::Generics)
|
pub fn print_where_clause(&mut self, generics: &ast::Generics)
|
||||||
-> IoResult<()> {
|
-> IoResult<()> {
|
||||||
if generics.where_clause.predicates.len() == 0 {
|
if generics.where_clause.predicates.len() == 0 {
|
||||||
|
|
|
@ -596,7 +596,8 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_method: &'v Tr
|
||||||
RequiredMethod(ref method_type) => visitor.visit_ty_method(method_type),
|
RequiredMethod(ref method_type) => visitor.visit_ty_method(method_type),
|
||||||
ProvidedMethod(ref method) => walk_method_helper(visitor, &**method),
|
ProvidedMethod(ref method) => walk_method_helper(visitor, &**method),
|
||||||
TypeTraitItem(ref associated_type) => {
|
TypeTraitItem(ref associated_type) => {
|
||||||
visitor.visit_ident(associated_type.span, associated_type.ident)
|
visitor.visit_ident(associated_type.ty_param.span,
|
||||||
|
associated_type.ty_param.ident)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue