• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // vim: tw=80
2 //! Proc Macros for use with Mockall
3 //!
4 //! You probably don't want to use this crate directly.  Instead, you should use
5 //! its reexports via the [`mockall`](https://docs.rs/mockall/latest/mockall)
6 //! crate.
7 
8 #![cfg_attr(feature = "nightly_derive", feature(proc_macro_diagnostic))]
9 #![cfg_attr(test, deny(warnings))]
10 
11 use cfg_if::cfg_if;
12 use proc_macro2::{Span, TokenStream};
13 use quote::{ToTokens, format_ident, quote};
14 use std::{
15     env,
16     hash::BuildHasherDefault
17 };
18 use syn::{
19     *,
20     punctuated::Punctuated,
21     spanned::Spanned
22 };
23 
24 mod automock;
25 mod mock_function;
26 mod mock_item;
27 mod mock_item_struct;
28 mod mock_trait;
29 mod mockable_item;
30 mod mockable_struct;
31 use crate::automock::Attrs;
32 use crate::mockable_struct::MockableStruct;
33 use crate::mock_item::MockItem;
34 use crate::mock_item_struct::MockItemStruct;
35 use crate::mockable_item::MockableItem;
36 
37 extern crate proc_macro;
38 
39 // Define deterministic aliases for these common types.
40 type HashMap<K, V> = std::collections::HashMap<K, V, BuildHasherDefault<std::collections::hash_map::DefaultHasher>>;
41 type HashSet<K> = std::collections::HashSet<K, BuildHasherDefault<std::collections::hash_map::DefaultHasher>>;
42 
43 cfg_if! {
44     // proc-macro2's Span::unstable method requires the nightly feature, and it
45     // doesn't work in test mode.
46     // https://github.com/alexcrichton/proc-macro2/issues/159
47     if #[cfg(all(feature = "nightly_derive", not(test)))] {
48         fn compile_error(span: Span, msg: &str) {
49             span.unstable()
50                 .error(msg)
51                 .emit();
52         }
53     } else {
54         fn compile_error(_span: Span, msg: &str) {
55             panic!("{msg}.  More information may be available when mockall is built with the \"nightly\" feature.");
56         }
57     }
58 }
59 
60 /// Does this Attribute represent Mockall's "concretize" pseudo-attribute?
is_concretize(attr: &Attribute) -> bool61 fn is_concretize(attr: &Attribute) -> bool {
62     if attr.path().segments.last().unwrap().ident == "concretize" {
63         true
64     } else if attr.path().is_ident("cfg_attr") {
65         match &attr.meta {
66             Meta::List(ml) => {
67                 ml.tokens.to_string().contains("concretize")
68             },
69             // cfg_attr should always contain a list
70             _ => false,
71         }
72     } else {
73         false
74     }
75 }
76 
77 /// replace generic arguments with concrete trait object arguments
78 ///
79 /// # Return
80 ///
81 /// * A Generics object with the concretized types removed
82 /// * An array of transformed argument types, suitable for matchers and
83 ///   returners
84 /// * An array of expressions that should be passed to the `call` function.
concretize_args(gen: &Generics, sig: &Signature) -> (Generics, Punctuated<FnArg, Token![,]>, Vec<TokenStream>, Signature)85 fn concretize_args(gen: &Generics, sig: &Signature) ->
86     (Generics, Punctuated<FnArg, Token![,]>, Vec<TokenStream>, Signature)
87 {
88     let args = &sig.inputs;
89     let mut hm = HashMap::default();
90     let mut needs_muts = HashMap::default();
91 
92     let mut save_types = |ident: &Ident, tpb: &Punctuated<TypeParamBound, Token![+]>| {
93         if !tpb.is_empty() {
94             let mut pat = quote!(&(dyn #tpb));
95             let mut needs_mut = false;
96             if let Some(TypeParamBound::Trait(t)) = tpb.first() {
97                 if t.path.segments.first().map(|seg| &seg.ident == "FnMut")
98                     .unwrap_or(false)
99                 {
100                     // For FnMut arguments, the rfunc needs a mutable reference
101                     pat = quote!(&mut (dyn #tpb));
102                     needs_mut = true;
103                 }
104             }
105             if let Ok(newty) = parse2::<Type>(pat) {
106                 // substitute T arguments
107                 let subst_ty: Type = parse2(quote!(#ident)).unwrap();
108                 needs_muts.insert(subst_ty.clone(), needs_mut);
109                 hm.insert(subst_ty, (newty.clone(), None));
110 
111                 // substitute &T arguments
112                 let subst_ty: Type = parse2(quote!(&#ident)).unwrap();
113                 needs_muts.insert(subst_ty.clone(), needs_mut);
114                 hm.insert(subst_ty, (newty, None));
115             } else {
116                 compile_error(tpb.span(),
117                     "Type cannot be made into a trait object");
118             }
119 
120             if let Ok(newty) = parse2::<Type>(quote!(&mut (dyn #tpb))) {
121                 // substitute &mut T arguments
122                 let subst_ty: Type = parse2(quote!(&mut #ident)).unwrap();
123                 needs_muts.insert(subst_ty.clone(), needs_mut);
124                 hm.insert(subst_ty, (newty, None));
125             } else {
126                 compile_error(tpb.span(),
127                     "Type cannot be made into a trait object");
128             }
129 
130             // I wish we could substitute &[T] arguments.  But there's no way
131             // for the mock method to turn &[T] into &[&dyn T].
132             if let Ok(newty) = parse2::<Type>(quote!(&[&(dyn #tpb)])) {
133                 let subst_ty: Type = parse2(quote!(&[#ident])).unwrap();
134                 needs_muts.insert(subst_ty.clone(), needs_mut);
135                 hm.insert(subst_ty, (newty, Some(tpb.clone())));
136             } else {
137                 compile_error(tpb.span(),
138                     "Type cannot be made into a trait object");
139             }
140         }
141     };
142 
143     for g in gen.params.iter() {
144         if let GenericParam::Type(tp) = g {
145             save_types(&tp.ident, &tp.bounds);
146             // else there had better be a where clause
147         }
148     }
149     if let Some(wc) = &gen.where_clause {
150         for pred in wc.predicates.iter() {
151             if let WherePredicate::Type(pt) = pred {
152                 let bounded_ty = &pt.bounded_ty;
153                 if let Ok(ident) = parse2::<Ident>(quote!(#bounded_ty)) {
154                     save_types(&ident, &pt.bounds);
155                 } else {
156                     // We can't yet handle where clauses this complicated
157                 }
158             }
159         }
160     }
161 
162     let outg = Generics {
163         lt_token: None,
164         gt_token: None,
165         params: Punctuated::new(),
166         where_clause: None
167     };
168     let outargs = args.iter().map(|arg| {
169         if let FnArg::Typed(pt) = arg {
170             let mut call_pt = pt.clone();
171             demutify_arg(&mut call_pt);
172             if let Some((newty, _)) = hm.get(&pt.ty) {
173                 FnArg::Typed(PatType {
174                     attrs: Vec::default(),
175                     pat: call_pt.pat,
176                     colon_token: pt.colon_token,
177                     ty: Box::new(newty.clone())
178                 })
179             } else {
180                 FnArg::Typed(PatType {
181                     attrs: Vec::default(),
182                     pat: call_pt.pat,
183                     colon_token: pt.colon_token,
184                     ty: pt.ty.clone()
185                 })
186             }
187         } else {
188             arg.clone()
189         }
190     }).collect();
191 
192     // Finally, Reference any concretizing arguments
193     // use filter_map to remove the &self argument
194     let call_exprs = args.iter().filter_map(|arg| {
195         match arg {
196             FnArg::Typed(pt) => {
197                 let mut pt2 = pt.clone();
198                 demutify_arg(&mut pt2);
199                 let pat = &pt2.pat;
200                 if pat_is_self(pat) {
201                     None
202                 } else if let Some((_, newbound)) = hm.get(&pt.ty) {
203                     if let Type::Reference(tr) = &*pt.ty {
204                         if let Type::Slice(_ts) = &*tr.elem {
205                             // Assume _ts is the generic type or we wouldn't be
206                             // here
207                             Some(quote!(
208                                 &(0..#pat.len())
209                                 .map(|__mockall_i| &#pat[__mockall_i] as &(dyn #newbound))
210                                 .collect::<Vec<_>>()
211                             ))
212                         } else {
213                             Some(quote!(#pat))
214                         }
215                     } else if needs_muts.get(&pt.ty).cloned().unwrap_or(false) {
216                         Some(quote!(&mut #pat))
217                     } else {
218                         Some(quote!(&#pat))
219                     }
220                 } else {
221                     Some(quote!(#pat))
222                 }
223             },
224             FnArg::Receiver(_) => None,
225         }
226     }).collect();
227 
228     // Add any necessary "mut" qualifiers to the Signature
229     let mut altsig = sig.clone();
230     for arg in altsig.inputs.iter_mut() {
231         if let FnArg::Typed(pt) = arg {
232             if needs_muts.get(&pt.ty).cloned().unwrap_or(false) {
233                 if let Pat::Ident(pi) = &mut *pt.pat {
234                     pi.mutability = Some(Token![mut](pi.mutability.span()));
235                 } else {
236                     compile_error(pt.pat.span(),
237                                     "This Pat type is not yet supported by Mockall when used as an argument to a concretized function.")
238                 }
239             }
240         }
241     }
242 
243     (outg, outargs, call_exprs, altsig)
244 }
245 
deanonymize_lifetime(lt: &mut Lifetime)246 fn deanonymize_lifetime(lt: &mut Lifetime) {
247     if lt.ident == "_" {
248         lt.ident = format_ident!("static");
249     }
250 }
251 
deanonymize_path(path: &mut Path)252 fn deanonymize_path(path: &mut Path) {
253     for seg in path.segments.iter_mut() {
254         match &mut seg.arguments {
255             PathArguments::None => (),
256             PathArguments::AngleBracketed(abga) => {
257                 for ga in abga.args.iter_mut() {
258                     if let GenericArgument::Lifetime(lt) = ga {
259                         deanonymize_lifetime(lt)
260                     }
261                 }
262             },
263             _ => compile_error(seg.arguments.span(),
264                 "Methods returning functions are TODO"),
265         }
266     }
267 }
268 
269 /// Replace any references to the anonymous lifetime `'_` with `'static`.
deanonymize(literal_type: &mut Type)270 fn deanonymize(literal_type: &mut Type) {
271     match literal_type {
272         Type::Array(ta) => deanonymize(ta.elem.as_mut()),
273         Type::BareFn(tbf) => {
274             if let ReturnType::Type(_, ref mut bt) = tbf.output {
275                 deanonymize(bt.as_mut());
276             }
277             for input in tbf.inputs.iter_mut() {
278                 deanonymize(&mut input.ty);
279             }
280         },
281         Type::Group(tg) => deanonymize(tg.elem.as_mut()),
282         Type::Infer(_) => (),
283         Type::Never(_) => (),
284         Type::Paren(tp) => deanonymize(tp.elem.as_mut()),
285         Type::Path(tp) => {
286             if let Some(ref mut qself) = tp.qself {
287                 deanonymize(qself.ty.as_mut());
288             }
289             deanonymize_path(&mut tp.path);
290         },
291         Type::Ptr(tptr) => deanonymize(tptr.elem.as_mut()),
292         Type::Reference(tr) => {
293             if let Some(lt) = tr.lifetime.as_mut() {
294                 deanonymize_lifetime(lt)
295             }
296             deanonymize(tr.elem.as_mut());
297         },
298         Type::Slice(s) => deanonymize(s.elem.as_mut()),
299         Type::TraitObject(tto) => {
300             for tpb in tto.bounds.iter_mut() {
301                 match tpb {
302                     TypeParamBound::Trait(tb) => deanonymize_path(&mut tb.path),
303                     TypeParamBound::Lifetime(lt) => deanonymize_lifetime(lt),
304                     _ => ()
305                 }
306             }
307         },
308         Type::Tuple(tt) => {
309             for ty in tt.elems.iter_mut() {
310                 deanonymize(ty)
311             }
312         }
313         x => compile_error(x.span(), "Unimplemented type for deanonymize")
314     }
315 }
316 
317 // If there are any closures in the argument list, turn them into boxed
318 // functions
declosurefy(gen: &Generics, args: &Punctuated<FnArg, Token![,]>) -> (Generics, Punctuated<FnArg, Token![,]>, Vec<TokenStream>)319 fn declosurefy(gen: &Generics, args: &Punctuated<FnArg, Token![,]>) ->
320     (Generics, Punctuated<FnArg, Token![,]>, Vec<TokenStream>)
321 {
322     let mut hm = HashMap::default();
323 
324     let mut save_fn_types = |ident: &Ident, bounds: &Punctuated<TypeParamBound, Token![+]>|
325     {
326         for tpb in bounds.iter() {
327             if let TypeParamBound::Trait(tb) = tpb {
328                 let fident = &tb.path.segments.last().unwrap().ident;
329                 if ["Fn", "FnMut", "FnOnce"].iter().any(|s| fident == *s) {
330                     let newty: Type = parse2(quote!(Box<dyn #bounds>)).unwrap();
331                     let subst_ty: Type = parse2(quote!(#ident)).unwrap();
332                     assert!(hm.insert(subst_ty, newty).is_none(),
333                         "A generic parameter had two Fn bounds?");
334                 }
335             }
336         }
337     };
338 
339     // First, build a HashMap of all Fn generic types
340     for g in gen.params.iter() {
341         if let GenericParam::Type(tp) = g {
342             save_fn_types(&tp.ident, &tp.bounds);
343         }
344     }
345     if let Some(wc) = &gen.where_clause {
346         for pred in wc.predicates.iter() {
347             if let WherePredicate::Type(pt) = pred {
348                 let bounded_ty = &pt.bounded_ty;
349                 if let Ok(ident) = parse2::<Ident>(quote!(#bounded_ty)) {
350                     save_fn_types(&ident, &pt.bounds);
351                 } else {
352                     // We can't yet handle where clauses this complicated
353                 }
354             }
355         }
356     }
357 
358     // Then remove those types from both the Generics' params and where clause
359     let should_remove = |ident: &Ident| {
360             let ty: Type = parse2(quote!(#ident)).unwrap();
361             hm.contains_key(&ty)
362     };
363     let params = gen.params.iter()
364         .filter(|g| {
365             if let GenericParam::Type(tp) = g {
366                 !should_remove(&tp.ident)
367             } else {
368                 true
369             }
370         }).cloned()
371         .collect::<Punctuated<_, _>>();
372     let mut wc2 = gen.where_clause.clone();
373     if let Some(wc) = &mut wc2 {
374         wc.predicates = wc.predicates.iter()
375             .filter(|wp| {
376                 if let WherePredicate::Type(pt) = wp {
377                     let bounded_ty = &pt.bounded_ty;
378                     if let Ok(ident) = parse2::<Ident>(quote!(#bounded_ty)) {
379                         !should_remove(&ident)
380                     } else {
381                         // We can't yet handle where clauses this complicated
382                         true
383                     }
384                 } else {
385                     true
386                 }
387             }).cloned()
388             .collect::<Punctuated<_, _>>();
389         if wc.predicates.is_empty() {
390             wc2 = None;
391         }
392     }
393     let outg = Generics {
394         lt_token: if params.is_empty() { None } else { gen.lt_token },
395         gt_token: if params.is_empty() { None } else { gen.gt_token },
396         params,
397         where_clause: wc2
398     };
399 
400     // Next substitute Box<Fn> into the arguments
401     let outargs = args.iter().map(|arg| {
402         if let FnArg::Typed(pt) = arg {
403             let mut immutable_pt = pt.clone();
404             demutify_arg(&mut immutable_pt);
405             if let Some(newty) = hm.get(&pt.ty) {
406                 FnArg::Typed(PatType {
407                     attrs: Vec::default(),
408                     pat: immutable_pt.pat,
409                     colon_token: pt.colon_token,
410                     ty: Box::new(newty.clone())
411                 })
412             } else {
413                 FnArg::Typed(PatType {
414                     attrs: Vec::default(),
415                     pat: immutable_pt.pat,
416                     colon_token: pt.colon_token,
417                     ty: pt.ty.clone()
418                 })
419             }
420         } else {
421             arg.clone()
422         }
423     }).collect();
424 
425     // Finally, Box any closure arguments
426     // use filter_map to remove the &self argument
427     let callargs = args.iter().filter_map(|arg| {
428         match arg {
429             FnArg::Typed(pt) => {
430                 let mut pt2 = pt.clone();
431                 demutify_arg(&mut pt2);
432                 let pat = &pt2.pat;
433                 if pat_is_self(pat) {
434                     None
435                 } else if hm.contains_key(&pt.ty) {
436                     Some(quote!(Box::new(#pat)))
437                 } else {
438                     Some(quote!(#pat))
439                 }
440             },
441             FnArg::Receiver(_) => None,
442         }
443     }).collect();
444     (outg, outargs, callargs)
445 }
446 
447 /// Replace any "impl trait" types with "Box<dyn trait>" or equivalent.
deimplify(rt: &mut ReturnType)448 fn deimplify(rt: &mut ReturnType) {
449     if let ReturnType::Type(_, ty) = rt {
450         if let Type::ImplTrait(ref tit) = &**ty {
451             let needs_pin = tit.bounds
452                 .iter()
453                 .any(|tpb| {
454                     if let TypeParamBound::Trait(tb) = tpb {
455                         if let Some(seg) = tb.path.segments.last() {
456                             seg.ident == "Future" || seg.ident == "Stream"
457                         } else {
458                             // It might still be a Future, but we can't guess
459                             // what names it might be imported under.  Too bad.
460                             false
461                         }
462                     } else {
463                         false
464                     }
465                 });
466             let bounds = &tit.bounds;
467             if needs_pin {
468                 *ty = parse2(quote!(::std::pin::Pin<Box<dyn #bounds>>)).unwrap();
469             } else {
470                 *ty = parse2(quote!(Box<dyn #bounds>)).unwrap();
471             }
472         }
473     }
474 }
475 
476 /// Remove any generics that place constraints on Self.
dewhereselfify(generics: &mut Generics)477 fn dewhereselfify(generics: &mut Generics) {
478     if let Some(ref mut wc) = &mut generics.where_clause {
479         let new_predicates = wc.predicates.iter()
480             .filter(|wp| match wp {
481                 WherePredicate::Type(pt) => {
482                     pt.bounded_ty != parse2(quote!(Self)).unwrap()
483                 },
484                 _ => true
485             }).cloned()
486             .collect::<Punctuated<WherePredicate, Token![,]>>();
487         wc.predicates = new_predicates;
488     }
489     if generics.where_clause.as_ref()
490         .map(|wc| wc.predicates.is_empty())
491         .unwrap_or(false)
492     {
493         generics.where_clause = None;
494     }
495 }
496 
497 /// Remove any mutability qualifiers from a method's argument list
demutify(inputs: &mut Punctuated<FnArg, token::Comma>)498 fn demutify(inputs: &mut Punctuated<FnArg, token::Comma>) {
499     for arg in inputs.iter_mut() {
500         match arg {
501             FnArg::Receiver(r) => if r.reference.is_none() {
502                 r.mutability = None
503             },
504             FnArg::Typed(pt) => demutify_arg(pt),
505         }
506     }
507 }
508 
509 /// Remove any "mut" from a method argument's binding.
demutify_arg(arg: &mut PatType)510 fn demutify_arg(arg: &mut PatType) {
511     match *arg.pat {
512         Pat::Wild(_) => {
513             compile_error(arg.span(),
514                 "Mocked methods must have named arguments");
515         },
516         Pat::Ident(ref mut pat_ident) => {
517             if let Some(r) = &pat_ident.by_ref {
518                 compile_error(r.span(),
519                     "Mockall does not support by-reference argument bindings");
520             }
521             if let Some((_at, subpat)) = &pat_ident.subpat {
522                 compile_error(subpat.span(),
523                     "Mockall does not support subpattern bindings");
524             }
525             pat_ident.mutability = None;
526         },
527         _ => {
528             compile_error(arg.span(), "Unsupported argument type");
529         }
530     };
531 }
532 
deselfify_path(path: &mut Path, actual: &Ident, generics: &Generics)533 fn deselfify_path(path: &mut Path, actual: &Ident, generics: &Generics) {
534     for seg in path.segments.iter_mut() {
535         if seg.ident == "Self" {
536             seg.ident = actual.clone();
537             if let PathArguments::None = seg.arguments {
538                 if !generics.params.is_empty() {
539                     let args = generics.params.iter()
540                         .map(|gp| {
541                             match gp {
542                                 GenericParam::Type(tp) => {
543                                     let ident = tp.ident.clone();
544                                     GenericArgument::Type(
545                                         Type::Path(
546                                             TypePath {
547                                                 qself: None,
548                                                 path: Path::from(ident)
549                                             }
550                                         )
551                                     )
552                                 },
553                                 GenericParam::Lifetime(ld) =>{
554                                     GenericArgument::Lifetime(
555                                         ld.lifetime.clone()
556                                     )
557                                 }
558                                 _ => unimplemented!(),
559                             }
560                         }).collect::<Punctuated<_, _>>();
561                     seg.arguments = PathArguments::AngleBracketed(
562                         AngleBracketedGenericArguments {
563                             colon2_token: None,
564                             lt_token: generics.lt_token.unwrap(),
565                             args,
566                             gt_token: generics.gt_token.unwrap(),
567                         }
568                     );
569                 }
570             } else {
571                 compile_error(seg.arguments.span(),
572                     "Type arguments after Self are unexpected");
573             }
574         }
575         if let PathArguments::AngleBracketed(abga) = &mut seg.arguments
576         {
577             for arg in abga.args.iter_mut() {
578                 match arg {
579                     GenericArgument::Type(ty) =>
580                         deselfify(ty, actual, generics),
581                     GenericArgument::AssocType(at) =>
582                         deselfify(&mut at.ty, actual, generics),
583                     _ => /* Nothing to do */(),
584                 }
585             }
586         }
587     }
588 }
589 
590 /// Replace any references to `Self` in `literal_type` with `actual`.
591 /// `generics` is the Generics field of the parent struct.  Useful for
592 /// constructor methods.
deselfify(literal_type: &mut Type, actual: &Ident, generics: &Generics)593 fn deselfify(literal_type: &mut Type, actual: &Ident, generics: &Generics) {
594     match literal_type {
595         Type::Slice(s) => {
596             deselfify(s.elem.as_mut(), actual, generics);
597         },
598         Type::Array(a) => {
599             deselfify(a.elem.as_mut(), actual, generics);
600         },
601         Type::Ptr(p) => {
602             deselfify(p.elem.as_mut(), actual, generics);
603         },
604         Type::Reference(r) => {
605             deselfify(r.elem.as_mut(), actual, generics);
606         },
607         Type::Tuple(tuple) => {
608             for elem in tuple.elems.iter_mut() {
609                 deselfify(elem, actual, generics);
610             }
611         }
612         Type::Path(type_path) => {
613             if let Some(ref mut qself) = type_path.qself {
614                 deselfify(qself.ty.as_mut(), actual, generics);
615             }
616             deselfify_path(&mut type_path.path, actual, generics);
617         },
618         Type::Paren(p) => {
619             deselfify(p.elem.as_mut(), actual, generics);
620         },
621         Type::Group(g) => {
622             deselfify(g.elem.as_mut(), actual, generics);
623         },
624         Type::Macro(_) | Type::Verbatim(_) => {
625             compile_error(literal_type.span(),
626                 "mockall_derive does not support this type as a return argument");
627         },
628         Type::TraitObject(tto) => {
629             // Change types like `dyn Self` into `dyn MockXXX`.
630             for bound in tto.bounds.iter_mut() {
631                 if let TypeParamBound::Trait(t) = bound {
632                     deselfify_path(&mut t.path, actual, generics);
633                 }
634             }
635         },
636         Type::ImplTrait(_) => {
637             /* Should've already been flagged as a compile_error */
638         },
639         Type::BareFn(_) => {
640             /* Bare functions can't have Self arguments.  Nothing to do */
641         },
642         Type::Infer(_) | Type::Never(_) =>
643         {
644             /* Nothing to do */
645         },
646         _ => compile_error(literal_type.span(), "Unsupported type"),
647     }
648 }
649 
650 /// Change any `Self` in a method's arguments' types with `actual`.
651 /// `generics` is the Generics field of the parent struct.
deselfify_args( args: &mut Punctuated<FnArg, Token![,]>, actual: &Ident, generics: &Generics)652 fn deselfify_args(
653     args: &mut Punctuated<FnArg, Token![,]>,
654     actual: &Ident,
655     generics: &Generics)
656 {
657     for arg in args.iter_mut() {
658         match arg {
659             FnArg::Receiver(r) => {
660                 if r.colon_token.is_some() {
661                     deselfify(r.ty.as_mut(), actual, generics)
662                 }
663             },
664             FnArg::Typed(pt) => deselfify(pt.ty.as_mut(), actual, generics)
665         }
666     }
667 }
668 
find_ident_from_path(path: &Path) -> (Ident, PathArguments)669 fn find_ident_from_path(path: &Path) -> (Ident, PathArguments) {
670     if path.segments.len() != 1 {
671         compile_error(path.span(),
672             "mockall_derive only supports structs defined in the current module");
673         return (Ident::new("", path.span()), PathArguments::None);
674     }
675     let last_seg = path.segments.last().unwrap();
676     (last_seg.ident.clone(), last_seg.arguments.clone())
677 }
678 
find_lifetimes_in_tpb(bound: &TypeParamBound) -> HashSet<Lifetime>679 fn find_lifetimes_in_tpb(bound: &TypeParamBound) -> HashSet<Lifetime> {
680     let mut ret = HashSet::default();
681     match bound {
682         TypeParamBound::Lifetime(lt) => {
683             ret.insert(lt.clone());
684         },
685         TypeParamBound::Trait(tb) => {
686             ret.extend(find_lifetimes_in_path(&tb.path));
687         },
688         _ => ()
689     };
690     ret
691 }
692 
find_lifetimes_in_path(path: &Path) -> HashSet<Lifetime>693 fn find_lifetimes_in_path(path: &Path) -> HashSet<Lifetime> {
694     let mut ret = HashSet::default();
695     for seg in path.segments.iter() {
696         if let PathArguments::AngleBracketed(abga) = &seg.arguments {
697             for arg in abga.args.iter() {
698                 match arg {
699                     GenericArgument::Lifetime(lt) => {
700                         ret.insert(lt.clone());
701                     },
702                     GenericArgument::Type(ty) => {
703                         ret.extend(find_lifetimes(ty));
704                     },
705                     GenericArgument::AssocType(at) => {
706                         ret.extend(find_lifetimes(&at.ty));
707                     },
708                     GenericArgument::Constraint(c) => {
709                         for bound in c.bounds.iter() {
710                             ret.extend(find_lifetimes_in_tpb(bound));
711                         }
712                     },
713                     GenericArgument::Const(_) => (),
714                     _ => ()
715                 }
716             }
717         }
718     }
719     ret
720 }
721 
find_lifetimes(ty: &Type) -> HashSet<Lifetime>722 fn find_lifetimes(ty: &Type) -> HashSet<Lifetime> {
723     match ty {
724         Type::Array(ta) => find_lifetimes(ta.elem.as_ref()),
725         Type::Group(tg) => find_lifetimes(tg.elem.as_ref()),
726         Type::Infer(_ti) => HashSet::default(),
727         Type::Never(_tn) => HashSet::default(),
728         Type::Paren(tp) => find_lifetimes(tp.elem.as_ref()),
729         Type::Path(tp) => {
730             let mut ret = find_lifetimes_in_path(&tp.path);
731             if let Some(qs) = &tp.qself {
732                 ret.extend(find_lifetimes(qs.ty.as_ref()));
733             }
734             ret
735         },
736         Type::Ptr(tp) => find_lifetimes(tp.elem.as_ref()),
737         Type::Reference(tr) => {
738             let mut ret = find_lifetimes(tr.elem.as_ref());
739             if let Some(lt) = &tr.lifetime {
740                 ret.insert(lt.clone());
741             }
742             ret
743         },
744         Type::Slice(ts) => find_lifetimes(ts.elem.as_ref()),
745         Type::TraitObject(tto) => {
746             let mut ret = HashSet::default();
747             for bound in tto.bounds.iter() {
748                 ret.extend(find_lifetimes_in_tpb(bound));
749             }
750             ret
751         }
752         Type::Tuple(tt) => {
753             let mut ret = HashSet::default();
754             for ty in tt.elems.iter() {
755                 ret.extend(find_lifetimes(ty));
756             }
757             ret
758         },
759         Type::ImplTrait(tit) => {
760             let mut ret = HashSet::default();
761             for tpb in tit.bounds.iter() {
762                 ret.extend(find_lifetimes_in_tpb(tpb));
763             }
764             ret
765         },
766         _ => {
767             compile_error(ty.span(), "unsupported type in this context");
768             HashSet::default()
769         }
770     }
771 }
772 
773 struct AttrFormatter<'a>{
774     attrs: &'a [Attribute],
775     async_trait: bool,
776     doc: bool,
777     must_use: bool,
778 }
779 
780 impl<'a> AttrFormatter<'a> {
new(attrs: &'a [Attribute]) -> AttrFormatter<'a>781     fn new(attrs: &'a [Attribute]) -> AttrFormatter<'a> {
782         Self {
783             attrs,
784             async_trait: true,
785             doc: true,
786             must_use: false,
787         }
788     }
789 
async_trait(&mut self, allowed: bool) -> &mut Self790     fn async_trait(&mut self, allowed: bool) -> &mut Self {
791         self.async_trait = allowed;
792         self
793     }
794 
doc(&mut self, allowed: bool) -> &mut Self795     fn doc(&mut self, allowed: bool) -> &mut Self {
796         self.doc = allowed;
797         self
798     }
799 
must_use(&mut self, allowed: bool) -> &mut Self800     fn must_use(&mut self, allowed: bool) -> &mut Self {
801         self.must_use = allowed;
802         self
803     }
804 
805     // XXX This logic requires that attributes are imported with their
806     // standard names.
807     #[allow(clippy::needless_bool)]
808     #[allow(clippy::if_same_then_else)]
format(&mut self) -> Vec<Attribute>809     fn format(&mut self) -> Vec<Attribute> {
810         self.attrs.iter()
811             .filter(|attr| {
812                 let i = attr.path().segments.last().map(|ps| &ps.ident);
813                 if is_concretize(attr) {
814                     // Internally used attribute.  Never emit.
815                     false
816                 } else if i.is_none() {
817                     false
818                 } else if *i.as_ref().unwrap() == "derive" {
819                     // We can't usefully derive any traits.  Ignore them
820                     false
821                 } else if *i.as_ref().unwrap() == "doc" {
822                     self.doc
823                 } else if *i.as_ref().unwrap() == "async_trait" {
824                     self.async_trait
825                 } else if *i.as_ref().unwrap() == "expect" {
826                     // This probably means that there's a lint that needs to be
827                     // surpressed for the real code, but not for the mock code.
828                     // Skip it.
829                     false
830                 } else if *i.as_ref().unwrap() == "inline" {
831                     // No need to inline mock functions.
832                     false
833                 } else if *i.as_ref().unwrap() == "cold" {
834                     // No need for such hints on mock functions.
835                     false
836                 } else if *i.as_ref().unwrap() == "instrument" {
837                     // We can't usefully instrument the mock method, so just
838                     // ignore this attribute.
839                     // https://docs.rs/tracing/0.1.23/tracing/attr.instrument.html
840                     false
841                 } else if *i.as_ref().unwrap() == "link_name" {
842                     // This shows up sometimes when mocking ffi functions.  We
843                     // must not emit it on anything that isn't an ffi definition
844                     false
845                 } else if *i.as_ref().unwrap() == "must_use" {
846                     self.must_use
847                 } else if *i.as_ref().unwrap() == "auto_enum" {
848                     // Ignore auto_enum, because we transform the return value
849                     // into a trait object.
850                     false
851                 } else {
852                     true
853                 }
854             }).cloned()
855             .collect()
856     }
857 }
858 
859 /// Determine if this Pat is any kind of `self` binding
pat_is_self(pat: &Pat) -> bool860 fn pat_is_self(pat: &Pat) -> bool {
861     if let Pat::Ident(pi) = pat {
862         pi.ident == "self"
863     } else {
864         false
865     }
866 }
867 
868 /// Add `levels` `super::` to the path.  Return the number of levels added.
supersuperfy_path(path: &mut Path, levels: usize) -> usize869 fn supersuperfy_path(path: &mut Path, levels: usize) -> usize {
870     if let Some(t) = path.segments.last_mut() {
871         match &mut t.arguments {
872             PathArguments::None => (),
873             PathArguments::AngleBracketed(ref mut abga) => {
874                 for arg in abga.args.iter_mut() {
875                     match arg {
876                         GenericArgument::Type(ref mut ty) => {
877                             *ty = supersuperfy(ty, levels);
878                         },
879                         GenericArgument::AssocType(ref mut at) => {
880                             at.ty = supersuperfy(&at.ty, levels);
881                         },
882                         GenericArgument::Constraint(ref mut constraint) => {
883                             supersuperfy_bounds(&mut constraint.bounds, levels);
884                         },
885                         _ => (),
886                     }
887                 }
888             },
889             PathArguments::Parenthesized(ref mut pga) => {
890                 for input in pga.inputs.iter_mut() {
891                     *input = supersuperfy(input, levels);
892                 }
893                 if let ReturnType::Type(_, ref mut ty) = pga.output {
894                     *ty = Box::new(supersuperfy(ty, levels));
895                 }
896             },
897         }
898     }
899     if let Some(t) = path.segments.first() {
900         if t.ident == "super" {
901             let mut ident = format_ident!("super");
902             ident.set_span(path.segments.span());
903             let ps = PathSegment {
904                 ident,
905                 arguments: PathArguments::None
906             };
907             for _ in 0..levels {
908                 path.segments.insert(0, ps.clone());
909             }
910             levels
911         } else {
912             0
913         }
914     } else {
915         0
916     }
917 }
918 
919 /// Replace any references to `super::X` in `original` with `super::super::X`.
supersuperfy(original: &Type, levels: usize) -> Type920 fn supersuperfy(original: &Type, levels: usize) -> Type {
921     let mut output = original.clone();
922     fn recurse(t: &mut Type, levels: usize) {
923         match t {
924             Type::Slice(s) => {
925                 recurse(s.elem.as_mut(), levels);
926             },
927             Type::Array(a) => {
928                 recurse(a.elem.as_mut(), levels);
929             },
930             Type::Ptr(p) => {
931                 recurse(p.elem.as_mut(), levels);
932             },
933             Type::Reference(r) => {
934                 recurse(r.elem.as_mut(), levels);
935             },
936             Type::BareFn(bfn) => {
937                 if let ReturnType::Type(_, ref mut bt) = bfn.output {
938                     recurse(bt.as_mut(), levels);
939                 }
940                 for input in bfn.inputs.iter_mut() {
941                     recurse(&mut input.ty, levels);
942                 }
943             },
944             Type::Tuple(tuple) => {
945                 for elem in tuple.elems.iter_mut() {
946                     recurse(elem, levels);
947                 }
948             }
949             Type::Path(type_path) => {
950                 let added = supersuperfy_path(&mut type_path.path, levels);
951                 if let Some(ref mut qself) = type_path.qself {
952                     recurse(qself.ty.as_mut(), levels);
953                     qself.position += added;
954                 }
955             },
956             Type::Paren(p) => {
957                 recurse(p.elem.as_mut(), levels);
958             },
959             Type::Group(g) => {
960                 recurse(g.elem.as_mut(), levels);
961             },
962             Type::Macro(_) | Type::Verbatim(_) => {
963                 compile_error(t.span(),
964                     "mockall_derive does not support this type in this position");
965             },
966             Type::TraitObject(tto) => {
967                 for bound in tto.bounds.iter_mut() {
968                     if let TypeParamBound::Trait(tb) = bound {
969                         supersuperfy_path(&mut tb.path, levels);
970                     }
971                 }
972             },
973             Type::ImplTrait(_) => {
974                 /* Should've already been flagged as a compile error */
975             },
976             Type::Infer(_) | Type::Never(_) =>
977             {
978                 /* Nothing to do */
979             },
980             _ => compile_error(t.span(), "Unsupported type"),
981         }
982     }
983     recurse(&mut output, levels);
984     output
985 }
986 
supersuperfy_generics(generics: &mut Generics, levels: usize)987 fn supersuperfy_generics(generics: &mut Generics, levels: usize) {
988     for param in generics.params.iter_mut() {
989         if let GenericParam::Type(tp) = param {
990             supersuperfy_bounds(&mut tp.bounds, levels);
991             if let Some(ty) = tp.default.as_mut() {
992                 *ty = supersuperfy(ty, levels);
993             }
994         }
995     }
996     if let Some(wc) = generics.where_clause.as_mut() {
997         for wp in wc.predicates.iter_mut() {
998             if let WherePredicate::Type(pt) = wp {
999                 pt.bounded_ty = supersuperfy(&pt.bounded_ty, levels);
1000                 supersuperfy_bounds(&mut pt.bounds, levels);
1001             }
1002         }
1003     }
1004 }
1005 
supersuperfy_bounds( bounds: &mut Punctuated<TypeParamBound, Token![+]>, levels: usize)1006 fn supersuperfy_bounds(
1007     bounds: &mut Punctuated<TypeParamBound, Token![+]>,
1008     levels: usize)
1009 {
1010     for bound in bounds.iter_mut() {
1011         if let TypeParamBound::Trait(tb) = bound {
1012             supersuperfy_path(&mut tb.path, levels);
1013         }
1014     }
1015 }
1016 
1017 /// Generate a suitable mockall::Key generic paramter from any Generics
gen_keyid(g: &Generics) -> impl ToTokens1018 fn gen_keyid(g: &Generics) -> impl ToTokens {
1019     match g.params.len() {
1020         0 => quote!(<()>),
1021         1 => {
1022             let (_, tg, _) = g.split_for_impl();
1023             quote!(#tg)
1024         },
1025         _ => {
1026             // Rust doesn't support variadic Generics, so mockall::Key must
1027             // always have exactly one generic type.  We need to add parentheses
1028             // around whatever type generics the caller passes.
1029             let tps = g.type_params()
1030             .map(|tp| tp.ident.clone())
1031             .collect::<Punctuated::<Ident, Token![,]>>();
1032             quote!(<(#tps)>)
1033         }
1034     }
1035 }
1036 
1037 /// Generate a mock identifier from the regular one: eg "Foo" => "MockFoo"
gen_mock_ident(ident: &Ident) -> Ident1038 fn gen_mock_ident(ident: &Ident) -> Ident {
1039     format_ident!("Mock{}", ident)
1040 }
1041 
1042 /// Generate an identifier for the mock struct's private module: eg "Foo" =>
1043 /// "__mock_Foo"
gen_mod_ident(struct_: &Ident, trait_: Option<&Ident>) -> Ident1044 fn gen_mod_ident(struct_: &Ident, trait_: Option<&Ident>) -> Ident {
1045     if let Some(t) = trait_ {
1046         format_ident!("__mock_{struct_}_{}", t)
1047     } else {
1048         format_ident!("__mock_{struct_}")
1049     }
1050 }
1051 
1052 /// Combine two Generics structs, producing a new one that has the union of
1053 /// their parameters.
merge_generics(x: &Generics, y: &Generics) -> Generics1054 fn merge_generics(x: &Generics, y: &Generics) -> Generics {
1055     /// Compare only the identifiers of two GenericParams
1056     fn cmp_gp_idents(x: &GenericParam, y: &GenericParam) -> bool {
1057         use GenericParam::*;
1058 
1059         match (x, y) {
1060             (Type(xtp), Type(ytp)) => xtp.ident == ytp.ident,
1061             (Lifetime(xld), Lifetime(yld)) => xld.lifetime == yld.lifetime,
1062             (Const(xc), Const(yc)) => xc.ident == yc.ident,
1063             _ => false
1064         }
1065     }
1066 
1067     /// Compare only the identifiers of two WherePredicates
1068     fn cmp_wp_idents(x: &WherePredicate, y: &WherePredicate) -> bool {
1069         use WherePredicate::*;
1070 
1071         match (x, y) {
1072             (Type(xpt), Type(ypt)) => xpt.bounded_ty == ypt.bounded_ty,
1073             (Lifetime(xpl), Lifetime(ypl)) => xpl.lifetime == ypl.lifetime,
1074             _ => false
1075         }
1076     }
1077 
1078     let mut out = if x.lt_token.is_none() && x.where_clause.is_none() {
1079         y.clone()
1080     } else if y.lt_token.is_none() && y.where_clause.is_none() {
1081         x.clone()
1082     } else {
1083         let mut out = x.clone();
1084         // First merge the params
1085         'outer_param: for yparam in y.params.iter() {
1086             // XXX: O(n^2) loop
1087             for outparam in out.params.iter_mut() {
1088                 if cmp_gp_idents(outparam, yparam) {
1089                     if let (GenericParam::Type(ref mut ot),
1090                             GenericParam::Type(yt)) = (outparam, yparam)
1091                     {
1092                         ot.attrs.extend(yt.attrs.iter().cloned());
1093                         ot.colon_token = ot.colon_token.or(yt.colon_token);
1094                         ot.eq_token = ot.eq_token.or(yt.eq_token);
1095                         if ot.default.is_none() {
1096                             ot.default.clone_from(&yt.default);
1097                         }
1098                         // XXX this might result in duplicate bounds
1099                         if ot.bounds != yt.bounds {
1100                             ot.bounds.extend(yt.bounds.iter().cloned());
1101                         }
1102                     }
1103                     continue 'outer_param;
1104                 }
1105             }
1106             out.params.push(yparam.clone());
1107         }
1108         out
1109     };
1110     // Then merge the where clauses
1111     match (&mut out.where_clause, &y.where_clause) {
1112         (_, None) => (),
1113         (None, Some(wc)) => out.where_clause = Some(wc.clone()),
1114         (Some(out_wc), Some(y_wc)) => {
1115             'outer_wc: for ypred in y_wc.predicates.iter() {
1116                 // XXX: O(n^2) loop
1117                 for outpred in out_wc.predicates.iter_mut() {
1118                     if cmp_wp_idents(outpred, ypred) {
1119                         if let (WherePredicate::Type(ref mut ot),
1120                                 WherePredicate::Type(yt)) = (outpred, ypred)
1121                         {
1122                             match (&mut ot.lifetimes, &yt.lifetimes) {
1123                                 (_, None) => (),
1124                                 (None, Some(bl)) =>
1125                                     ot.lifetimes = Some(bl.clone()),
1126                                 (Some(obl), Some(ybl)) =>
1127                                     // XXX: might result in duplicates
1128                                     obl.lifetimes.extend(
1129                                         ybl.lifetimes.iter().cloned()),
1130                             };
1131                             // XXX: might result in duplicate bounds
1132                             if ot.bounds != yt.bounds {
1133                                 ot.bounds.extend(yt.bounds.iter().cloned())
1134                             }
1135                         }
1136                         continue 'outer_wc;
1137                     }
1138                 }
1139                 out_wc.predicates.push(ypred.clone());
1140             }
1141         }
1142     }
1143     out
1144 }
1145 
lifetimes_to_generic_params(lv: &Punctuated<LifetimeParam, Token![,]>) -> Punctuated<GenericParam, Token![,]>1146 fn lifetimes_to_generic_params(lv: &Punctuated<LifetimeParam, Token![,]>)
1147     -> Punctuated<GenericParam, Token![,]>
1148 {
1149     lv.iter()
1150         .map(|lt| GenericParam::Lifetime(lt.clone()))
1151         .collect()
1152 }
1153 
1154 /// Transform a Vec of lifetimes into a Generics
lifetimes_to_generics(lv: &Punctuated<LifetimeParam, Token![,]>)-> Generics1155 fn lifetimes_to_generics(lv: &Punctuated<LifetimeParam, Token![,]>)-> Generics {
1156     if lv.is_empty() {
1157             Generics::default()
1158     } else {
1159         let params = lifetimes_to_generic_params(lv);
1160         Generics {
1161             lt_token: Some(Token![<](lv[0].span())),
1162             gt_token: Some(Token![>](lv[0].span())),
1163             params,
1164             where_clause: None
1165         }
1166     }
1167 }
1168 
1169 /// Split a generics list into three: one for type generics and where predicates
1170 /// that relate to the signature, one for lifetimes that relate to the arguments
1171 /// only, and one for lifetimes that relate to the return type only.
split_lifetimes( generics: Generics, args: &Punctuated<FnArg, Token![,]>, rt: &ReturnType) -> (Generics, Punctuated<LifetimeParam, token::Comma>, Punctuated<LifetimeParam, token::Comma>)1172 fn split_lifetimes(
1173     generics: Generics,
1174     args: &Punctuated<FnArg, Token![,]>,
1175     rt: &ReturnType)
1176     -> (Generics,
1177         Punctuated<LifetimeParam, token::Comma>,
1178         Punctuated<LifetimeParam, token::Comma>)
1179 {
1180     if generics.lt_token.is_none() {
1181         return (generics, Default::default(), Default::default());
1182     }
1183 
1184     // Check which types and lifetimes are referenced by the arguments
1185     let mut alts = HashSet::<Lifetime>::default();
1186     let mut rlts = HashSet::<Lifetime>::default();
1187     for arg in args {
1188         match arg {
1189             FnArg::Receiver(r) => {
1190                 if let Some((_, Some(lt))) = &r.reference {
1191                     alts.insert(lt.clone());
1192                 }
1193             },
1194             FnArg::Typed(pt) => {
1195                 alts.extend(find_lifetimes(pt.ty.as_ref()));
1196             },
1197         };
1198     };
1199 
1200     if let ReturnType::Type(_, ty) = rt {
1201         rlts.extend(find_lifetimes(ty));
1202     }
1203 
1204     let mut tv = Punctuated::new();
1205     let mut alv = Punctuated::new();
1206     let mut rlv = Punctuated::new();
1207     for p in generics.params.into_iter() {
1208         match p {
1209             GenericParam::Lifetime(ltd) if rlts.contains(&ltd.lifetime) =>
1210                 rlv.push(ltd),
1211             GenericParam::Lifetime(ltd) if alts.contains(&ltd.lifetime) =>
1212                 alv.push(ltd),
1213             GenericParam::Lifetime(_) => {
1214                 // Probably a lifetime parameter from the impl block that isn't
1215                 // used by this particular method
1216             },
1217             GenericParam::Type(_) => tv.push(p),
1218             _ => (),
1219         }
1220     }
1221 
1222     let tg = if tv.is_empty() {
1223         Generics::default()
1224     } else {
1225         Generics {
1226             lt_token: generics.lt_token,
1227             gt_token: generics.gt_token,
1228             params: tv,
1229             where_clause: generics.where_clause
1230         }
1231     };
1232 
1233     (tg, alv, rlv)
1234 }
1235 
1236 /// Return the visibility that should be used for expectation!, given the
1237 /// original method's visibility.
1238 ///
1239 /// # Arguments
1240 /// - `vis`:    Original visibility of the item
1241 /// - `levels`: How many modules will the mock item be nested in?
expectation_visibility(vis: &Visibility, levels: usize) -> Visibility1242 fn expectation_visibility(vis: &Visibility, levels: usize)
1243     -> Visibility
1244 {
1245     if levels == 0 {
1246         return vis.clone();
1247     }
1248 
1249     let in_token = Token![in](vis.span());
1250     let super_token = Token![super](vis.span());
1251     match vis {
1252         Visibility::Inherited => {
1253             // Private items need pub(in super::[...]) for each level
1254             let mut path = Path::from(super_token);
1255             for _ in 1..levels {
1256                 path.segments.push(super_token.into());
1257             }
1258             Visibility::Restricted(VisRestricted{
1259                 pub_token: Token![pub](vis.span()),
1260                 paren_token: token::Paren::default(),
1261                 in_token: Some(in_token),
1262                 path: Box::new(path)
1263             })
1264         },
1265         Visibility::Restricted(vr) => {
1266             // crate => don't change
1267             // in crate::* => don't change
1268             // super => in super::super::super
1269             // self => in super::super
1270             // in anything_else => super::super::anything_else
1271             if vr.path.segments.first().unwrap().ident == "crate" {
1272                 Visibility::Restricted(vr.clone())
1273             } else {
1274                 let mut out = vr.clone();
1275                 out.in_token = Some(in_token);
1276                 for _ in 0..levels {
1277                     out.path.segments.insert(0, super_token.into());
1278                 }
1279                 Visibility::Restricted(out)
1280             }
1281         },
1282         _ => vis.clone()
1283     }
1284 }
1285 
staticize(generics: &Generics) -> Generics1286 fn staticize(generics: &Generics) -> Generics {
1287     let mut ret = generics.clone();
1288     for lt in ret.lifetimes_mut() {
1289         lt.lifetime = Lifetime::new("'static", Span::call_site());
1290     };
1291     ret
1292 }
1293 
mock_it<M: Into<MockableItem>>(inputs: M) -> TokenStream1294 fn mock_it<M: Into<MockableItem>>(inputs: M) -> TokenStream
1295 {
1296     let mockable: MockableItem = inputs.into();
1297     let mock = MockItem::from(mockable);
1298     let ts = mock.into_token_stream();
1299     if env::var("MOCKALL_DEBUG").is_ok() {
1300         println!("{ts}");
1301     }
1302     ts
1303 }
1304 
do_mock_once(input: TokenStream) -> TokenStream1305 fn do_mock_once(input: TokenStream) -> TokenStream
1306 {
1307     let item: MockableStruct = match syn::parse2(input) {
1308         Ok(mock) => mock,
1309         Err(err) => {
1310             return err.to_compile_error();
1311         }
1312     };
1313     mock_it(item)
1314 }
1315 
do_mock(input: TokenStream) -> TokenStream1316 fn do_mock(input: TokenStream) -> TokenStream
1317 {
1318     cfg_if! {
1319         if #[cfg(reprocheck)] {
1320             let ts_a = do_mock_once(input.clone());
1321             let ts_b = do_mock_once(input.clone());
1322             assert_eq!(ts_a.to_string(), ts_b.to_string());
1323         }
1324     }
1325     do_mock_once(input)
1326 }
1327 
1328 #[proc_macro_attribute]
concretize( _attrs: proc_macro::TokenStream, input: proc_macro::TokenStream) -> proc_macro::TokenStream1329 pub fn concretize(
1330     _attrs: proc_macro::TokenStream,
1331     input: proc_macro::TokenStream) -> proc_macro::TokenStream
1332 {
1333     // Do nothing.  This "attribute" is processed as text by the real proc
1334     // macros.
1335     input
1336 }
1337 
1338 #[proc_macro]
mock(input: proc_macro::TokenStream) -> proc_macro::TokenStream1339 pub fn mock(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
1340     do_mock(input.into()).into()
1341 }
1342 
1343 #[proc_macro_attribute]
automock(attrs: proc_macro::TokenStream, input: proc_macro::TokenStream) -> proc_macro::TokenStream1344 pub fn automock(attrs: proc_macro::TokenStream, input: proc_macro::TokenStream)
1345     -> proc_macro::TokenStream
1346 {
1347     let attrs: proc_macro2::TokenStream = attrs.into();
1348     let input: proc_macro2::TokenStream = input.into();
1349     do_automock(attrs, input).into()
1350 }
1351 
do_automock_once(attrs: TokenStream, input: TokenStream) -> TokenStream1352 fn do_automock_once(attrs: TokenStream, input: TokenStream) -> TokenStream {
1353     let mut output = input.clone();
1354     let attrs: Attrs = match parse2(attrs) {
1355         Ok(a) => a,
1356         Err(err) => {
1357             return err.to_compile_error();
1358         }
1359     };
1360     let item: Item = match parse2(input) {
1361         Ok(item) => item,
1362         Err(err) => {
1363             return err.to_compile_error();
1364         }
1365     };
1366     output.extend(mock_it((attrs, item)));
1367     output
1368 }
1369 
do_automock(attrs: TokenStream, input: TokenStream) -> TokenStream1370 fn do_automock(attrs: TokenStream, input: TokenStream) -> TokenStream {
1371     cfg_if! {
1372         if #[cfg(reprocheck)] {
1373             let ts_a = do_automock_once(attrs.clone(), input.clone());
1374             let ts_b = do_automock_once(attrs.clone(), input.clone());
1375             assert_eq!(ts_a.to_string(), ts_b.to_string());
1376         }
1377     }
1378     do_automock_once(attrs, input)
1379 }
1380 
1381 #[cfg(test)]
1382 mod t {
1383     use super::*;
1384 
assert_contains(output: &str, tokens: TokenStream)1385 fn assert_contains(output: &str, tokens: TokenStream) {
1386     let s = tokens.to_string();
1387     assert!(output.contains(&s), "output does not contain {:?}", &s);
1388 }
1389 
assert_not_contains(output: &str, tokens: TokenStream)1390 fn assert_not_contains(output: &str, tokens: TokenStream) {
1391     let s = tokens.to_string();
1392     assert!(!output.contains(&s), "output contains {:?}", &s);
1393 }
1394 
1395 /// Various tests for overall code generation that are hard or impossible to
1396 /// write as integration tests
1397 mod mock {
1398     use std::str::FromStr;
1399     use super::super::*;
1400     use super::*;
1401 
1402     #[test]
inherent_method_visibility()1403     fn inherent_method_visibility() {
1404         let code = "
1405             Foo {
1406                 fn foo(&self);
1407                 pub fn bar(&self);
1408                 pub(crate) fn baz(&self);
1409                 pub(super) fn bean(&self);
1410                 pub(in crate::outer) fn boom(&self);
1411             }
1412         ";
1413         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1414         let output = do_mock(ts).to_string();
1415         assert_not_contains(&output, quote!(pub fn foo));
1416         assert!(!output.contains(") fn foo"));
1417         assert_contains(&output, quote!(pub fn bar));
1418         assert_contains(&output, quote!(pub(crate) fn baz));
1419         assert_contains(&output, quote!(pub(super) fn bean));
1420         assert_contains(&output, quote!(pub(in crate::outer) fn boom));
1421 
1422         assert_not_contains(&output, quote!(pub fn expect_foo));
1423         assert!(!output.contains("pub fn expect_foo"));
1424         assert!(!output.contains(") fn expect_foo"));
1425         assert_contains(&output, quote!(pub fn expect_bar));
1426         assert_contains(&output, quote!(pub(crate) fn expect_baz));
1427         assert_contains(&output, quote!(pub(super) fn expect_bean));
1428         assert_contains(&output, quote!(pub(in crate::outer) fn expect_boom));
1429     }
1430 
1431     #[test]
must_use_struct()1432     fn must_use_struct() {
1433         let code = "
1434             #[must_use]
1435             pub Foo {}
1436         ";
1437         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1438         let output = do_mock(ts).to_string();
1439         assert_contains(&output, quote!(#[must_use] pub struct MockFoo));
1440     }
1441 
1442     #[test]
specific_impl()1443     fn specific_impl() {
1444         let code = "
1445             pub Foo<T: 'static> {}
1446             impl Bar for Foo<u32> {
1447                 fn bar(&self);
1448             }
1449             impl Bar for Foo<i32> {
1450                 fn bar(&self);
1451             }
1452         ";
1453         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1454         let output = do_mock(ts).to_string();
1455         assert_contains(&output, quote!(impl Bar for MockFoo<u32>));
1456         assert_contains(&output, quote!(impl Bar for MockFoo<i32>));
1457         // Ensure we don't duplicate the checkpoint function
1458         assert_not_contains(&output, quote!(
1459             self.Bar_expectations.checkpoint();
1460             self.Bar_expectations.checkpoint();
1461         ));
1462         // The expect methods should return specific types, not generic ones
1463         assert_contains(&output, quote!(
1464             pub fn expect_bar(&mut self) -> &mut __mock_MockFoo_Bar::__bar::Expectation<u32>
1465         ));
1466         assert_contains(&output, quote!(
1467             pub fn expect_bar(&mut self) -> &mut __mock_MockFoo_Bar::__bar::Expectation<i32>
1468         ));
1469     }
1470 }
1471 
1472 /// Various tests for overall code generation that are hard or impossible to
1473 /// write as integration tests
1474 mod automock {
1475     use std::str::FromStr;
1476     use super::super::*;
1477     use super::*;
1478 
1479     #[test]
doc_comments()1480     fn doc_comments() {
1481         let code = "
1482             mod foo {
1483                 /// Function docs
1484                 pub fn bar() { unimplemented!() }
1485             }
1486         ";
1487         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1488         let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
1489         let output = do_automock(attrs_ts, ts).to_string();
1490         assert_contains(&output, quote!(#[doc=" Function docs"] pub fn bar));
1491     }
1492 
1493     #[test]
method_visibility()1494     fn method_visibility() {
1495         let code = "
1496         impl Foo {
1497             fn foo(&self) {}
1498             pub fn bar(&self) {}
1499             pub(super) fn baz(&self) {}
1500             pub(crate) fn bang(&self) {}
1501             pub(in super::x) fn bean(&self) {}
1502         }";
1503         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1504         let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
1505         let output = do_automock(attrs_ts, ts).to_string();
1506         assert_not_contains(&output, quote!(pub fn foo));
1507         assert!(!output.contains(") fn foo"));
1508         assert_not_contains(&output, quote!(pub fn expect_foo));
1509         assert!(!output.contains(") fn expect_foo"));
1510         assert_contains(&output, quote!(pub fn bar));
1511         assert_contains(&output, quote!(pub fn expect_bar));
1512         assert_contains(&output, quote!(pub(super) fn baz));
1513         assert_contains(&output, quote!(pub(super) fn expect_baz));
1514         assert_contains(&output, quote!(pub ( crate ) fn bang));
1515         assert_contains(&output, quote!(pub ( crate ) fn expect_bang));
1516         assert_contains(&output, quote!(pub ( in super :: x ) fn bean));
1517         assert_contains(&output, quote!(pub ( in super :: x ) fn expect_bean));
1518     }
1519 
1520     #[test]
must_use_method()1521     fn must_use_method() {
1522         let code = "
1523         impl Foo {
1524             #[must_use]
1525             fn foo(&self) -> i32 {42}
1526         }";
1527         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1528         let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
1529         let output = do_automock(attrs_ts, ts).to_string();
1530         assert_not_contains(&output, quote!(#[must_use] fn expect_foo));
1531         assert_contains(&output, quote!(#[must_use] #[allow(dead_code)] fn foo));
1532     }
1533 
1534     #[test]
must_use_static_method()1535     fn must_use_static_method() {
1536         let code = "
1537         impl Foo {
1538             #[must_use]
1539             fn foo() -> i32 {42}
1540         }";
1541         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1542         let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
1543         let output = do_automock(attrs_ts, ts).to_string();
1544         assert_not_contains(&output, quote!(#[must_use] fn expect));
1545         assert_not_contains(&output, quote!(#[must_use] fn foo_context));
1546         assert_contains(&output, quote!(#[must_use] #[allow(dead_code)] fn foo));
1547     }
1548 
1549     #[test]
must_use_trait()1550     fn must_use_trait() {
1551         let code = "
1552         #[must_use]
1553         trait Foo {}
1554         ";
1555         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1556         let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
1557         let output = do_automock(attrs_ts, ts).to_string();
1558         assert_not_contains(&output, quote!(#[must_use] struct MockFoo));
1559     }
1560 
1561     #[test]
1562     #[should_panic(expected = "automock does not currently support structs with elided lifetimes")]
elided_lifetimes()1563     fn elided_lifetimes() {
1564         let code = "impl X<'_> {}";
1565         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1566         let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
1567         do_automock(attrs_ts, ts).to_string();
1568     }
1569 
1570     #[test]
1571     #[should_panic(expected = "can only mock inline modules")]
external_module()1572     fn external_module() {
1573         let code = "mod foo;";
1574         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1575         let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
1576         do_automock(attrs_ts, ts).to_string();
1577     }
1578 
1579     #[test]
trait_visibility()1580     fn trait_visibility() {
1581         let code = "
1582         pub(super) trait Foo {}
1583         ";
1584         let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
1585         let ts = proc_macro2::TokenStream::from_str(code).unwrap();
1586         let output = do_automock(attrs_ts, ts).to_string();
1587         assert_contains(&output, quote!(pub ( super ) struct MockFoo));
1588     }
1589 }
1590 
1591 mod concretize_args {
1592     use super::*;
1593 
1594     #[allow(clippy::needless_range_loop)] // Clippy's suggestion is worse
check_concretize( sig: TokenStream, expected_inputs: &[TokenStream], expected_call_exprs: &[TokenStream], expected_sig_inputs: &[TokenStream])1595     fn check_concretize(
1596         sig: TokenStream,
1597         expected_inputs: &[TokenStream],
1598         expected_call_exprs: &[TokenStream],
1599         expected_sig_inputs: &[TokenStream])
1600     {
1601         let f: Signature = parse2(sig).unwrap();
1602         let (generics, inputs, call_exprs, altsig) = concretize_args(&f.generics, &f);
1603         assert!(generics.params.is_empty());
1604         assert_eq!(inputs.len(), expected_inputs.len());
1605         assert_eq!(call_exprs.len(), expected_call_exprs.len());
1606         for i in 0..inputs.len() {
1607             let actual = &inputs[i];
1608             let exp = &expected_inputs[i];
1609             assert_eq!(quote!(#actual).to_string(), quote!(#exp).to_string());
1610         }
1611         for i in 0..call_exprs.len() {
1612             let actual = &call_exprs[i];
1613             let exp = &expected_call_exprs[i];
1614             assert_eq!(quote!(#actual).to_string(), quote!(#exp).to_string());
1615         }
1616         for i in 0..altsig.inputs.len() {
1617             let actual = &altsig.inputs[i];
1618             let exp = &expected_sig_inputs[i];
1619             assert_eq!(quote!(#actual).to_string(), quote!(#exp).to_string());
1620         }
1621     }
1622 
1623     #[test]
bystanders()1624     fn bystanders() {
1625         check_concretize(
1626             quote!(fn foo<P: AsRef<Path>>(x: i32, p: P, y: &f64)),
1627             &[quote!(x: i32), quote!(p: &(dyn AsRef<Path>)), quote!(y: &f64)],
1628             &[quote!(x), quote!(&p), quote!(y)],
1629             &[quote!(x: i32), quote!(p: P), quote!(y: &f64)]
1630         );
1631     }
1632 
1633     #[test]
function_args()1634     fn function_args() {
1635         check_concretize(
1636             quote!(fn foo<F1: Fn(u32) -> u32,
1637                           F2: FnMut(&mut u32) -> u32,
1638                           F3: FnOnce(u32) -> u32,
1639                           F4: Fn() + Send>(f1: F1, f2: F2, f3: F3, f4: F4)),
1640             &[quote!(f1: &(dyn Fn(u32) -> u32)),
1641               quote!(f2: &mut(dyn FnMut(&mut u32) -> u32)),
1642               quote!(f3: &(dyn FnOnce(u32) -> u32)),
1643               quote!(f4: &(dyn Fn() + Send))],
1644             &[quote!(&f1), quote!(&mut f2), quote!(&f3), quote!(&f4)],
1645             &[quote!(f1: F1), quote!(mut f2: F2), quote!(f3: F3), quote!(f4: F4)]
1646         );
1647     }
1648 
1649     #[test]
multi_bounds()1650     fn multi_bounds() {
1651         check_concretize(
1652             quote!(fn foo<P: AsRef<String> + AsMut<String>>(p: P)),
1653             &[quote!(p: &(dyn AsRef<String> + AsMut<String>))],
1654             &[quote!(&p)],
1655             &[quote!(p: P)],
1656         );
1657     }
1658 
1659     #[test]
mutable_reference_arg()1660     fn mutable_reference_arg() {
1661         check_concretize(
1662             quote!(fn foo<P: AsMut<Path>>(p: &mut P)),
1663             &[quote!(p: &mut (dyn AsMut<Path>))],
1664             &[quote!(p)],
1665             &[quote!(p: &mut P)],
1666         );
1667     }
1668 
1669     #[test]
mutable_reference_multi_bounds()1670     fn mutable_reference_multi_bounds() {
1671         check_concretize(
1672             quote!(fn foo<P: AsRef<String> + AsMut<String>>(p: &mut P)),
1673             &[quote!(p: &mut (dyn AsRef<String> + AsMut<String>))],
1674             &[quote!(p)],
1675             &[quote!(p: &mut P)]
1676         );
1677     }
1678 
1679     #[test]
reference_arg()1680     fn reference_arg() {
1681         check_concretize(
1682             quote!(fn foo<P: AsRef<Path>>(p: &P)),
1683             &[quote!(p: &(dyn AsRef<Path>))],
1684             &[quote!(p)],
1685             &[quote!(p: &P)]
1686         );
1687     }
1688 
1689     #[test]
simple()1690     fn simple() {
1691         check_concretize(
1692             quote!(fn foo<P: AsRef<Path>>(p: P)),
1693             &[quote!(p: &(dyn AsRef<Path>))],
1694             &[quote!(&p)],
1695             &[quote!(p: P)],
1696         );
1697     }
1698 
1699     #[test]
slice()1700     fn slice() {
1701         check_concretize(
1702             quote!(fn foo<P: AsRef<Path>>(p: &[P])),
1703             &[quote!(p: &[&(dyn AsRef<Path>)])],
1704             &[quote!(&(0..p.len()).map(|__mockall_i| &p[__mockall_i] as &(dyn AsRef<Path>)).collect::<Vec<_>>())],
1705             &[quote!(p: &[P])]
1706         );
1707     }
1708 
1709     #[test]
slice_with_multi_bounds()1710     fn slice_with_multi_bounds() {
1711         check_concretize(
1712             quote!(fn foo<P: AsRef<Path> + AsMut<String>>(p: &[P])),
1713             &[quote!(p: &[&(dyn AsRef<Path> + AsMut<String>)])],
1714             &[quote!(&(0..p.len()).map(|__mockall_i| &p[__mockall_i] as &(dyn AsRef<Path> + AsMut<String>)).collect::<Vec<_>>())],
1715             &[quote!(p: &[P])]
1716         );
1717     }
1718 
1719     #[test]
where_clause()1720     fn where_clause() {
1721         check_concretize(
1722             quote!(fn foo<P>(p: P) where P: AsRef<Path>),
1723             &[quote!(p: &(dyn AsRef<Path>))],
1724             &[quote!(&p)],
1725             &[quote!(p: P)]
1726         );
1727     }
1728 }
1729 
1730 mod declosurefy {
1731     use super::*;
1732 
check_declosurefy( sig: TokenStream, expected_inputs: &[TokenStream], expected_call_exprs: &[TokenStream])1733     fn check_declosurefy(
1734         sig: TokenStream,
1735         expected_inputs: &[TokenStream],
1736         expected_call_exprs: &[TokenStream])
1737     {
1738         let f: Signature = parse2(sig).unwrap();
1739         let (generics, inputs, call_exprs) =
1740             declosurefy(&f.generics, &f.inputs);
1741         assert!(generics.params.is_empty());
1742         assert_eq!(inputs.len(), expected_inputs.len());
1743         assert_eq!(call_exprs.len(), expected_call_exprs.len());
1744         for i in 0..inputs.len() {
1745             let actual = &inputs[i];
1746             let exp = &expected_inputs[i];
1747             assert_eq!(quote!(#actual).to_string(), quote!(#exp).to_string());
1748         }
1749         for i in 0..call_exprs.len() {
1750             let actual = &call_exprs[i];
1751             let exp = &expected_call_exprs[i];
1752             assert_eq!(quote!(#actual).to_string(), quote!(#exp).to_string());
1753         }
1754     }
1755 
1756     #[test]
bounds()1757     fn bounds() {
1758         check_declosurefy(
1759             quote!(fn foo<F: Fn(u32) -> u32 + Send>(f: F)),
1760             &[quote!(f: Box<dyn Fn(u32) -> u32 + Send>)],
1761             &[quote!(Box::new(f))]
1762         );
1763     }
1764 
1765     #[test]
1766     fn r#fn() {
1767         check_declosurefy(
1768             quote!(fn foo<F: Fn(u32) -> u32>(f: F)),
1769             &[quote!(f: Box<dyn Fn(u32) -> u32>)],
1770             &[quote!(Box::new(f))]
1771         );
1772     }
1773 
1774     #[test]
fn_mut()1775     fn fn_mut() {
1776         check_declosurefy(
1777             quote!(fn foo<F: FnMut(u32) -> u32>(f: F)),
1778             &[quote!(f: Box<dyn FnMut(u32) -> u32>)],
1779             &[quote!(Box::new(f))]
1780         );
1781     }
1782 
1783     #[test]
fn_once()1784     fn fn_once() {
1785         check_declosurefy(
1786             quote!(fn foo<F: FnOnce(u32) -> u32>(f: F)),
1787             &[quote!(f: Box<dyn FnOnce(u32) -> u32>)],
1788             &[quote!(Box::new(f))]
1789         );
1790     }
1791 
1792     #[test]
mutable_pattern()1793     fn mutable_pattern() {
1794         check_declosurefy(
1795             quote!(fn foo<F: FnMut(u32) -> u32>(mut f: F)),
1796             &[quote!(f: Box<dyn FnMut(u32) -> u32>)],
1797             &[quote!(Box::new(f))]
1798         );
1799     }
1800 
1801     #[test]
where_clause()1802     fn where_clause() {
1803         check_declosurefy(
1804             quote!(fn foo<F>(f: F) where F: Fn(u32) -> u32),
1805             &[quote!(f: Box<dyn Fn(u32) -> u32>)],
1806             &[quote!(Box::new(f))]
1807         );
1808     }
1809 
1810     #[test]
where_clause_with_bounds()1811     fn where_clause_with_bounds() {
1812         check_declosurefy(
1813             quote!(fn foo<F>(f: F) where F: Fn(u32) -> u32 + Send),
1814             &[quote!(f: Box<dyn Fn(u32) -> u32 + Send>)],
1815             &[quote!(Box::new(f))]
1816         );
1817     }
1818 }
1819 
1820 mod deimplify {
1821     use super::*;
1822 
check_deimplify(orig_ts: TokenStream, expected_ts: TokenStream)1823     fn check_deimplify(orig_ts: TokenStream, expected_ts: TokenStream) {
1824         let mut orig: ReturnType = parse2(orig_ts).unwrap();
1825         let expected: ReturnType = parse2(expected_ts).unwrap();
1826         deimplify(&mut orig);
1827         assert_eq!(quote!(#orig).to_string(), quote!(#expected).to_string());
1828     }
1829 
1830     // Future is a special case
1831     #[test]
impl_future()1832     fn impl_future() {
1833         check_deimplify(
1834             quote!(-> impl Future<Output=i32>),
1835             quote!(-> ::std::pin::Pin<Box<dyn Future<Output=i32>>>)
1836         );
1837     }
1838 
1839     // Future is a special case, wherever it appears
1840     #[test]
impl_future_reverse()1841     fn impl_future_reverse() {
1842         check_deimplify(
1843             quote!(-> impl Send + Future<Output=i32>),
1844             quote!(-> ::std::pin::Pin<Box<dyn Send + Future<Output=i32>>>)
1845         );
1846     }
1847 
1848     // Stream is a special case
1849     #[test]
impl_stream()1850     fn impl_stream() {
1851         check_deimplify(
1852             quote!(-> impl Stream<Item=i32>),
1853             quote!(-> ::std::pin::Pin<Box<dyn Stream<Item=i32>>>)
1854         );
1855     }
1856 
1857     #[test]
impl_trait()1858     fn impl_trait() {
1859         check_deimplify(
1860             quote!(-> impl Foo),
1861             quote!(-> Box<dyn Foo>)
1862         );
1863     }
1864 
1865     // With extra bounds
1866     #[test]
impl_trait2()1867     fn impl_trait2() {
1868         check_deimplify(
1869             quote!(-> impl Foo + Send),
1870             quote!(-> Box<dyn Foo + Send>)
1871         );
1872     }
1873 }
1874 
1875 mod deselfify {
1876     use super::*;
1877 
check_deselfify( orig_ts: TokenStream, actual_ts: TokenStream, generics_ts: TokenStream, expected_ts: TokenStream)1878     fn check_deselfify(
1879         orig_ts: TokenStream,
1880         actual_ts: TokenStream,
1881         generics_ts: TokenStream,
1882         expected_ts: TokenStream)
1883     {
1884         let mut ty: Type = parse2(orig_ts).unwrap();
1885         let actual: Ident = parse2(actual_ts).unwrap();
1886         let generics: Generics = parse2(generics_ts).unwrap();
1887         let expected: Type = parse2(expected_ts).unwrap();
1888         deselfify(&mut ty, &actual, &generics);
1889         assert_eq!(quote!(#ty).to_string(),
1890                    quote!(#expected).to_string());
1891     }
1892 
1893     #[test]
arc()1894     fn arc() {
1895         check_deselfify(
1896             quote!(Arc<Self>),
1897             quote!(Foo),
1898             quote!(),
1899             quote!(Arc<Foo>)
1900         );
1901     }
1902     #[test]
future()1903     fn future() {
1904         check_deselfify(
1905             quote!(Box<dyn Future<Output=Self>>),
1906             quote!(Foo),
1907             quote!(),
1908             quote!(Box<dyn Future<Output=Foo>>)
1909         );
1910     }
1911 
1912     #[test]
qself()1913     fn qself() {
1914         check_deselfify(
1915             quote!(<Self as Self>::Self),
1916             quote!(Foo),
1917             quote!(),
1918             quote!(<Foo as Foo>::Foo)
1919         );
1920     }
1921 
1922     #[test]
trait_object()1923     fn trait_object() {
1924         check_deselfify(
1925             quote!(Box<dyn Self>),
1926             quote!(Foo),
1927             quote!(),
1928             quote!(Box<dyn Foo>)
1929         );
1930     }
1931 
1932     // A trait object with multiple bounds
1933     #[test]
trait_object2()1934     fn trait_object2() {
1935         check_deselfify(
1936             quote!(Box<dyn Self + Send>),
1937             quote!(Foo),
1938             quote!(),
1939             quote!(Box<dyn Foo + Send>)
1940         );
1941     }
1942 }
1943 
1944 mod dewhereselfify {
1945     use super::*;
1946 
1947     #[test]
lifetime()1948     fn lifetime() {
1949         let mut meth: ImplItemFn = parse2(quote!(
1950                 fn foo<'a>(&self) where 'a: 'static, Self: Sized {}
1951         )).unwrap();
1952         let expected: ImplItemFn = parse2(quote!(
1953                 fn foo<'a>(&self) where 'a: 'static {}
1954         )).unwrap();
1955         dewhereselfify(&mut meth.sig.generics);
1956         assert_eq!(meth, expected);
1957     }
1958 
1959     #[test]
normal_method()1960     fn normal_method() {
1961         let mut meth: ImplItemFn = parse2(quote!(
1962                 fn foo(&self) where Self: Sized {}
1963         )).unwrap();
1964         let expected: ImplItemFn = parse2(quote!(
1965                 fn foo(&self) {}
1966         )).unwrap();
1967         dewhereselfify(&mut meth.sig.generics);
1968         assert_eq!(meth, expected);
1969     }
1970 
1971     #[test]
with_real_generics()1972     fn with_real_generics() {
1973         let mut meth: ImplItemFn = parse2(quote!(
1974                 fn foo<T>(&self, t: T) where Self: Sized, T: Copy {}
1975         )).unwrap();
1976         let expected: ImplItemFn = parse2(quote!(
1977                 fn foo<T>(&self, t: T) where T: Copy {}
1978         )).unwrap();
1979         dewhereselfify(&mut meth.sig.generics);
1980         assert_eq!(meth, expected);
1981     }
1982 }
1983 
1984 mod gen_keyid {
1985     use super::*;
1986 
check_gen_keyid(orig: TokenStream, expected: TokenStream)1987     fn check_gen_keyid(orig: TokenStream, expected: TokenStream) {
1988         let g: Generics = parse2(orig).unwrap();
1989         let keyid = gen_keyid(&g);
1990         assert_eq!(quote!(#keyid).to_string(), quote!(#expected).to_string());
1991     }
1992 
1993     #[test]
empty()1994     fn empty() {
1995         check_gen_keyid(quote!(), quote!(<()>));
1996     }
1997 
1998     #[test]
onetype()1999     fn onetype() {
2000         check_gen_keyid(quote!(<T>), quote!(<T>));
2001     }
2002 
2003     #[test]
twotypes()2004     fn twotypes() {
2005         check_gen_keyid(quote!(<T, V>), quote!(<(T, V)>));
2006     }
2007 }
2008 
2009 mod merge_generics {
2010     use super::*;
2011 
2012     #[test]
both()2013     fn both() {
2014         let mut g1: Generics = parse2(quote!(<T: 'static, V: Copy> )).unwrap();
2015         let wc1: WhereClause = parse2(quote!(where T: Default)).unwrap();
2016         g1.where_clause = Some(wc1);
2017 
2018         let mut g2: Generics = parse2(quote!(<Q: Send, V: Clone>)).unwrap();
2019         let wc2: WhereClause = parse2(quote!(where T: Sync, Q: Debug)).unwrap();
2020         g2.where_clause = Some(wc2);
2021 
2022         let gm = super::merge_generics(&g1, &g2);
2023         let gm_wc = &gm.where_clause;
2024 
2025         let ge: Generics = parse2(quote!(
2026                 <T: 'static, V: Copy + Clone, Q: Send>
2027         )).unwrap();
2028         let wce: WhereClause = parse2(quote!(
2029             where T: Default + Sync, Q: Debug
2030         )).unwrap();
2031 
2032         assert_eq!(quote!(#ge #wce).to_string(),
2033                    quote!(#gm #gm_wc).to_string());
2034     }
2035 
2036     #[test]
eq()2037     fn eq() {
2038         let mut g1: Generics = parse2(quote!(<T: 'static, V: Copy> )).unwrap();
2039         let wc1: WhereClause = parse2(quote!(where T: Default)).unwrap();
2040         g1.where_clause = Some(wc1.clone());
2041 
2042         let gm = super::merge_generics(&g1, &g1);
2043         let gm_wc = &gm.where_clause;
2044 
2045         assert_eq!(quote!(#g1 #wc1).to_string(),
2046                    quote!(#gm #gm_wc).to_string());
2047     }
2048 
2049     #[test]
lhs_only()2050     fn lhs_only() {
2051         let mut g1: Generics = parse2(quote!(<T: 'static, V: Copy> )).unwrap();
2052         let wc1: WhereClause = parse2(quote!(where T: Default)).unwrap();
2053         g1.where_clause = Some(wc1.clone());
2054 
2055         let g2 = Generics::default();
2056 
2057         let gm = super::merge_generics(&g1, &g2);
2058         let gm_wc = &gm.where_clause;
2059 
2060         assert_eq!(quote!(#g1 #wc1).to_string(),
2061                    quote!(#gm #gm_wc).to_string());
2062     }
2063 
2064     #[test]
lhs_wc_only()2065     fn lhs_wc_only() {
2066         let mut g1 = Generics::default();
2067         let wc1: WhereClause = parse2(quote!(where T: Default)).unwrap();
2068         g1.where_clause = Some(wc1.clone());
2069 
2070         let g2 = Generics::default();
2071 
2072         let gm = super::merge_generics(&g1, &g2);
2073         let gm_wc = &gm.where_clause;
2074 
2075         assert_eq!(quote!(#g1 #wc1).to_string(),
2076                    quote!(#gm #gm_wc).to_string());
2077     }
2078 
2079     #[test]
rhs_only()2080     fn rhs_only() {
2081         let g1 = Generics::default();
2082         let mut g2: Generics = parse2(quote!(<Q: Send, V: Clone>)).unwrap();
2083         let wc2: WhereClause = parse2(quote!(where T: Sync, Q: Debug)).unwrap();
2084         g2.where_clause = Some(wc2.clone());
2085 
2086         let gm = super::merge_generics(&g1, &g2);
2087         let gm_wc = &gm.where_clause;
2088 
2089         assert_eq!(quote!(#g2 #wc2).to_string(),
2090                    quote!(#gm #gm_wc).to_string());
2091     }
2092 }
2093 
2094 mod supersuperfy {
2095     use super::*;
2096 
check_supersuperfy(orig: TokenStream, expected: TokenStream)2097     fn check_supersuperfy(orig: TokenStream, expected: TokenStream) {
2098         let orig_ty: Type = parse2(orig).unwrap();
2099         let expected_ty: Type = parse2(expected).unwrap();
2100         let output = supersuperfy(&orig_ty, 1);
2101         assert_eq!(quote!(#output).to_string(),
2102                    quote!(#expected_ty).to_string());
2103     }
2104 
2105     #[test]
array()2106     fn array() {
2107         check_supersuperfy(
2108             quote!([super::X; n]),
2109             quote!([super::super::X; n])
2110         );
2111     }
2112 
2113     #[test]
barefn()2114     fn barefn() {
2115         check_supersuperfy(
2116             quote!(fn(super::A) -> super::B),
2117             quote!(fn(super::super::A) -> super::super::B)
2118         );
2119     }
2120 
2121     #[test]
group()2122     fn group() {
2123         let orig = TypeGroup {
2124             group_token: token::Group::default(),
2125             elem: Box::new(parse2(quote!(super::T)).unwrap())
2126         };
2127         let expected = TypeGroup {
2128             group_token: token::Group::default(),
2129             elem: Box::new(parse2(quote!(super::super::T)).unwrap())
2130         };
2131         let output = supersuperfy(&Type::Group(orig), 1);
2132         assert_eq!(quote!(#output).to_string(),
2133                    quote!(#expected).to_string());
2134     }
2135 
2136     // Just check that it doesn't panic
2137     #[test]
infer()2138     fn infer() {
2139         check_supersuperfy( quote!(_), quote!(_));
2140     }
2141 
2142     // Just check that it doesn't panic
2143     #[test]
never()2144     fn never() {
2145         check_supersuperfy( quote!(!), quote!(!));
2146     }
2147 
2148     #[test]
paren()2149     fn paren() {
2150         check_supersuperfy(
2151             quote!((super::X)),
2152             quote!((super::super::X))
2153         );
2154     }
2155 
2156     #[test]
path()2157     fn path() {
2158         check_supersuperfy(
2159             quote!(::super::SuperT<u32>),
2160             quote!(::super::super::SuperT<u32>)
2161         );
2162     }
2163 
2164     #[test]
path_with_qself()2165     fn path_with_qself() {
2166         check_supersuperfy(
2167             quote!(<super::X as super::Y>::Foo<u32>),
2168             quote!(<super::super::X as super::super::Y>::Foo<u32>),
2169         );
2170     }
2171 
2172     #[test]
angle_bracketed_generic_arguments()2173     fn angle_bracketed_generic_arguments() {
2174         check_supersuperfy(
2175             quote!(mod_::T<super::X>),
2176             quote!(mod_::T<super::super::X>)
2177         );
2178     }
2179 
2180     #[test]
ptr()2181     fn ptr() {
2182         check_supersuperfy(
2183             quote!(*const super::X),
2184             quote!(*const super::super::X)
2185         );
2186     }
2187 
2188     #[test]
reference()2189     fn reference() {
2190         check_supersuperfy(
2191             quote!(&'a mut super::X),
2192             quote!(&'a mut super::super::X)
2193         );
2194     }
2195 
2196     #[test]
slice()2197     fn slice() {
2198         check_supersuperfy(
2199             quote!([super::X]),
2200             quote!([super::super::X])
2201         );
2202     }
2203 
2204     #[test]
trait_object()2205     fn trait_object() {
2206         check_supersuperfy(
2207             quote!(dyn super::X + super::Y),
2208             quote!(dyn super::super::X + super::super::Y)
2209         );
2210     }
2211 
2212     #[test]
tuple()2213     fn tuple() {
2214         check_supersuperfy(
2215             quote!((super::A, super::B)),
2216             quote!((super::super::A, super::super::B))
2217         );
2218     }
2219 }
2220 
2221 mod supersuperfy_generics {
2222     use super::*;
2223 
check_supersuperfy_generics( orig: TokenStream, orig_wc: TokenStream, expected: TokenStream, expected_wc: TokenStream)2224     fn check_supersuperfy_generics(
2225         orig: TokenStream,
2226         orig_wc: TokenStream,
2227         expected: TokenStream,
2228         expected_wc: TokenStream)
2229     {
2230         let mut orig_g: Generics = parse2(orig).unwrap();
2231         orig_g.where_clause = parse2(orig_wc).unwrap();
2232         let mut expected_g: Generics = parse2(expected).unwrap();
2233         expected_g.where_clause = parse2(expected_wc).unwrap();
2234         let mut output: Generics = orig_g;
2235         supersuperfy_generics(&mut output, 1);
2236         let (o_ig, o_tg, o_wc) = output.split_for_impl();
2237         let (e_ig, e_tg, e_wc) = expected_g.split_for_impl();
2238         assert_eq!(quote!(#o_ig).to_string(), quote!(#e_ig).to_string());
2239         assert_eq!(quote!(#o_tg).to_string(), quote!(#e_tg).to_string());
2240         assert_eq!(quote!(#o_wc).to_string(), quote!(#e_wc).to_string());
2241     }
2242 
2243     #[test]
default()2244     fn default() {
2245         check_supersuperfy_generics(
2246             quote!(<T: X = super::Y>), quote!(),
2247             quote!(<T: X = super::super::Y>), quote!(),
2248         );
2249     }
2250 
2251     #[test]
empty()2252     fn empty() {
2253         check_supersuperfy_generics(quote!(), quote!(), quote!(), quote!());
2254     }
2255 
2256     #[test]
everything()2257     fn everything() {
2258         check_supersuperfy_generics(
2259             quote!(<T: super::A = super::B>),
2260             quote!(where super::C: super::D),
2261             quote!(<T: super::super::A = super::super::B>),
2262             quote!(where super::super::C: super::super::D),
2263         );
2264     }
2265 
2266     #[test]
bound()2267     fn bound() {
2268         check_supersuperfy_generics(
2269             quote!(<T: super::A>), quote!(),
2270             quote!(<T: super::super::A>), quote!(),
2271         );
2272     }
2273 
2274     #[test]
closure()2275     fn closure() {
2276         check_supersuperfy_generics(
2277             quote!(<F: Fn(u32) -> super::SuperT>), quote!(),
2278             quote!(<F: Fn(u32) -> super::super::SuperT>), quote!(),
2279         );
2280     }
2281 
2282     #[test]
wc_bounded_ty()2283     fn wc_bounded_ty() {
2284         check_supersuperfy_generics(
2285             quote!(), quote!(where super::T: X),
2286             quote!(), quote!(where super::super::T: X),
2287         );
2288     }
2289 
2290     #[test]
wc_bounds()2291     fn wc_bounds() {
2292         check_supersuperfy_generics(
2293             quote!(), quote!(where T: super::X),
2294             quote!(), quote!(where T: super::super::X),
2295         );
2296     }
2297 }
2298 }
2299