Add support for default trait impls in libsyntax
This commit is contained in:
parent
2b01a37ec3
commit
6a2f16e136
8 changed files with 60 additions and 19 deletions
|
@ -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 @@ impl Item_ {
|
|||
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 @@ impl<'a> TraitDef<'a> {
|
|||
// 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::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
|
|||
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 @@ impl<'a> Parser<'a> {
|
|||
(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 @@ impl<'a> Parser<'a> {
|
|||
// 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 @@ impl<'a> Parser<'a> {
|
|||
self.span_err(ty.span, "not a trait");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
ty = self.parse_ty_sum();
|
||||
opt_trait_ref
|
||||
}
|
||||
} else {
|
||||
match polarity {
|
||||
ast::ImplPolarity::Negative => {
|
||||
|
@ -4834,15 +4834,28 @@ impl<'a> Parser<'a> {
|
|||
None
|
||||
};
|
||||
|
||||
if self.eat(&token::DotDot) {
|
||||
if generics.is_parameterized() {
|
||||
self.span_err(impl_span, "default trait implementations are not \
|
||||
allowed to have genercis");
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
|
||||
|
||||
(ident,
|
||||
(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>
|
||||
fn parse_trait_ref(&mut self) -> TraitRef {
|
||||
|
|
|
@ -926,6 +926,18 @@ impl<'a> State<'a> {
|
|||
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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue