itctx: ImplTraitContext,
) -> (hir::GenericArgs, bool) {
let &AngleBracketedArgs { ref args, ref bindings, .. } = data;
+ let has_types = args.iter().any(|arg| match arg {
+ GenericArgAST::Type(_) => true,
+ _ => false,
+ });
(hir::GenericArgs {
args: args.iter().map(|a| self.lower_generic_arg(a, itctx)).collect(),
bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx)).collect(),
parenthesized: false,
},
- data.types().count() == 0 && param_mode == ParamMode::Optional)
+ has_types && param_mode == ParamMode::Optional)
}
fn lower_parenthesized_parameter_data(
ast::TyKind::Path(_, ref path) => path.segments.iter().any(|seg| {
match seg.args.as_ref().map(|generic_arg| &**generic_arg) {
None => false,
- Some(&ast::GenericArgs::AngleBracketed(ref data)) =>
- any_involves_impl_trait(data.types().into_iter()) ||
- any_involves_impl_trait(data.bindings.iter().map(|b| &b.ty)),
- Some(&ast::GenericArgs::Parenthesized(ref data)) =>
+ Some(&ast::GenericArgs::AngleBracketed(ref data)) => {
+ let types = data.args.iter().filter_map(|arg| match arg {
+ ast::GenericArgAST::Type(ty) => Some(ty),
+ _ => None,
+ });
+ any_involves_impl_trait(types.into_iter()) ||
+ any_involves_impl_trait(data.bindings.iter().map(|b| &b.ty))
+ },
+ Some(&ast::GenericArgs::Parenthesized(ref data)) => {
any_involves_impl_trait(data.inputs.iter()) ||
- any_involves_impl_trait(data.output.iter()),
+ any_involves_impl_trait(data.output.iter())
+ }
}
}),
_ => false,
}
fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) {
match *generic_args {
- GenericArgs::AngleBracketed(ref generic_args) => {
- for type_ in generic_args.types() {
- self.visit_ty(type_);
+ GenericArgs::AngleBracketed(ref data) => {
+ for arg in &data.args {
+ match arg {
+ GenericArgAST::Type(ty) => self.visit_ty(ty),
+ _ => {}
+ }
}
- for type_binding in &generic_args.bindings {
+ for type_binding in &data.bindings {
// Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
// are allowed to contain nested `impl Trait`.
self.with_impl_trait(None, |this| visit::walk_ty(this, &type_binding.ty));
}
}
- GenericArgs::Parenthesized(ref generic_args) => {
- for type_ in &generic_args.inputs {
+ GenericArgs::Parenthesized(ref data) => {
+ for type_ in &data.inputs {
self.visit_ty(type_);
}
- if let Some(ref type_) = generic_args.output {
+ if let Some(ref type_) = data.output {
// `-> Foo` syntax is essentially an associated type binding,
// so it is also allowed to contain nested `impl Trait`.
self.with_impl_trait(None, |this| visit::walk_ty(this, type_));
for seg in &path.segments {
if let Some(ref generic_args) = seg.args {
match **generic_args {
- ast::GenericArgs::AngleBracketed(ref data) => for t in data.types() {
- self.visit_ty(t);
- },
+ ast::GenericArgs::AngleBracketed(ref data) => {
+ for arg in &data.args {
+ match arg {
+ ast::GenericArgAST::Type(ty) => self.visit_ty(ty),
+ _ => {}
+ }
+ }
+ }
ast::GenericArgs::Parenthesized(ref data) => {
for t in &data.inputs {
self.visit_ty(t);
// Explicit types in the turbo-fish.
if let Some(ref generic_args) = seg.args {
if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
- for t in data.types() {
- self.visit_ty(t);
+ for arg in &data.args {
+ match arg {
+ ast::GenericArgAST::Type(ty) => self.visit_ty(ty),
+ _ => {}
+ }
}
}
}
pub bindings: Vec<TypeBinding>,
}
-impl AngleBracketedArgs {
- pub fn lifetimes(&self) -> impl DoubleEndedIterator<Item = &Lifetime> {
- self.args.iter().filter_map(|arg| {
- if let GenericArgAST::Lifetime(lt) = arg {
- Some(lt)
- } else {
- None
- }
- })
- }
-
- pub fn types(&self) -> impl DoubleEndedIterator<Item = &P<Ty>> {
- self.args.iter().filter_map(|arg| {
- if let GenericArgAST::Type(ty) = arg {
- Some(ty)
- } else {
- None
- }
- })
- }
-}
-
impl Into<Option<P<GenericArgs>>> for AngleBracketedArgs {
fn into(self) -> Option<P<GenericArgs>> {
Some(P(GenericArgs::AngleBracketed(self)))