Eliminate PolyTraitRef
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index 9d1eb24..5d4dc7d 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -312,8 +312,6 @@
fn fold_path_segment(&mut self, i: PathSegment) -> PathSegment { fold_path_segment(self, i) }
-fn fold_poly_trait_ref(&mut self, i: PolyTraitRef) -> PolyTraitRef { fold_poly_trait_ref(self, i) }
-
fn fold_predicate_eq(&mut self, i: PredicateEq) -> PredicateEq { fold_predicate_eq(self, i) }
fn fold_predicate_lifetime(&mut self, i: PredicateLifetime) -> PredicateLifetime { fold_predicate_lifetime(self, i) }
@@ -330,6 +328,8 @@
# [ cfg ( feature = "full" ) ]
fn fold_stmt(&mut self, i: Stmt) -> Stmt { fold_stmt(self, i) }
+fn fold_trait_bound(&mut self, i: TraitBound) -> TraitBound { fold_trait_bound(self, i) }
+
fn fold_trait_bound_modifier(&mut self, i: TraitBoundModifier) -> TraitBoundModifier { fold_trait_bound_modifier(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_trait_item(&mut self, i: TraitItem) -> TraitItem { fold_trait_item(self, i) }
@@ -2307,13 +2307,6 @@
}
}
-pub fn fold_poly_trait_ref<V: Folder + ?Sized>(_visitor: &mut V, _i: PolyTraitRef) -> PolyTraitRef {
- PolyTraitRef {
- bound_lifetimes: (_i . bound_lifetimes).map(|it| { _visitor.fold_bound_lifetimes(it) }),
- trait_ref: _visitor.fold_path(_i . trait_ref),
- }
-}
-
pub fn fold_predicate_eq<V: Folder + ?Sized>(_visitor: &mut V, _i: PredicateEq) -> PredicateEq {
PredicateEq {
lhs_ty: _visitor.fold_type(_i . lhs_ty),
@@ -2332,7 +2325,7 @@
pub fn fold_predicate_type<V: Folder + ?Sized>(_visitor: &mut V, _i: PredicateType) -> PredicateType {
PredicateType {
- bound_lifetimes: (_i . bound_lifetimes).map(|it| { _visitor.fold_bound_lifetimes(it) }),
+ lifetimes: (_i . lifetimes).map(|it| { _visitor.fold_bound_lifetimes(it) }),
bounded_ty: _visitor.fold_type(_i . bounded_ty),
colon_token: Token ! [ : ](tokens_helper(_visitor, &(_i . colon_token).0)),
bounds: FoldHelper::lift(_i . bounds, |it| { _visitor.fold_type_param_bound(it) }),
@@ -2406,6 +2399,14 @@
}
}
+pub fn fold_trait_bound<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitBound) -> TraitBound {
+ TraitBound {
+ modifier: _visitor.fold_trait_bound_modifier(_i . modifier),
+ lifetimes: (_i . lifetimes).map(|it| { _visitor.fold_bound_lifetimes(it) }),
+ path: _visitor.fold_path(_i . path),
+ }
+}
+
pub fn fold_trait_bound_modifier<V: Folder + ?Sized>(_visitor: &mut V, _i: TraitBoundModifier) -> TraitBoundModifier {
match _i {
TraitBoundModifier::None => { TraitBoundModifier::None }
@@ -2648,14 +2649,13 @@
pub fn fold_type_param_bound<V: Folder + ?Sized>(_visitor: &mut V, _i: TypeParamBound) -> TypeParamBound {
match _i {
- TypeParamBound::Trait(_binding_0, _binding_1, ) => {
+ TypeParamBound::Trait(_binding_0, ) => {
TypeParamBound::Trait (
- _visitor.fold_poly_trait_ref(_binding_0),
- _visitor.fold_trait_bound_modifier(_binding_1),
+ _visitor.fold_trait_bound(_binding_0),
)
}
- TypeParamBound::Region(_binding_0, ) => {
- TypeParamBound::Region (
+ TypeParamBound::Lifetime(_binding_0, ) => {
+ TypeParamBound::Lifetime (
_visitor.fold_lifetime(_binding_0),
)
}
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index 2770a7b..a14a24f 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -309,8 +309,6 @@
fn visit_path_segment(&mut self, i: &'ast PathSegment) { visit_path_segment(self, i) }
-fn visit_poly_trait_ref(&mut self, i: &'ast PolyTraitRef) { visit_poly_trait_ref(self, i) }
-
fn visit_predicate_eq(&mut self, i: &'ast PredicateEq) { visit_predicate_eq(self, i) }
fn visit_predicate_lifetime(&mut self, i: &'ast PredicateLifetime) { visit_predicate_lifetime(self, i) }
@@ -327,6 +325,8 @@
# [ cfg ( feature = "full" ) ]
fn visit_stmt(&mut self, i: &'ast Stmt) { visit_stmt(self, i) }
+fn visit_trait_bound(&mut self, i: &'ast TraitBound) { visit_trait_bound(self, i) }
+
fn visit_trait_bound_modifier(&mut self, i: &'ast TraitBoundModifier) { visit_trait_bound_modifier(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_trait_item(&mut self, i: &'ast TraitItem) { visit_trait_item(self, i) }
@@ -1794,11 +1794,6 @@
_visitor.visit_path_arguments(& _i . arguments);
}
-pub fn visit_poly_trait_ref<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PolyTraitRef) {
- if let Some(ref it) = _i . bound_lifetimes { _visitor.visit_bound_lifetimes(it) };
- _visitor.visit_path(& _i . trait_ref);
-}
-
pub fn visit_predicate_eq<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PredicateEq) {
_visitor.visit_type(& _i . lhs_ty);
tokens_helper(_visitor, &(& _i . eq_token).0);
@@ -1812,7 +1807,7 @@
}
pub fn visit_predicate_type<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast PredicateType) {
- if let Some(ref it) = _i . bound_lifetimes { _visitor.visit_bound_lifetimes(it) };
+ if let Some(ref it) = _i . lifetimes { _visitor.visit_bound_lifetimes(it) };
_visitor.visit_type(& _i . bounded_ty);
tokens_helper(_visitor, &(& _i . colon_token).0);
for el in Punctuated::elements(& _i . bounds) { let it = el.item(); _visitor.visit_type_param_bound(it) };
@@ -1868,6 +1863,12 @@
}
}
+pub fn visit_trait_bound<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TraitBound) {
+ _visitor.visit_trait_bound_modifier(& _i . modifier);
+ if let Some(ref it) = _i . lifetimes { _visitor.visit_bound_lifetimes(it) };
+ _visitor.visit_path(& _i . path);
+}
+
pub fn visit_trait_bound_modifier<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TraitBoundModifier) {
match *_i {
TraitBoundModifier::None => { }
@@ -2042,11 +2043,10 @@
pub fn visit_type_param_bound<'ast, V: Visitor<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast TypeParamBound) {
match *_i {
- TypeParamBound::Trait(ref _binding_0, ref _binding_1, ) => {
- _visitor.visit_poly_trait_ref(_binding_0);
- _visitor.visit_trait_bound_modifier(_binding_1);
+ TypeParamBound::Trait(ref _binding_0, ) => {
+ _visitor.visit_trait_bound(_binding_0);
}
- TypeParamBound::Region(ref _binding_0, ) => {
+ TypeParamBound::Lifetime(ref _binding_0, ) => {
_visitor.visit_lifetime(_binding_0);
}
}
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 4019815..250ce97 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -309,8 +309,6 @@
fn visit_path_segment_mut(&mut self, i: &mut PathSegment) { visit_path_segment_mut(self, i) }
-fn visit_poly_trait_ref_mut(&mut self, i: &mut PolyTraitRef) { visit_poly_trait_ref_mut(self, i) }
-
fn visit_predicate_eq_mut(&mut self, i: &mut PredicateEq) { visit_predicate_eq_mut(self, i) }
fn visit_predicate_lifetime_mut(&mut self, i: &mut PredicateLifetime) { visit_predicate_lifetime_mut(self, i) }
@@ -327,6 +325,8 @@
# [ cfg ( feature = "full" ) ]
fn visit_stmt_mut(&mut self, i: &mut Stmt) { visit_stmt_mut(self, i) }
+fn visit_trait_bound_mut(&mut self, i: &mut TraitBound) { visit_trait_bound_mut(self, i) }
+
fn visit_trait_bound_modifier_mut(&mut self, i: &mut TraitBoundModifier) { visit_trait_bound_modifier_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_trait_item_mut(&mut self, i: &mut TraitItem) { visit_trait_item_mut(self, i) }
@@ -1794,11 +1794,6 @@
_visitor.visit_path_arguments_mut(& mut _i . arguments);
}
-pub fn visit_poly_trait_ref_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PolyTraitRef) {
- if let Some(ref mut it) = _i . bound_lifetimes { _visitor.visit_bound_lifetimes_mut(it) };
- _visitor.visit_path_mut(& mut _i . trait_ref);
-}
-
pub fn visit_predicate_eq_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PredicateEq) {
_visitor.visit_type_mut(& mut _i . lhs_ty);
tokens_helper(_visitor, &mut (& mut _i . eq_token).0);
@@ -1812,7 +1807,7 @@
}
pub fn visit_predicate_type_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut PredicateType) {
- if let Some(ref mut it) = _i . bound_lifetimes { _visitor.visit_bound_lifetimes_mut(it) };
+ if let Some(ref mut it) = _i . lifetimes { _visitor.visit_bound_lifetimes_mut(it) };
_visitor.visit_type_mut(& mut _i . bounded_ty);
tokens_helper(_visitor, &mut (& mut _i . colon_token).0);
for mut el in Punctuated::elements_mut(& mut _i . bounds) { let it = el.item_mut(); _visitor.visit_type_param_bound_mut(it) };
@@ -1868,6 +1863,12 @@
}
}
+pub fn visit_trait_bound_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitBound) {
+ _visitor.visit_trait_bound_modifier_mut(& mut _i . modifier);
+ if let Some(ref mut it) = _i . lifetimes { _visitor.visit_bound_lifetimes_mut(it) };
+ _visitor.visit_path_mut(& mut _i . path);
+}
+
pub fn visit_trait_bound_modifier_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TraitBoundModifier) {
match *_i {
TraitBoundModifier::None => { }
@@ -2042,11 +2043,10 @@
pub fn visit_type_param_bound_mut<V: VisitorMut + ?Sized>(_visitor: &mut V, _i: &mut TypeParamBound) {
match *_i {
- TypeParamBound::Trait(ref mut _binding_0, ref mut _binding_1, ) => {
- _visitor.visit_poly_trait_ref_mut(_binding_0);
- _visitor.visit_trait_bound_modifier_mut(_binding_1);
+ TypeParamBound::Trait(ref mut _binding_0, ) => {
+ _visitor.visit_trait_bound_mut(_binding_0);
}
- TypeParamBound::Region(ref mut _binding_0, ) => {
+ TypeParamBound::Lifetime(ref mut _binding_0, ) => {
_visitor.visit_lifetime_mut(_binding_0);
}
}
diff --git a/src/generics.rs b/src/generics.rs
index 4260f18..0f0e31d 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -131,20 +131,26 @@
}
}
-ast_enum! {
- /// The AST represents all type param bounds as types.
- /// `typeck::collect::compute_bounds` matches these against
- /// the "special" built-in traits (see `middle::lang_items`) and
- /// detects Copy, Send and Sync.
+ast_enum_of_structs! {
pub enum TypeParamBound {
- Trait(PolyTraitRef, TraitBoundModifier),
- Region(Lifetime),
+ pub Trait(TraitBound),
+ pub Lifetime(Lifetime),
+ }
+}
+
+ast_struct! {
+ pub struct TraitBound {
+ pub modifier: TraitBoundModifier,
+ /// The `for<'a>` in `for<'a> Foo<&'a T>`
+ pub lifetimes: Option<BoundLifetimes>,
+ /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
+ pub path: Path,
}
}
ast_enum! {
/// A modifier on a bound, currently this is only used for `?Sized`, where the
- /// modifier is `Maybe`. Negative bounds should also be handled here.
+ /// modifier is `Maybe`.
#[cfg_attr(feature = "clone-impls", derive(Copy))]
pub enum TraitBoundModifier {
None,
@@ -166,7 +172,7 @@
/// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
pub Type(PredicateType {
/// Any lifetimes from a `for` binding
- pub bound_lifetimes: Option<BoundLifetimes>,
+ pub lifetimes: Option<BoundLifetimes>,
/// The type being bounded
pub bounded_ty: Type,
pub colon_token: Token![:],
@@ -305,21 +311,11 @@
impl Synom for TypeParamBound {
named!(parse -> Self, alt!(
- do_parse!(
- question: punct!(?) >>
- poly: syn!(PolyTraitRef) >>
- (TypeParamBound::Trait(poly, TraitBoundModifier::Maybe(question)))
- )
+ syn!(Lifetime) => { TypeParamBound::Lifetime }
|
- syn!(Lifetime) => { TypeParamBound::Region }
+ syn!(TraitBound) => { TypeParamBound::Trait }
|
- syn!(PolyTraitRef) => {
- |poly| TypeParamBound::Trait(poly, TraitBoundModifier::None)
- }
- |
- parens!(syn!(PolyTraitRef)) => {
- |poly| TypeParamBound::Trait(poly.1, TraitBoundModifier::None)
- }
+ parens!(syn!(TraitBound)) => { |bound| TypeParamBound::Trait(bound.1) }
));
fn description() -> Option<&'static str> {
@@ -327,6 +323,45 @@
}
}
+ impl Synom for TraitBound {
+ named!(parse -> Self, do_parse!(
+ modifier: syn!(TraitBoundModifier) >>
+ lifetimes: option!(syn!(BoundLifetimes)) >>
+ mut path: syn!(Path) >>
+ parenthesized: option!(cond_reduce!(
+ path.segments.last().unwrap().item().arguments.is_empty(),
+ syn!(ParenthesizedGenericArguments)
+ )) >>
+ ({
+ if let Some(parenthesized) = parenthesized {
+ let parenthesized = PathArguments::Parenthesized(parenthesized);
+ path.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
+ }
+ TraitBound {
+ modifier: modifier,
+ lifetimes: lifetimes,
+ path: path,
+ }
+ })
+ ));
+
+ fn description() -> Option<&'static str> {
+ Some("trait bound")
+ }
+ }
+
+ impl Synom for TraitBoundModifier {
+ named!(parse -> Self, alt!(
+ punct!(?) => { TraitBoundModifier::Maybe }
+ |
+ epsilon!() => { |_| TraitBoundModifier::None }
+ ));
+
+ fn description() -> Option<&'static str> {
+ Some("trait bound modifier")
+ }
+ }
+
impl Synom for ConstParam {
named!(parse -> Self, do_parse!(
attrs: many0!(Attribute::parse_outer) >>
@@ -389,12 +424,12 @@
)
|
do_parse!(
- bound_lifetimes: option!(syn!(BoundLifetimes)) >>
+ lifetimes: option!(syn!(BoundLifetimes)) >>
bounded_ty: syn!(Type) >>
colon: punct!(:) >>
bounds: call!(Punctuated::parse_separated_nonempty) >>
(WherePredicate::Type(PredicateType {
- bound_lifetimes: bound_lifetimes,
+ lifetimes: lifetimes,
bounded_ty: bounded_ty,
bounds: bounds,
colon_token: colon,
@@ -539,15 +574,11 @@
}
}
- impl ToTokens for TypeParamBound {
+ impl ToTokens for TraitBound {
fn to_tokens(&self, tokens: &mut Tokens) {
- match *self {
- TypeParamBound::Region(ref lifetime) => lifetime.to_tokens(tokens),
- TypeParamBound::Trait(ref trait_ref, ref modifier) => {
- modifier.to_tokens(tokens);
- trait_ref.to_tokens(tokens);
- }
- }
+ self.modifier.to_tokens(tokens);
+ self.lifetimes.to_tokens(tokens);
+ self.path.to_tokens(tokens);
}
}
@@ -583,7 +614,7 @@
impl ToTokens for PredicateType {
fn to_tokens(&self, tokens: &mut Tokens) {
- self.bound_lifetimes.to_tokens(tokens);
+ self.lifetimes.to_tokens(tokens);
self.bounded_ty.to_tokens(tokens);
self.colon_token.to_tokens(tokens);
self.bounds.to_tokens(tokens);
diff --git a/src/lib.rs b/src/lib.rs
index c7862a9..ce9a830 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -42,7 +42,7 @@
mod generics;
pub use generics::{BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeDef,
- PredicateEq, PredicateLifetime, PredicateType, TraitBoundModifier,
+ PredicateEq, PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier,
TypeParam, TypeParamBound, WhereClause, WherePredicate};
#[cfg(feature = "printing")]
pub use generics::{ImplGenerics, Turbofish, TypeGenerics};
@@ -84,7 +84,7 @@
mod ty;
pub use ty::{Abi, AngleBracketedGenericArguments, BareFnArg, BareFnArgName,
Binding, GenericArgument, ParenthesizedGenericArguments, Path,
- PathArguments, PathSegment, PolyTraitRef, QSelf, ReturnType, Type, TypeArray,
+ PathArguments, PathSegment, QSelf, ReturnType, Type, TypeArray,
TypeBareFn, TypeGroup, TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen,
TypePath, TypePtr, TypeReference, TypeSlice, TypeTraitObject, TypeTuple, TypeVerbatim};
#[cfg(feature = "printing")]
diff --git a/src/ty.rs b/src/ty.rs
index c8d7e87..5656094 100644
--- a/src/ty.rs
+++ b/src/ty.rs
@@ -268,15 +268,6 @@
}
ast_struct! {
- pub struct PolyTraitRef {
- /// The `for<'a>` in `for<'a> Foo<&'a T>`
- pub bound_lifetimes: Option<BoundLifetimes>,
- /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
- pub trait_ref: Path,
- }
-}
-
-ast_struct! {
/// The explicit Self type in a "qualified path". The actual
/// path, including the trait and the associated item, is stored
/// separately. `position` represents the index of the associated
@@ -841,32 +832,6 @@
}
}
- impl Synom for PolyTraitRef {
- named!(parse -> Self, do_parse!(
- bound_lifetimes: option!(syn!(BoundLifetimes)) >>
- trait_ref: syn!(Path) >>
- parenthesized: option!(cond_reduce!(
- trait_ref.segments.last().unwrap().item().arguments.is_empty(),
- syn!(ParenthesizedGenericArguments)
- )) >>
- ({
- let mut trait_ref = trait_ref;
- if let Some(parenthesized) = parenthesized {
- let parenthesized = PathArguments::Parenthesized(parenthesized);
- trait_ref.segments.last_mut().unwrap().item_mut().arguments = parenthesized;
- }
- PolyTraitRef {
- bound_lifetimes: bound_lifetimes,
- trait_ref: trait_ref,
- }
- })
- ));
-
- fn description() -> Option<&'static str> {
- Some("poly trait reference")
- }
- }
-
impl Synom for BareFnArg {
named!(parse -> Self, do_parse!(
name: option!(do_parse!(
@@ -1179,13 +1144,6 @@
}
}
- impl ToTokens for PolyTraitRef {
- fn to_tokens(&self, tokens: &mut Tokens) {
- self.bound_lifetimes.to_tokens(tokens);
- self.trait_ref.to_tokens(tokens);
- }
- }
-
impl ToTokens for BareFnArg {
fn to_tokens(&self, tokens: &mut Tokens) {
if let Some((ref name, ref colon)) = self.name {
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
index 2b35936..b22c07c 100644
--- a/tests/test_generics.rs
+++ b/tests/test_generics.rs
@@ -47,7 +47,7 @@
],
ident: "T".into(),
bounds: punctuated![
- TypeParamBound::Region(Lifetime::new(Term::intern("'a"), Span::default())),
+ TypeParamBound::Lifetime(Lifetime::new(Term::intern("'a"), Span::default())),
],
default: Some(
TypeTuple {
@@ -63,20 +63,18 @@
where_token: Default::default(),
predicates: punctuated![
WherePredicate::Type(PredicateType {
- bound_lifetimes: None,
+ lifetimes: None,
colon_token: Default::default(),
bounded_ty: TypePath {
qself: None,
path: "T".into(),
}.into(),
bounds: punctuated![
- TypeParamBound::Trait(
- PolyTraitRef {
- bound_lifetimes: None,
- trait_ref: "Debug".into(),
- },
- TraitBoundModifier::None,
- ),
+ TypeParamBound::Trait(TraitBound {
+ modifier: TraitBoundModifier::None,
+ lifetimes: None,
+ path: "Debug".into(),
+ }),
],
}),
],
@@ -105,33 +103,29 @@
#[test]
fn test_ty_param_bound() {
let tokens = quote!('a);
- let expected = TypeParamBound::Region(Lifetime::new(Term::intern("'a"), Span::default()));
+ let expected = TypeParamBound::Lifetime(Lifetime::new(Term::intern("'a"), Span::default()));
assert_eq!(
expected,
common::parse::syn::<TypeParamBound>(tokens.into())
);
let tokens = quote!(Debug);
- let expected = TypeParamBound::Trait(
- PolyTraitRef {
- bound_lifetimes: None,
- trait_ref: "Debug".into(),
- },
- TraitBoundModifier::None,
- );
+ let expected = TypeParamBound::Trait(TraitBound {
+ modifier: TraitBoundModifier::None,
+ lifetimes: None,
+ path: "Debug".into(),
+ });
assert_eq!(
expected,
common::parse::syn::<TypeParamBound>(tokens.into())
);
let tokens = quote!(?Sized);
- let expected = TypeParamBound::Trait(
- PolyTraitRef {
- bound_lifetimes: None,
- trait_ref: "Sized".into(),
- },
- TraitBoundModifier::Maybe(Default::default()),
- );
+ let expected = TypeParamBound::Trait(TraitBound {
+ modifier: TraitBoundModifier::Maybe(Default::default()),
+ lifetimes: None,
+ path: "Sized".into(),
+ });
assert_eq!(
expected,
common::parse::syn::<TypeParamBound>(tokens.into())