提交 319d778e 编写于 作者: N Niko Matsakis

Restructure AST so that the associated type definition carries

bounds like any other "type parameter".
上级 01b81c0e
......@@ -81,7 +81,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
e::IIForeignRef(i) => i.id,
e::IITraitItemRef(_, &ast::ProvidedMethod(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::TypeImplItem(ref ti)) => ti.id,
};
......@@ -156,7 +156,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
match *ti {
ast::ProvidedMethod(ref m) => m.pe_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) => {
......
......@@ -296,8 +296,8 @@ fn visit_item(&mut self, item: &ast::Item) {
self.exported_items.insert(m.id);
}
ast::TypeTraitItem(ref t) => {
debug!("typedef {}", t.id);
self.exported_items.insert(t.id);
debug!("typedef {}", t.ty_param.id);
self.exported_items.insert(t.ty_param.id);
}
}
}
......
......@@ -1559,19 +1559,19 @@ fn build_reduced_graph_for_item(&mut self,
}
ast::TypeTraitItem(ref associated_type) => {
let def = DefAssociatedTy(local_def(
associated_type.id));
associated_type.ty_param.id));
let name_bindings =
self.add_child(associated_type.ident.name,
self.add_child(associated_type.ty_param.ident.name,
module_parent.clone(),
ForbidDuplicateTypesAndValues,
associated_type.span);
associated_type.ty_param.span);
// NB: not IMPORTABLE
name_bindings.define_type(def,
associated_type.span,
associated_type.ty_param.span,
PUBLIC);
(associated_type.ident.name, TypeTraitItemKind)
(associated_type.ty_param.ident.name, TypeTraitItemKind)
}
};
......@@ -4218,7 +4218,7 @@ fn resolve_item(&mut self, item: &Item) {
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.
let mut self_type_rib = Rib::new(ItemRibKind);
......@@ -4246,13 +4246,13 @@ fn resolve_item(&mut self, item: &Item) {
_ => {}
}
for method in (*methods).iter() {
// Create a new rib for the method-specific type
for trait_item in (*trait_items).iter() {
// Create a new rib for the trait_item-specific type
// parameters.
//
// FIXME #4951: Do we need a node ID here?
match *method {
match *trait_item {
ast::RequiredMethod(ref ty_m) => {
this.with_type_parameter_rib
(HasTypeParameters(&ty_m.generics,
......@@ -4287,8 +4287,9 @@ fn resolve_item(&mut self, item: &Item) {
ProvidedMethod(m.id)),
&**m)
}
ast::TypeTraitItem(_) => {
visit::walk_trait_item(this, method);
ast::TypeTraitItem(ref data) => {
this.resolve_type_parameter(&data.ty_param);
visit::walk_trait_item(this, trait_item);
}
}
}
......@@ -4477,20 +4478,25 @@ fn resolve_function(&mut self,
fn resolve_type_parameters(&mut self,
type_parameters: &OwnedSlice<TyParam>) {
for type_parameter in type_parameters.iter() {
for bound in type_parameter.bounds.iter() {
self.resolve_type_parameter_bound(type_parameter.id, bound,
TraitBoundingTypeParameter);
}
match &type_parameter.unbound {
&Some(ref unbound) =>
self.resolve_type_parameter_bound(
type_parameter.id, unbound, TraitBoundingTypeParameter),
&None => {}
}
match type_parameter.default {
Some(ref ty) => self.resolve_type(&**ty),
None => {}
}
self.resolve_type_parameter(type_parameter);
}
}
fn resolve_type_parameter(&mut self,
type_parameter: &TyParam) {
for bound in type_parameter.bounds.iter() {
self.resolve_type_parameter_bound(type_parameter.id, bound,
TraitBoundingTypeParameter);
}
match &type_parameter.unbound {
&Some(ref unbound) =>
self.resolve_type_parameter_bound(
type_parameter.id, unbound, TraitBoundingTypeParameter),
&None => {}
}
match type_parameter.default {
Some(ref ty) => self.resolve_type(&**ty),
None => {}
}
}
......@@ -4577,14 +4583,14 @@ fn resolve_trait_reference(&mut self,
self.resolve_error(trait_reference.path.span,
format!("`{}` is not a trait",
self.path_names_to_string(
&trait_reference.path)));
&trait_reference.path)));
// If it's a typedef, give a note
match def {
DefTy(..) => {
self.session.span_note(
trait_reference.path.span,
format!("`type` aliases cannot \
trait_reference.path.span,
format!("`type` aliases cannot \
be used for traits")
.as_slice());
}
......
......@@ -86,7 +86,7 @@ fn visit_trait_item(&mut self, t: &TraitItem) {
}
}
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));
}
......
......@@ -298,7 +298,7 @@ fn collect_trait_methods(ccx: &CrateCtxt,
&*m.pe_fn_decl())
}
ast::TypeTraitItem(ref at) => {
tcx.sess.span_bug(at.span,
tcx.sess.span_bug(at.ty_param.span,
"there shouldn't \
be a type trait \
item here")
......@@ -315,9 +315,9 @@ fn collect_trait_methods(ccx: &CrateCtxt,
ast::TypeTraitItem(ref ast_associated_type) => {
let trait_did = local_def(trait_id);
let associated_type = ty::AssociatedType {
name: ast_associated_type.ident.name,
name: ast_associated_type.ty_param.ident.name,
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),
};
......@@ -345,7 +345,7 @@ fn collect_trait_methods(ccx: &CrateCtxt,
method.id))
}
ast::TypeTraitItem(ref typedef) => {
ty::TypeTraitItemId(local_def(typedef.id))
ty::TypeTraitItemId(local_def(typedef.ty_param.id))
}
}
}).collect());
......@@ -463,12 +463,12 @@ fn convert_associated_type(ccx: &CrateCtxt,
.get_slice(subst::TypeSpace)
.iter()
.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 {
Some(type_parameter_def) => type_parameter_def,
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 \
a type parameter ID corresponding to \
this type")
......@@ -477,18 +477,18 @@ fn convert_associated_type(ccx: &CrateCtxt,
let param_type = ty::mk_param(ccx.tcx,
subst::TypeSpace,
type_parameter_def.index,
local_def(associated_type.id));
ccx.tcx.tcache.borrow_mut().insert(local_def(associated_type.id),
local_def(associated_type.ty_param.id));
ccx.tcx.tcache.borrow_mut().insert(local_def(associated_type.ty_param.id),
Polytype {
generics: ty::Generics::empty(),
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 {
name: associated_type.ident.name,
name: associated_type.ty_param.ident.name,
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),
});
ccx.tcx
......@@ -978,7 +978,7 @@ fn associated_type_binding(&self,
match *item {
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
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(),
subst::TypeSpace,
index,
......@@ -1480,7 +1480,7 @@ fn mk_trait_substs(ccx: &CrateCtxt,
types.push(ty::mk_param(ccx.tcx,
subst::TypeSpace,
index,
local_def(trait_item.id)))
local_def(trait_item.ty_param.id)))
}
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")
}
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) {
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 \
an item?!")
}
......@@ -1680,8 +1680,8 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
let def = ty::TypeParameterDef {
space: subst::TypeSpace,
index: generics.types.len(subst::TypeSpace),
name: associated_type.ident.name,
def_id: local_def(associated_type.id),
name: associated_type.ty_param.ident.name,
def_id: local_def(associated_type.ty_param.id),
bounds: ty::ParamBounds {
builtin_bounds: ty::empty_builtin_bounds(),
trait_bounds: Vec::new(),
......@@ -1690,7 +1690,7 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
associated_with: Some(local_def(trait_id)),
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());
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::TypeTraitItem(ref associated_type) => {
let info = ty::AssociatedTypeInfo {
def_id: local_def(associated_type.id),
def_id: local_def(associated_type.ty_param.id),
index: index,
name: associated_type.ident.name,
name: associated_type.ty_param.ident.name,
};
result.push(info);
index += 1;
......
......@@ -861,10 +861,8 @@ pub enum ImplItem {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct AssociatedType {
pub id: NodeId,
pub span: Span,
pub ident: Ident,
pub attrs: Vec<Attribute>,
pub ty_param: TyParam,
}
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
......
......@@ -405,7 +405,9 @@ pub fn get_path_elem(&self, id: NodeId) -> PathElem {
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),
_ => panic!("no path elem for {}", node)
......@@ -510,7 +512,7 @@ pub fn opt_span(&self, id: NodeId) -> Option<Span> {
match *trait_method {
RequiredMethod(ref type_method) => type_method.span,
ProvidedMethod(ref method) => method.span,
TypeTraitItem(ref typedef) => typedef.span,
TypeTraitItem(ref typedef) => typedef.ty_param.span,
}
}
Some(NodeImplItem(ref impl_item)) => {
......@@ -650,7 +652,7 @@ fn name(&self) -> Name {
match *self {
RequiredMethod(ref tm) => tm.ident.name,
ProvidedMethod(ref m) => m.name(),
TypeTraitItem(ref at) => at.ident.name,
TypeTraitItem(ref at) => at.ty_param.ident.name,
}
}
}
......@@ -783,7 +785,7 @@ fn visit_item(&mut self, i: &'ast Item) {
self.insert(m.id, NodeTraitItem(tm));
}
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 {
ProvidedMethod(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));
......@@ -1080,7 +1082,7 @@ fn node_id_to_string(map: &Map, id: NodeId) -> String {
}
TypeTraitItem(ref t) => {
format!("type item {} in {} (id={})",
token::get_ident(t.ident),
token::get_ident(t.ty_param.ident),
map.path_to_string(id),
id)
}
......
......@@ -525,7 +525,7 @@ fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
match *tm {
ast::RequiredMethod(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);
}
......
......@@ -260,7 +260,7 @@ fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
ast::TypeTraitItem(ref ti) => {
self.gate_feature("associated_types",
ti.span,
ti.ty_param.span,
"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)
-> AssociatedType
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);
where T: Folder
{
let new_attrs = at.attrs
.iter()
.map(|attr| folder.fold_attribute((*attr).clone()))
.collect();
let new_param = folder.fold_ty_param(at.ty_param);
ast::AssociatedType {
ident: new_ident,
attrs: new_attrs,
id: new_id,
span: new_span,
ty_param: new_param,
}
}
......
......@@ -1229,16 +1229,13 @@ pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
/// Parses `type Foo;` in a trait declaration only. The `type` keyword has
/// already been parsed.
fn parse_associated_type(&mut self, attrs: Vec<Attribute>)
-> AssociatedType {
let lo = self.span.lo;
let ident = self.parse_ident();
let hi = self.span.hi;
-> AssociatedType
{
let ty_param = self.parse_ty_param();
self.expect(&token::Semi);
AssociatedType {
id: ast::DUMMY_NODE_ID,
span: mk_sp(lo, hi),
ident: ident,
attrs: attrs,
ty_param: ty_param,
}
}
......
......@@ -818,9 +818,11 @@ pub fn print_foreign_item(&mut self,
}
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.print_ident(typedef.ident));
try!(self.print_ty_param(&typedef.ty_param));
word(&mut self.s, ";")
}
......@@ -2434,23 +2436,7 @@ pub fn print_generics(&mut self,
} else {
let idx = idx - generics.lifetimes.len();
let param = generics.ty_params.get(idx);
match param.unbound {
Some(TraitTyParamBound(ref tref)) => {
try!(s.print_trait_ref(tref));
try!(s.word_space("?"));
}
_ => {}
}
try!(s.print_ident(param.ident));
try!(s.print_bounds(":", &param.bounds));
match param.default {
Some(ref default) => {
try!(space(&mut s.s));
try!(s.word_space("="));
s.print_type(&**default)
}
_ => Ok(())
}
s.print_ty_param(param)
}
}));
......@@ -2458,6 +2444,26 @@ pub fn print_generics(&mut self,
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(":", &param.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)
-> IoResult<()> {
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),
ProvidedMethod(ref method) => walk_method_helper(visitor, &**method),
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)
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册