mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Add support for default trait impls in libsyntax
This commit is contained in:
parent
2b01a37ec3
commit
6a2f16e136
@ -1641,6 +1641,10 @@ pub enum Item_ {
|
|||||||
Generics,
|
Generics,
|
||||||
TyParamBounds,
|
TyParamBounds,
|
||||||
Vec<TraitItem>),
|
Vec<TraitItem>),
|
||||||
|
|
||||||
|
// Default trait implementations
|
||||||
|
// `impl Trait for ..`
|
||||||
|
ItemDefTrait(Unsafety, TraitRef),
|
||||||
ItemImpl(Unsafety,
|
ItemImpl(Unsafety,
|
||||||
ImplPolarity,
|
ImplPolarity,
|
||||||
Generics,
|
Generics,
|
||||||
@ -1666,7 +1670,8 @@ impl Item_ {
|
|||||||
ItemStruct(..) => "struct",
|
ItemStruct(..) => "struct",
|
||||||
ItemTrait(..) => "trait",
|
ItemTrait(..) => "trait",
|
||||||
ItemMac(..) |
|
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",
|
ItemStruct(..) => "struct",
|
||||||
ItemTrait(..) => "trait",
|
ItemTrait(..) => "trait",
|
||||||
ItemImpl(..) => "impl",
|
ItemImpl(..) => "impl",
|
||||||
|
ItemDefTrait(..) => "default impl",
|
||||||
ItemMac(..) => "macro"
|
ItemMac(..) => "macro"
|
||||||
};
|
};
|
||||||
format!("{} {}{}", item_str, path_str, id_str)
|
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
|
/// hint of where they came from, (previously they would all just be
|
||||||
/// listed as `__extensions__::method_name::hash`, with no indication
|
/// listed as `__extensions__::method_name::hash`, with no indication
|
||||||
/// of the type).
|
/// of the type).
|
||||||
pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
|
pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident {
|
||||||
let mut pretty = pprust::ty_to_string(ty);
|
let mut pretty = match ty {
|
||||||
|
Some(t) => pprust::ty_to_string(t),
|
||||||
|
None => String::from_str("..")
|
||||||
|
};
|
||||||
|
|
||||||
match *trait_ref {
|
match *trait_ref {
|
||||||
Some(ref trait_ref) => {
|
Some(ref trait_ref) => {
|
||||||
pretty.push('.');
|
pretty.push('.');
|
||||||
|
@ -498,7 +498,7 @@ impl<'a> TraitDef<'a> {
|
|||||||
// Just mark it now since we know that it'll end up used downstream
|
// Just mark it now since we know that it'll end up used downstream
|
||||||
attr::mark_used(&attr);
|
attr::mark_used(&attr);
|
||||||
let opt_trait_ref = Some(trait_ref);
|
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];
|
let mut a = vec![attr];
|
||||||
a.extend(self.attributes.iter().cloned());
|
a.extend(self.attributes.iter().cloned());
|
||||||
cx.item(
|
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);
|
let struct_def = folder.fold_struct_def(struct_def);
|
||||||
ItemStruct(struct_def, folder.fold_generics(generics))
|
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) => {
|
ItemImpl(unsafety, polarity, generics, ifce, ty, impl_items) => {
|
||||||
let new_impl_items = impl_items.into_iter().flat_map(|item| {
|
let new_impl_items = impl_items.into_iter().flat_map(|item| {
|
||||||
folder.fold_impl_item(item).into_iter()
|
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 {
|
let ident = match node {
|
||||||
// The node may have changed, recompute the "pretty" impl name.
|
// The node may have changed, recompute the "pretty" impl name.
|
||||||
ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => {
|
ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => {
|
||||||
ast_util::impl_pretty_name(maybe_trait, &**ty)
|
ast_util::impl_pretty_name(maybe_trait, Some(&**ty))
|
||||||
}
|
}
|
||||||
_ => ident
|
_ => ident
|
||||||
};
|
};
|
||||||
|
@ -31,7 +31,7 @@ use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
|
|||||||
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
|
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy};
|
||||||
use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
|
use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
|
||||||
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
|
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::{ItemExternCrate, ItemUse};
|
||||||
use ast::{LifetimeDef, Lit, Lit_};
|
use ast::{LifetimeDef, Lit, Lit_};
|
||||||
use ast::{LitBool, LitChar, LitByte, LitBinary};
|
use ast::{LitBool, LitChar, LitByte, LitBinary};
|
||||||
@ -4783,10 +4783,13 @@ impl<'a> Parser<'a> {
|
|||||||
(impl_items, inner_attrs)
|
(impl_items, inner_attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses two variants (with the region/type params always optional):
|
/// Parses items implementations variants
|
||||||
/// impl<T> Foo { ... }
|
/// 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 {
|
fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
|
||||||
|
let impl_span = self.span;
|
||||||
|
|
||||||
// First, parse type parameters if necessary.
|
// First, parse type parameters if necessary.
|
||||||
let mut generics = self.parse_generics();
|
let mut generics = self.parse_generics();
|
||||||
|
|
||||||
@ -4807,7 +4810,7 @@ impl<'a> Parser<'a> {
|
|||||||
// Parse traits, if necessary.
|
// Parse traits, if necessary.
|
||||||
let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
|
let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
|
||||||
// New-style trait. Reinterpret the type as a trait.
|
// New-style trait. Reinterpret the type as a trait.
|
||||||
let opt_trait_ref = match ty.node {
|
match ty.node {
|
||||||
TyPath(ref path, node_id) => {
|
TyPath(ref path, node_id) => {
|
||||||
Some(TraitRef {
|
Some(TraitRef {
|
||||||
path: (*path).clone(),
|
path: (*path).clone(),
|
||||||
@ -4818,10 +4821,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.span_err(ty.span, "not a trait");
|
self.span_err(ty.span, "not a trait");
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
ty = self.parse_ty_sum();
|
|
||||||
opt_trait_ref
|
|
||||||
} else {
|
} else {
|
||||||
match polarity {
|
match polarity {
|
||||||
ast::ImplPolarity::Negative => {
|
ast::ImplPolarity::Negative => {
|
||||||
@ -4834,14 +4834,27 @@ impl<'a> Parser<'a> {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
self.parse_where_clause(&mut generics);
|
if self.eat(&token::DotDot) {
|
||||||
let (impl_items, attrs) = self.parse_impl_items();
|
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,
|
(ast_util::impl_pretty_name(&opt_trait, Some(&*ty)),
|
||||||
ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
|
ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
|
||||||
Some(attrs))
|
Some(attrs))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a::B<String,i32>
|
/// Parse a::B<String,i32>
|
||||||
|
@ -926,6 +926,18 @@ impl<'a> State<'a> {
|
|||||||
try!(self.print_struct(&**struct_def, generics, item.ident, item.span));
|
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,
|
ast::ItemImpl(unsafety,
|
||||||
polarity,
|
polarity,
|
||||||
ref generics,
|
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);
|
visitor.visit_generics(type_parameters);
|
||||||
walk_enum_def(visitor, enum_definition, type_parameters)
|
walk_enum_def(visitor, enum_definition, type_parameters)
|
||||||
}
|
}
|
||||||
|
ItemDefTrait(_, ref trait_ref) => {
|
||||||
|
visitor.visit_trait_ref(trait_ref)
|
||||||
|
}
|
||||||
ItemImpl(_, _,
|
ItemImpl(_, _,
|
||||||
ref type_parameters,
|
ref type_parameters,
|
||||||
ref trait_reference,
|
ref trait_reference,
|
||||||
|
Loading…
Reference in New Issue
Block a user