Skip to content

Commit 6a2f16e

Browse files
committed
Add support for default trait impls in libsyntax
1 parent 2b01a37 commit 6a2f16e

File tree

8 files changed

+60
-19
lines changed

8 files changed

+60
-19
lines changed

src/libsyntax/ast.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,10 @@ pub enum Item_ {
16411641
Generics,
16421642
TyParamBounds,
16431643
Vec<TraitItem>),
1644+
1645+
// Default trait implementations
1646+
// `impl Trait for ..`
1647+
ItemDefTrait(Unsafety, TraitRef),
16441648
ItemImpl(Unsafety,
16451649
ImplPolarity,
16461650
Generics,
@@ -1666,7 +1670,8 @@ impl Item_ {
16661670
ItemStruct(..) => "struct",
16671671
ItemTrait(..) => "trait",
16681672
ItemMac(..) |
1669-
ItemImpl(..) => "item"
1673+
ItemImpl(..) |
1674+
ItemDefTrait(..) => "item"
16701675
}
16711676
}
16721677
}

src/libsyntax/ast_map/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
10441044
ItemStruct(..) => "struct",
10451045
ItemTrait(..) => "trait",
10461046
ItemImpl(..) => "impl",
1047+
ItemDefTrait(..) => "default impl",
10471048
ItemMac(..) => "macro"
10481049
};
10491050
format!("{} {}{}", item_str, path_str, id_str)

src/libsyntax/ast_util.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,12 @@ pub fn name_to_dummy_lifetime(name: Name) -> Lifetime {
252252
/// hint of where they came from, (previously they would all just be
253253
/// listed as `__extensions__::method_name::hash`, with no indication
254254
/// of the type).
255-
pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
256-
let mut pretty = pprust::ty_to_string(ty);
255+
pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident {
256+
let mut pretty = match ty {
257+
Some(t) => pprust::ty_to_string(t),
258+
None => String::from_str("..")
259+
};
260+
257261
match *trait_ref {
258262
Some(ref trait_ref) => {
259263
pretty.push('.');

src/libsyntax/ext/deriving/generic/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl<'a> TraitDef<'a> {
498498
// Just mark it now since we know that it'll end up used downstream
499499
attr::mark_used(&attr);
500500
let opt_trait_ref = Some(trait_ref);
501-
let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
501+
let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&*self_type));
502502
let mut a = vec![attr];
503503
a.extend(self.attributes.iter().cloned());
504504
cx.item(

src/libsyntax/fold.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,9 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
999999
let struct_def = folder.fold_struct_def(struct_def);
10001000
ItemStruct(struct_def, folder.fold_generics(generics))
10011001
}
1002+
ItemDefTrait(unsafety, ref trait_ref) => {
1003+
ItemDefTrait(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
1004+
}
10021005
ItemImpl(unsafety, polarity, generics, ifce, ty, impl_items) => {
10031006
let new_impl_items = impl_items.into_iter().flat_map(|item| {
10041007
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}
11501153
let ident = match node {
11511154
// The node may have changed, recompute the "pretty" impl name.
11521155
ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => {
1153-
ast_util::impl_pretty_name(maybe_trait, &**ty)
1156+
ast_util::impl_pretty_name(maybe_trait, Some(&**ty))
11541157
}
11551158
_ => ident
11561159
};

src/libsyntax/parse/parser.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
3131
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
3232
use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
3333
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
34-
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
34+
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefTrait};
3535
use ast::{ItemExternCrate, ItemUse};
3636
use ast::{LifetimeDef, Lit, Lit_};
3737
use ast::{LitBool, LitChar, LitByte, LitBinary};
@@ -4783,10 +4783,13 @@ impl<'a> Parser<'a> {
47834783
(impl_items, inner_attrs)
47844784
}
47854785

4786-
/// Parses two variants (with the region/type params always optional):
4786+
/// Parses items implementations variants
47874787
/// impl<T> Foo { ... }
4788-
/// impl<T> ToString for ~[T] { ... }
4788+
/// impl<T> ToString for &'static T { ... }
4789+
/// impl Send for .. {}
47894790
fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
4791+
let impl_span = self.span;
4792+
47904793
// First, parse type parameters if necessary.
47914794
let mut generics = self.parse_generics();
47924795

@@ -4807,7 +4810,7 @@ impl<'a> Parser<'a> {
48074810
// Parse traits, if necessary.
48084811
let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
48094812
// New-style trait. Reinterpret the type as a trait.
4810-
let opt_trait_ref = match ty.node {
4813+
match ty.node {
48114814
TyPath(ref path, node_id) => {
48124815
Some(TraitRef {
48134816
path: (*path).clone(),
@@ -4818,10 +4821,7 @@ impl<'a> Parser<'a> {
48184821
self.span_err(ty.span, "not a trait");
48194822
None
48204823
}
4821-
};
4822-
4823-
ty = self.parse_ty_sum();
4824-
opt_trait_ref
4824+
}
48254825
} else {
48264826
match polarity {
48274827
ast::ImplPolarity::Negative => {
@@ -4834,14 +4834,27 @@ impl<'a> Parser<'a> {
48344834
None
48354835
};
48364836

4837-
self.parse_where_clause(&mut generics);
4838-
let (impl_items, attrs) = self.parse_impl_items();
4837+
if self.eat(&token::DotDot) {
4838+
if generics.is_parameterized() {
4839+
self.span_err(impl_span, "default trait implementations are not \
4840+
allowed to have genercis");
4841+
}
48394842

4840-
let ident = ast_util::impl_pretty_name(&opt_trait, &*ty);
4843+
self.expect(&token::OpenDelim(token::Brace));
4844+
self.expect(&token::CloseDelim(token::Brace));
4845+
(ast_util::impl_pretty_name(&opt_trait, None),
4846+
ItemDefTrait(unsafety, opt_trait.unwrap()), None)
4847+
} else {
4848+
if opt_trait.is_some() {
4849+
ty = self.parse_ty_sum();
4850+
}
4851+
self.parse_where_clause(&mut generics);
4852+
let (impl_items, attrs) = self.parse_impl_items();
48414853

4842-
(ident,
4843-
ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
4844-
Some(attrs))
4854+
(ast_util::impl_pretty_name(&opt_trait, Some(&*ty)),
4855+
ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
4856+
Some(attrs))
4857+
}
48454858
}
48464859

48474860
/// Parse a::B<String,i32>

src/libsyntax/print/pprust.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,18 @@ impl<'a> State<'a> {
926926
try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
927927
}
928928

929+
ast::ItemDefTrait(unsafety, ref trait_ref) => {
930+
try!(self.head(""));
931+
try!(self.print_visibility(item.vis));
932+
try!(self.print_unsafety(unsafety));
933+
try!(self.word_nbsp("impl"));
934+
try!(self.print_trait_ref(trait_ref));
935+
try!(space(&mut self.s));
936+
try!(self.word_space("for"));
937+
try!(self.word_space(".."));
938+
try!(self.bopen());
939+
try!(self.bclose(item.span));
940+
}
929941
ast::ItemImpl(unsafety,
930942
polarity,
931943
ref generics,

src/libsyntax/visit.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
282282
visitor.visit_generics(type_parameters);
283283
walk_enum_def(visitor, enum_definition, type_parameters)
284284
}
285+
ItemDefTrait(_, ref trait_ref) => {
286+
visitor.visit_trait_ref(trait_ref)
287+
}
285288
ItemImpl(_, _,
286289
ref type_parameters,
287290
ref trait_reference,

0 commit comments

Comments
 (0)