提交 6a2f16e1 编写于 作者: F Flavio Percoco

Add support for default trait impls in libsyntax

上级 2b01a37e
......@@ -1641,6 +1641,10 @@ pub enum Item_ {
Generics,
TyParamBounds,
Vec<TraitItem>),
// Default trait implementations
// `impl Trait for ..`
ItemDefTrait(Unsafety, TraitRef),
ItemImpl(Unsafety,
ImplPolarity,
Generics,
......@@ -1666,7 +1670,8 @@ pub fn descriptive_variant(&self) -> &str {
ItemStruct(..) => "struct",
ItemTrait(..) => "trait",
ItemMac(..) |
ItemImpl(..) => "item"
ItemImpl(..) |
ItemDefTrait(..) => "item"
}
}
}
......
......@@ -1044,6 +1044,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
ItemStruct(..) => "struct",
ItemTrait(..) => "trait",
ItemImpl(..) => "impl",
ItemDefTrait(..) => "default impl",
ItemMac(..) => "macro"
};
format!("{} {}{}", item_str, path_str, id_str)
......
......@@ -252,8 +252,12 @@ pub fn name_to_dummy_lifetime(name: Name) -> Lifetime {
/// hint of where they came from, (previously they would all just be
/// listed as `__extensions__::method_name::hash`, with no indication
/// of the type).
pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
let mut pretty = pprust::ty_to_string(ty);
pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident {
let mut pretty = match ty {
Some(t) => pprust::ty_to_string(t),
None => String::from_str("..")
};
match *trait_ref {
Some(ref trait_ref) => {
pretty.push('.');
......
......@@ -498,7 +498,7 @@ fn create_derived_impl(&self,
// Just mark it now since we know that it'll end up used downstream
attr::mark_used(&attr);
let opt_trait_ref = Some(trait_ref);
let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&*self_type));
let mut a = vec![attr];
a.extend(self.attributes.iter().cloned());
cx.item(
......
......@@ -999,6 +999,9 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
let struct_def = folder.fold_struct_def(struct_def);
ItemStruct(struct_def, folder.fold_generics(generics))
}
ItemDefTrait(unsafety, ref trait_ref) => {
ItemDefTrait(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
}
ItemImpl(unsafety, polarity, generics, ifce, ty, impl_items) => {
let new_impl_items = impl_items.into_iter().flat_map(|item| {
folder.fold_impl_item(item).into_iter()
......@@ -1150,7 +1153,7 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}
let ident = match node {
// The node may have changed, recompute the "pretty" impl name.
ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => {
ast_util::impl_pretty_name(maybe_trait, &**ty)
ast_util::impl_pretty_name(maybe_trait, Some(&**ty))
}
_ => ident
};
......
......@@ -31,7 +31,7 @@
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefTrait};
use ast::{ItemExternCrate, ItemUse};
use ast::{LifetimeDef, Lit, Lit_};
use ast::{LitBool, LitChar, LitByte, LitBinary};
......@@ -4783,10 +4783,13 @@ fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) {
(impl_items, inner_attrs)
}
/// Parses two variants (with the region/type params always optional):
/// Parses items implementations variants
/// impl<T> Foo { ... }
/// impl<T> ToString for ~[T] { ... }
/// impl<T> ToString for &'static T { ... }
/// impl Send for .. {}
fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
let impl_span = self.span;
// First, parse type parameters if necessary.
let mut generics = self.parse_generics();
......@@ -4807,7 +4810,7 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
// Parse traits, if necessary.
let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
// New-style trait. Reinterpret the type as a trait.
let opt_trait_ref = match ty.node {
match ty.node {
TyPath(ref path, node_id) => {
Some(TraitRef {
path: (*path).clone(),
......@@ -4818,10 +4821,7 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
self.span_err(ty.span, "not a trait");
None
}
};
ty = self.parse_ty_sum();
opt_trait_ref
}
} else {
match polarity {
ast::ImplPolarity::Negative => {
......@@ -4834,14 +4834,27 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
None
};
self.parse_where_clause(&mut generics);
let (impl_items, attrs) = self.parse_impl_items();
if self.eat(&token::DotDot) {
if generics.is_parameterized() {
self.span_err(impl_span, "default trait implementations are not \
allowed to have genercis");
}
let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
self.expect(&token::OpenDelim(token::Brace));
self.expect(&token::CloseDelim(token::Brace));
(ast_util::impl_pretty_name(&opt_trait, None),
ItemDefTrait(unsafety, opt_trait.unwrap()), None)
} else {
if opt_trait.is_some() {
ty = self.parse_ty_sum();
}
self.parse_where_clause(&mut generics);
let (impl_items, attrs) = self.parse_impl_items();
(ident,
ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
Some(attrs))
(ast_util::impl_pretty_name(&opt_trait, Some(&*ty)),
ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
Some(attrs))
}
}
/// Parse a::B<String,i32>
......
......@@ -926,6 +926,18 @@ pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
}
ast::ItemDefTrait(unsafety, ref trait_ref) => {
try!(self.head(""));
try!(self.print_visibility(item.vis));
try!(self.print_unsafety(unsafety));
try!(self.word_nbsp("impl"));
try!(self.print_trait_ref(trait_ref));
try!(space(&mut self.s));
try!(self.word_space("for"));
try!(self.word_space(".."));
try!(self.bopen());
try!(self.bclose(item.span));
}
ast::ItemImpl(unsafety,
polarity,
ref generics,
......
......@@ -282,6 +282,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_generics(type_parameters);
walk_enum_def(visitor, enum_definition, type_parameters)
}
ItemDefTrait(_, ref trait_ref) => {
visitor.visit_trait_ref(trait_ref)
}
ItemImpl(_, _,
ref type_parameters,
ref trait_reference,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册