unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
@ 2024-03-17 15:59 Aaron Covrig via Guix-patches via
  2024-03-19 10:45 ` Efraim Flashner
  0 siblings, 1 reply; 4+ messages in thread
From: Aaron Covrig via Guix-patches via @ 2024-03-17 15:59 UTC (permalink / raw)
  To: 69859; +Cc: Aaron Covrig, efraim

* gnu/packages/crates-io.scm (rust-pcap-1): New variable
* gnu/packages/crates-io.scm (rust-pcap-0.11): New variable
* gnu/packages/crates-io.scm (rust-pcap-0.10): New variable
* gnu/packages/crates-io.scm (rust-gat-std-0.1): New variable
* gnu/packages/crates-io.scm (rust-gat-std-proc-0.1): New variable
* gnu/packages/crates-io.scm (rust-etherparse-0.14): New variable
* gnu/packages/crates-io.scm (rust-etherparse-0.9): New variable
* gnu/packages/crates-io.scm (rust-eui48-1): New variable
* gnu/packages/crates-io.scm (rust-tun-tap-0.1): New variable
* gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch:
  New file (provides tests and examples rust-mockall)
* gnu/packages/crates-io.scm (rust-mockall-0.12): New variable
* gnu/packages/crates-io.scm (rust-mockall-derive-0.12): New variable
* gnu/packages/crates-io.scm (rust-mockall-0.11): Bumps to 0.11.4
* gnu/packages/crates-io.scm (rust-mockall-derive-0.11): Bumps to 0.11.4
* gnu/packages/crates-io.scm (rust-mockall-double-0.3): Bumps to 0.3.1
* gnu/packages/crates-io.scm (rust-fragile-2): New variable
* gnu/packages/crates-io.scm (rust-fragile-1): Bumps to 1.2.2
* gnu/packages/crates-io.scm (rust-slab-0.4): Bumps to 0.4.9
---
 gnu/packages/crates-io.scm                    |  453 +-
 ...t-mockall-restore-examples-and-tests.patch | 7611 +++++++++++++++++
 2 files changed, 7976 insertions(+), 88 deletions(-)
 create mode 100644 gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch

diff --git a/gnu/packages/crates-io.scm b/gnu/packages/crates-io.scm
index e99f0f991b..34916d251e 100644
--- a/gnu/packages/crates-io.scm
+++ b/gnu/packages/crates-io.scm
@@ -24519,25 +24519,41 @@ (define-public rust-form-urlencoded-1
 syntax, as used by HTML forms.")
     (license (list license:expat license:asl2.0))))
 
-(define-public rust-fragile-1
+(define-public rust-fragile-2
   (package
     (name "rust-fragile")
-    (version "1.0.0")
+    (version "2.0.0")
     (source
      (origin
        (method url-fetch)
        (uri (crate-uri "fragile" version))
        (file-name (string-append name "-" version ".tar.gz"))
        (sha256
-        (base32 "1wlihmkjyhvl5rckal32p010piy1l15s6l81h7z31jcd971kk839"))))
+        (base32 "1ajfdnwdn921bhjlzyvsqvdgci8ab40ln6w9ly422lf8svb428bc"))))
     (build-system cargo-build-system)
-    (arguments `(#:skip-build? #t))
-    (home-page "https://github.com/mitsuhiko/rust-fragile")
+    (arguments
+     `(#:cargo-inputs (("rust-slab" ,rust-slab-0.4))))
+    (home-page "https://github.com/mitsuhiko/fragile")
     (synopsis "Wrapper types for sending non-send values to other threads")
     (description "This package provides wrapper types for sending non-send
 values to other threads.")
     (license license:asl2.0)))
 
+(define-public rust-fragile-1
+  (package
+    (inherit rust-fragile-2)
+    (name "rust-fragile")
+    (version "1.2.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "fragile" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "1s2rz4cmmba5zi0gf2h6hprrcrf0wm83c1y45sdls09z99f4qimp"))))
+    (arguments
+     `(#:cargo-inputs (("rust-fragile" ,rust-fragile-2))))))
+
 (define-public rust-freetype-0.7
   (package
     (name "rust-freetype")
@@ -25974,6 +25990,48 @@ (define-public rust-galil-seiferas-0.1
 time, for nonorderable alphabets.")
     (license (list license:expat license:asl2.0))))
 
+(define-public rust-gat-std-0.1
+  (package
+    (name "rust-gat-std")
+    (version "0.1.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "gat-std" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "14v4ldnzi8y8zkcj2qq7rj4af5ygk0s9iklflssxpcdgqzsfp3p0"))))
+    (build-system cargo-build-system)
+    (arguments
+     `(#:cargo-inputs (("rust-gat-std-proc" ,rust-gat-std-proc-0.1))))
+    (home-page "https://github.com/CraftSpider/gat-std")
+    (synopsis "Variants of Rust std traits that use GATs")
+    (description
+     "A variant of Rust std traits that use GATs, as well as a macro to allow
+rewriting code to use these traits instead of the std equivalents.")
+    (license (list license:expat license:asl2.0))))
+
+(define-public rust-gat-std-proc-0.1
+  (package
+    (name "rust-gat-std-proc")
+    (version "0.1.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "gat-std-proc" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "0br6d92fg4g7s81lsms6q3ayss1bl19fanqxc7v1csnic2vaw84c"))))
+    (build-system cargo-build-system)
+    (arguments
+     `(#:cargo-inputs (("rust-proc-macro2" ,rust-proc-macro2-1)
+                       ("rust-quote" ,rust-quote-1)
+                       ("rust-syn" ,rust-syn-1))))
+    (home-page "https://github.com/CraftSpider/gat-std")
+    (synopsis "Proc macros for gat-std")
+    (description "Proc macros for gat-std.")
+    (license (list license:expat license:asl2.0))))
+
 (define-public rust-gcc-0.3
   (package
     (name "rust-gcc")
@@ -38529,85 +38587,136 @@ (define-public rust-mock-instant-0.2
      "This package provides a simple way to mock an std::time::Instant in rust.")
     (license license:bsd-0)))
 
-(define-public rust-mockall-0.11
+(define-public rust-mockall-0.12
   (package
     (name "rust-mockall")
-    (version "0.11.1")
-    (source (origin
-              (method url-fetch)
-              (uri (crate-uri "mockall" version))
-              (file-name (string-append name "-" version ".tar.gz"))
-              (sha256
-               (base32
-                "0k3g3xxf195vsnzmwza047dv89zlg6h5yj5774wjlndgpdvf8han"))))
+    (version "0.12.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "mockall" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "0j0a1wx6sb8yimjgg3q1svrn8jsnaiz9zqgz93ihvc83a8mnqxj3"))
+       (patches (search-patches
+                 "rust-mockall-restore-examples-and-tests.patch"))))
     (build-system cargo-build-system)
+    ;; Tests depend on additional includes, only running examples
     (arguments
-     `(#:tests? #f          ; Not all files included.
-       #:cargo-inputs
-       (("rust-cfg-if" ,rust-cfg-if-1)
-        ("rust-downcast" ,rust-downcast-0.11)
-        ("rust-fragile" ,rust-fragile-1)
-        ("rust-lazy-static" ,rust-lazy-static-1)
-        ("rust-mockall-derive" ,rust-mockall-derive-0.11)
-        ("rust-predicates" ,rust-predicates-2)
-        ("rust-predicates-tree" ,rust-predicates-tree-1))
-       #:cargo-development-inputs
-       (("rust-async-trait" ,rust-async-trait-0.1)
-        ("rust-futures" ,rust-futures-0.3)
-        ("rust-mockall-double" ,rust-mockall-double-0.3)
-        ("rust-serde" ,rust-serde-1)
-        ("rust-serde-derive" ,rust-serde-derive-1)
-        ("rust-serde-json" ,rust-serde-json-1)
-        ("rust-tracing" ,rust-tracing-0.1))))
+     `(#:cargo-test-flags '("--release" "--examples" "--lib")
+       #:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
+                       ("rust-downcast" ,rust-downcast-0.11)
+                       ("rust-fragile" ,rust-fragile-2)
+                       ("rust-lazy-static" ,rust-lazy-static-1)
+                       ("rust-mockall-derive" ,rust-mockall-derive-0.12)
+                       ("rust-predicates" ,rust-predicates-3)
+                       ("rust-predicates-tree" ,rust-predicates-tree-1))
+       #:cargo-development-inputs (("rust-async-trait" ,rust-async-trait-0.1)
+                                   ("rust-futures" ,rust-futures-0.3)
+                                   ("rust-mockall-double" ,rust-mockall-double-0.3)
+                                   ("rust-serde" ,rust-serde-1)
+                                   ("rust-serde-derive" ,rust-serde-derive-1)
+                                   ("rust-serde-json" ,rust-serde-json-1)
+                                   ("rust-tracing" ,rust-tracing-0.1))))
     (home-page "https://github.com/asomers/mockall")
     (synopsis "Mock object library for Rust")
     (description
      "Mockall is a rich mocking library with a terse and ergonomic interface.")
     (license (list license:expat license:asl2.0))))
 
-(define-public rust-mockall-derive-0.11
+(define-public rust-mockall-0.11
+  (package
+    (inherit rust-mockall-0.12)
+    (name "rust-mockall")
+    (version "0.11.4")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "mockall" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "15kww0a3wv300wkksc6zj0kz1jwk0hyly48daxs2vvpj300lk12c"))
+       (patches (search-patches
+                 "rust-mockall-restore-examples-and-tests.patch"))))
+    (build-system cargo-build-system)
+    ;; Tests depend on additional includes, only running examples
+    (arguments
+     `(#:cargo-test-flags '("--release" "--examples" "--lib")
+       #:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
+                       ("rust-downcast" ,rust-downcast-0.11)
+                       ("rust-fragile" ,rust-fragile-2)
+                       ("rust-lazy-static" ,rust-lazy-static-1)
+                       ("rust-mockall-derive" ,rust-mockall-derive-0.11)
+                       ("rust-predicates" ,rust-predicates-2)
+                       ("rust-predicates-tree" ,rust-predicates-tree-1))
+       #:cargo-development-inputs (("rust-async-trait" ,rust-async-trait-0.1)
+                                   ("rust-futures" ,rust-futures-0.3)
+                                   ("rust-mockall-double" ,rust-mockall-double-0.3)
+                                   ("rust-serde" ,rust-serde-1)
+                                   ("rust-serde-derive" ,rust-serde-derive-1)
+                                   ("rust-serde-json" ,rust-serde-json-1)
+                                   ("rust-tracing" ,rust-tracing-0.1))))))
+
+(define-public rust-mockall-derive-0.12
   (package
     (name "rust-mockall-derive")
-    (version "0.11.1")
-    (source (origin
-              (method url-fetch)
-              (uri (crate-uri "mockall_derive" version))
-              (file-name (string-append name "-" version ".tar.gz"))
-              (sha256
-               (base32
-                "1ixhmsrg5ky4b2jlvbxhlpr3mbv7frd6wr8msm005vijb5rmcb96"))))
+    (version "0.12.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "mockall_derive" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "1qhal0m997vy5vv8admrrbcibsq1cjkr1ajbypaa31f3kvkvqz5g"))))
     (build-system cargo-build-system)
     (arguments
-     `(#:cargo-inputs
-       (("rust-cfg-if" ,rust-cfg-if-1)
-        ("rust-proc-macro2" ,rust-proc-macro2-1)
-        ("rust-quote" ,rust-quote-1)
-        ("rust-syn" ,rust-syn-1))
-       #:cargo-development-inputs
-       (("rust-pretty-assertions" ,rust-pretty-assertions-0.7))))
+     `(#:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
+                       ("rust-proc-macro2" ,rust-proc-macro2-1)
+                       ("rust-quote" ,rust-quote-1)
+                       ("rust-syn" ,rust-syn-2))
+       #:cargo-development-inputs (("rust-pretty-assertions" ,rust-pretty-assertions-1))))
     (home-page "https://github.com/asomers/mockall")
     (synopsis "Procedural macros for the Mockall crate")
     (description
      "This package procides procedural macros for the Mockall crate.")
     (license (list license:expat license:asl2.0))))
 
+(define-public rust-mockall-derive-0.11
+  (package
+    (inherit rust-mockall-derive-0.12)
+    (name "rust-mockall-derive")
+    (version "0.11.4")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "mockall_derive" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "1fvc9kwjcc9ia6ng7z9z02b4qkl9dvsx9m4z51xz9i0mj1k7bki2"))))
+    (arguments
+     `(#:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
+                       ("rust-proc-macro2" ,rust-proc-macro2-1)
+                       ("rust-quote" ,rust-quote-1)
+                       ("rust-syn" ,rust-syn-1))
+       #:cargo-development-inputs (("rust-pretty-assertions" ,rust-pretty-assertions-1))))))
+
 (define-public rust-mockall-double-0.3
   (package
     (name "rust-mockall-double")
-    (version "0.3.0")
-    (source (origin
-              (method url-fetch)
-              (uri (crate-uri "mockall_double" version))
-              (file-name (string-append name "-" version ".tar.gz"))
-              (sha256
-               (base32
-                "1xk6hjr7m73zly4hg3zmma437vqvrwnjxy2wfxy1hxbk52xwfwdf"))))
+    (version "0.3.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "mockall_double" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "1s0k85929bf8afvdgq8m2vs8haqpkg9ysdimw7inl99mmkjrdjpi"))))
     (build-system cargo-build-system)
     (arguments
      `(#:cargo-inputs (("rust-cfg-if" ,rust-cfg-if-1)
                        ("rust-proc-macro2" ,rust-proc-macro2-1)
                        ("rust-quote" ,rust-quote-1)
-                       ("rust-syn" ,rust-syn-1))))
+                       ("rust-syn" ,rust-syn-2))))
     (home-page "https://github.com/asomers/mockall")
     (synopsis "Double test adapter that works well with Mockall")
     (description
@@ -46217,8 +46326,91 @@ (define-public rust-pathdiff-0.2
 path.")
     (license (list license:asl2.0 license:expat))))
 
+(define-public rust-pcap-1
+  (package
+    (name "rust-pcap")
+    (version "1.3.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "pcap" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "0ygzsi7v2x9ld5cb61dfg8jgifs2rln6qlknypzqjjnmfgy3bscr"))))
+    (build-system cargo-build-system)
+    (arguments
+     `(#:cargo-inputs (("rust-bitflags" ,rust-bitflags-1)
+                       ("rust-errno" ,rust-errno-0.2)
+                       ("rust-etherparse" ,rust-etherparse-0.13)
+                       ("rust-gat-std" ,rust-gat-std-0.1)
+                       ("rust-futures" ,rust-futures-0.3)
+                       ("rust-libc" ,rust-libc-0.2)
+                       ("rust-tokio" ,rust-tokio-1)
+                       ("rust-tun-tap" ,rust-tun-tap-0.1)
+                       ("rust-windows-sys" ,rust-windows-sys-0.36))
+       #:cargo-development-inputs (("rust-eui48" ,rust-eui48-1)
+                                   ("rust-mockall" ,rust-mockall-0.11)
+                                   ("rust-once-cell" ,rust-once-cell-1)
+                                   ("rust-tempdir" ,rust-tempdir-0.3))))
+    (inputs (list libpcap))
+    (home-page "https://github.com/rust-pcap/pcap")
+    (synopsis "Rust packet capture API around pcap/wpcap")
+    (description "This is a Rust language crate for accessing the packet
+sniffing capabilities of libpcap (or Npcap on Windows).")
+    (license (list license:asl2.0 license:expat))))
+
+(define-public rust-pcap-0.11
+  (package
+    (inherit rust-pcap-1)
+    (name "rust-pcap")
+    (version "0.11.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "pcap" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "0sk9d0ygqgpwn6rpdclx8lqxcz8gm470pyfspbdjcgjvyr5jvncq"))))
+    (arguments
+     `(#:cargo-inputs (("rust-bitflags" ,rust-bitflags-1)
+                       ("rust-errno" ,rust-errno-0.2)
+                       ("rust-futures" ,rust-futures-0.3)
+                       ("rust-libc" ,rust-libc-0.2)
+                       ("rust-windows-sys" ,rust-windows-sys-0.36)
+                       ("rust-tokio" ,rust-tokio-1))
+       #:cargo-development-inputs (("rust-libloading" ,rust-libloading-0.6)
+                                   ("rust-pkg-config" ,rust-pkg-config-0.3)
+                                   ("rust-regex" ,rust-regex-1)
+                                   ("rust-eui48" ,rust-eui48-1)
+                                   ("rust-tempdir" ,rust-tempdir-0.3))))))
+
+(define-public rust-pcap-0.10
+  (package
+    (inherit rust-pcap-1)
+    (name "rust-pcap")
+    (version "0.10.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "pcap" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "0yp1akb8y53faf993xv7l7va957waiv9qmjl8m3mpijw2744999d"))))
+    (arguments
+     `(#:cargo-inputs (("rust-bitflags" ,rust-bitflags-1)
+                       ("rust-errno" ,rust-errno-0.2)
+                       ("rust-futures" ,rust-futures-0.3)
+                       ("rust-libc" ,rust-libc-0.2)
+                       ("rust-windows-sys" ,rust-windows-sys-0.36)
+                       ("rust-tokio" ,rust-tokio-1))
+       #:cargo-development-inputs (("rust-eui48" ,rust-eui48-1)
+                                   ("rust-libloading" ,rust-libloading-0.6)
+                                   ("rust-regex" ,rust-regex-1)
+                                   ("rust-tempdir" ,rust-tempdir-0.3))))))
+
 (define-public rust-pcap-0.7
   (package
+    (inherit rust-pcap-0.10)
     (name "rust-pcap")
     (version "0.7.0")
     (source
@@ -46228,8 +46420,6 @@ (define-public rust-pcap-0.7
        (file-name (string-append name "-" version ".tar.gz"))
        (sha256
         (base32 "14blflnbj87z3ajlj1hszsl6k7rwa338y4aw2yjm2j0xdpjvj4pr"))))
-    (native-inputs (list libpcap))
-    (build-system cargo-build-system)
     (arguments
      `(#:tests? #f  ; can't find crate for `futures`
        #:cargo-inputs
@@ -46239,11 +46429,7 @@ (define-public rust-pcap-0.7
         ("rust-mio" ,rust-mio-0.6)
         ("rust-tokio-core" ,rust-tokio-core-0.1))
        #:cargo-development-inputs
-       (("rust-tempdir" ,rust-tempdir-0.3))))
-    (home-page "https://github.com/rust-pcap/pcap")
-    (synopsis "Packet capture API around pcap/wpcap")
-    (description "This package provides a packet capture API around pcap/wpcap.")
-    (license (list license:expat license:asl2.0))))
+       (("rust-tempdir" ,rust-tempdir-0.3))))))
 
 (define-public rust-pcap-sys-0.1
   (package
@@ -57118,29 +57304,91 @@ (define-public rust-ethtool-0.2
     (description "Linux Ethtool Communication Library.")
     (license license:expat)))
 
-(define-public rust-etherparse-0.13
+
+(define-public rust-etherparse-0.14
   (package
     (name "rust-etherparse")
-    (version "0.13.0")
+    (version "0.14.2")
     (source
      (origin
        (method url-fetch)
        (uri (crate-uri "etherparse" version))
        (file-name (string-append name "-" version ".tar.gz"))
        (sha256
-        (base32 "146rcbnhlpcbl6c6csfhvz0227wbiwhk13md6acq8211b7m94wl2"))))
+        (base32 "1cf9qf089c8a5xlr7az2wcrr0i0l2zi1q9h2ixwalhsbxc1hd294"))))
     (build-system cargo-build-system)
     (arguments
      `(#:cargo-inputs (("rust-arrayvec" ,rust-arrayvec-0.7))
-       #:cargo-development-inputs (("rust-assert-matches" ,rust-assert-matches-1)
-                                   ("rust-proptest" ,rust-proptest-1))))
+       #:cargo-development-inputs (("rust-proptest" ,rust-proptest-1))))
     (home-page "https://github.com/JulianSchmid/etherparse")
-    (synopsis "Library for parsing & writing a bunch of packet based protocols")
+    (synopsis
+     "Library for parsing & writing a bunch of packet based protocols")
     (description
-     "This package provides a library for parsing & writing a bunch of packet
-based protocols (@code{EthernetII}, IPv4, IPv6, UDP, TCP ...).")
+     "A zero allocation library for parsing & writing a bunch of
+packet based protocols (EthernetII, IPv4, IPv6, UDP, TCP ...).")
     (license (list license:expat license:asl2.0))))
 
+(define-public rust-etherparse-0.13
+  (package
+    (inherit rust-etherparse-0.14)
+    (name "rust-etherparse")
+    (version "0.13.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "etherparse" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "146rcbnhlpcbl6c6csfhvz0227wbiwhk13md6acq8211b7m94wl2"))))
+    (arguments
+     `(#:cargo-inputs (("rust-arrayvec" ,rust-arrayvec-0.7))
+       #:cargo-development-inputs (("rust-assert-matches" ,rust-assert-matches-1)
+                                   ("rust-proptest" ,rust-proptest-1))))))
+
+(define-public rust-etherparse-0.9
+  (package
+    (inherit rust-etherparse-0.13)
+    (name "rust-etherparse")
+    (version "0.9.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "etherparse" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "01s86nj0k663mgxpj3r7y5wr50l5c3aq0pm4rpzyb7hz50i0k8ig"))))
+    (arguments
+     `(#:cargo-inputs (("rust-byteorder" ,rust-byteorder-1))
+       #:cargo-development-inputs (("rust-assert-matches" ,rust-assert-matches-1)
+                                   ("rust-proptest" ,rust-proptest-0.9))))))
+
+(define-public rust-eui48-1
+  (package
+    (name "rust-eui48")
+    (version "1.1.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "eui48" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "00cpf25kc3mxhqnahm0bw9xl19gr2pzc5g84dvkc4mwdbsn1hx48"))))
+    (build-system cargo-build-system)
+    (arguments
+     `(#:cargo-inputs (("rust-regex" ,rust-regex-1)
+                       ("rust-rustc-serialize" ,rust-rustc-serialize-0.3)
+                       ("rust-serde" ,rust-serde-1)
+                       ("rust-serde-json" ,rust-serde-json-1))
+       #:cargo-development-inputs (("rust-bincode" ,rust-bincode-1))))
+    (home-page "https://github.com/abaumhauer/eui48")
+    (synopsis "Rust implementation of IEEE EUI-48 (MAC-48) datatype")
+    (description
+     "A library to generate and parse IEEE EUI-48 and EUI-64, also
+known as MAC-48 media access control addresses.  The IEEE claims trademarks on
+the names EUI-48 and EUI-64, in which EUI is an abbreviation for Extended Unique
+Identifier.")
+    (license (list license:asl2.0 license:expat))))
+
 (define-public rust-rust-hawktracer-0.7
   (package
     (name "rust-rust-hawktracer")
@@ -62931,26 +63179,23 @@ (define-public rust-skim-0.7
 (define-public rust-slab-0.4
   (package
     (name "rust-slab")
-    (version "0.4.8")
+    (version "0.4.9")
     (source
-      (origin
-        (method url-fetch)
-        (uri (crate-uri "slab" version))
-        (file-name (string-append name "-" version ".tar.gz"))
-        (sha256
-         (base32
-          "0bgwxig8gkqp6gz8rvrpdj6qwa10karnsxwx7wsj5ay8kcf3aa35"))))
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "slab" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "0rxvsgir0qw5lkycrqgb1cxsvxzjv9bmx73bk5y42svnzfba94lg"))))
     (build-system cargo-build-system)
     (arguments
-     `(#:cargo-development-inputs
-       (("rust-rustversion" ,rust-rustversion-1)
-        ("rust-serde" ,rust-serde-1)
-        ("rust-serde-test" ,rust-serde-test-1))
-       #:cargo-inputs (("rust-autocfg" ,rust-autocfg-1)
-                       ("rust-serde" ,rust-serde-1))))
-    (native-inputs
-     (list rust-autocfg-1))
-    (home-page "https://github.com/carllerche/slab")
+     `(#:cargo-development-inputs (("rust-rustversion" ,rust-rustversion-1)
+                                   ("rust-serde" ,rust-serde-1)
+                                   ("rust-serde-test" ,rust-serde-test-1)
+                                   ("rust-autocfg" ,rust-autocfg-1))
+       #:cargo-inputs (("rust-serde" ,rust-serde-1)
+                       ("rust-autocfg" ,rust-autocfg-1))))
+    (home-page "https://github.com/tokio-rs/slab")
     (synopsis "Pre-allocated storage for a uniform data type")
     (description "This create provides a pre-allocated storage for a uniform
 data type.")
@@ -74935,6 +75180,38 @@ (define-public rust-tuikit-0.2
        #:cargo-development-inputs
        (("rust-env-logger" ,rust-env-logger-0.6))))))
 
+(define-public rust-tun-tap-0.1
+  (package
+    (name "rust-tun-tap")
+    (version "0.1.4")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (crate-uri "tun-tap" version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "0l5yp9xs5kyhzrkqfhnqjwj97ylzr5xd0g6jfp42miv7jd77liws"))))
+    (build-system cargo-build-system)
+    (arguments
+     `(#:cargo-test-flags '("--"
+                            ;; Network access not allowed in build environment
+                            "--skip=it_receives_packets"
+                            "--skip=it_sents_packets")
+       #:cargo-inputs (("rust-futures" ,rust-futures-0.1)
+                       ("rust-libc" ,rust-libc-0.2)
+                       ("rust-mio" ,rust-mio-0.6)
+                       ("rust-tokio-core" ,rust-tokio-core-0.1))
+       #:cargo-development-inputs (("rust-cc" ,rust-cc-1)
+                                   ("rust-etherparse" ,rust-etherparse-0.9)
+                                   ("rust-serial-test" ,rust-serial-test-0.4)
+                                   ("rust-version-sync" ,rust-version-sync-0.9))))
+    (home-page "https://github.com/vorner/tuntap")
+    (synopsis "TUN/TAP interface wrapper")
+    (description
+     "Rust TUN/TAP wrapper allowing the implementation of virtual network adaptors in
+userspace.")
+    (license (list license:expat license:asl2.0))))
+
 (define-public rust-twoway-0.2
   (package
     (name "rust-twoway")
diff --git a/gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch b/gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
new file mode 100644
index 0000000000..1c1f77eb0d
--- /dev/null
+++ b/gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
@@ -0,0 +1,7611 @@
+This patch restores the tests and examples that were removed from
+mockall when it was bundled for distribution. They are required
+to enable testing of the built packages.
+
+---
+diff --git a/examples/ffi.rs b/examples/ffi.rs
+new file mode 100644
+index 0000000..6b7c9d0
+--- /dev/null
++++ b/examples/ffi.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! An example of unit testing involving mocked FFI functions
++
++#[cfg(test)]
++use mockall::automock;
++use mockall_double::double;
++
++#[cfg_attr(test, automock)]
++pub mod mockable_ffi {
++    extern "C" {
++        pub fn abs(i: i32) -> i32;
++    }
++}
++
++#[double]
++use mockable_ffi as ffi;
++
++fn abs(i: i32) -> i32 {
++    unsafe { ffi::abs(i) }
++}
++
++fn main() {
++    let i: i32 = -42;
++    println!("abs({}) = {}", i, abs(i) );
++}
++
++
++#[test]
++fn time_test() {
++    let ctx = ffi::abs_context();
++    ctx.expect()
++        .return_const(42);
++    assert_eq!(42, abs(-42))
++}
+diff --git a/examples/serde.rs b/examples/serde.rs
+new file mode 100644
+index 0000000..4498449
+--- /dev/null
++++ b/examples/serde.rs
+@@ -0,0 +1,102 @@
++// vim: tw=80
++//! Mock a struct that implements Serde traits
++//!
++//! Serde defines to popular traits that look like this:
++//! ```ignore
++//! trait Serialize {
++//!     fn serialize<S: Serializer>(&self, serializer: S) -> Result<String, anyhow::Error>;
++//! }
++//! trait Deserialize {
++//!     fn deserialize<D: Deserializer>(deserializer: D) -> Result<Self, anyhow::Error>;
++//! }
++//! ```
++//!
++//! Mockall can usually implement traits with generic methods.  However,
++//! `serde::Serializer` isn't `'static`, and the definition of
++//! `Serialize::serialize` doesn't require `S` to be static.  That's a problem,
++//! because Mockall requires that all generic methods' generic types be
++//! `'static` so that they can implement `std::any::Any`.
++//!
++//! There's no getting around that requirement.  But there's still hope!  You
++//! can mock a struct that implements Serde traits by manually implementing
++//! `Serialize` and `Deserialize` in terms of non-generic methods, using a
++//! surrogate object for the expectations.
++#![deny(warnings)]
++
++use mockall::*;
++use serde::{Deserialize, Deserializer};
++use serde_derive::*;
++
++/// A serializable surrogate for `Thing`.  It should serialize and deserialize
++/// in exactly the same way as `Thing`.  In fact, it may even be `Thing`.
++#[derive(Deserialize, Serialize)]
++pub struct SurrogateThing {
++    x: u32
++}
++
++mock! {
++    pub Thing {
++        // MockThing's private deserialize method.  The name is not important,
++        // but you probably don't want to call it `deserialize` because then
++        // you'll have to call the real deserialize method using
++        // `<x as Deserialize>::deserialize` syntax.
++        //
++        // This method must always succeed (or panic), because `Deserialize`'s
++        // error type is neither `'static` nor `Default`.
++        fn private_deserialize(deserializable: Result<SurrogateThing, ()>) -> Self;
++        // MockThing's private serialize method.  The name is not important,
++        // but you probably don't want to call it `serialize` because then
++        // you'll have to call the real serialize method using
++        // `<x as Serialize>::serialize` syntax.
++        //
++        // This method must always succeed (or panic), because `Serialize`'s
++        // error type is neither `'static` nor `Default`.
++        fn private_serialize(&self) -> SurrogateThing;
++    }
++}
++
++// Manually implement Serialize for MockThing
++impl serde::Serialize for MockThing {
++    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
++        self.private_serialize().serialize(s)
++    }
++}
++
++// Manually implement Deserialize for MockThing
++impl<'de> Deserialize<'de> for MockThing {
++    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
++    where
++        D: Deserializer<'de>,
++    {
++        let serializable = SurrogateThing::deserialize(deserializer)
++            .map_err(|_| ());
++        Ok(MockThing::private_deserialize(serializable))
++    }
++}
++
++// In your tests, set an expectation for `private_serialize` and return a
++// suitable `SurrogateThing`
++#[test]
++fn serialize() {
++    let mut mock = MockThing::default();
++    mock.expect_private_serialize()
++        .returning(|| SurrogateThing{x: 42} );
++
++    let json = serde_json::to_string(&mock).unwrap();
++    assert_eq!("{\"x\":42}", json);
++}
++
++// In your tests, set an expectation for `private_deserialize`, which will
++// receive an already-deserialized `SurrogateThing` object.
++#[test]
++fn deserialize() {
++    let ctx = MockThing::private_deserialize_context();
++    ctx.expect()
++        .withf(|st: &Result<SurrogateThing, ()>|
++               st.as_ref().unwrap().x == 42
++        ).once()
++        .returning(|_| MockThing::default());
++
++    let json = "{\"x\":42}";
++    let _thing: MockThing = serde_json::from_str(json).unwrap();
++}
+diff --git a/examples/synchronization.rs b/examples/synchronization.rs
+new file mode 100644
+index 0000000..a943b88
+--- /dev/null
++++ b/examples/synchronization.rs
+@@ -0,0 +1,64 @@
++// vim: tw=80
++//! Add synchronization to multiple tests that are accessing the same mock
++//!
++//! When mockall mocks a function or static method, it does so globally. This
++//! can cause hard to debug and non-deterministic failures when one test
++//! overwrites the mock that another test is depending on. The solution to this
++//! is to add some form of synchronization so that tests that depend on a
++//! specific mock will not run in parallel. This is easily achieved using a
++//! Mutex.
++#![deny(warnings)]
++
++use mockall_double::double;
++
++pub mod my_mock {
++    #[cfg(test)]
++    use mockall::automock;
++
++    pub struct Thing;
++    #[cfg_attr(test, automock)]
++    impl Thing {
++        pub fn one() -> u32 {
++            1
++        }
++    }
++}
++
++#[double]
++use my_mock::Thing;
++
++fn main() {
++    println!("1 == {}", Thing::one());
++}
++
++#[cfg(test)]
++mod test {
++    use crate::my_mock::MockThing;
++    use std::sync::Mutex;
++
++    static MTX: Mutex<()> = Mutex::new(());
++
++    #[test]
++    fn test_1() {
++        // The mutex might be poisoned if another test fails.  But we don't
++        // care, because it doesn't hold any data.  So don't unwrap the Result
++        // object; whether it's poisoned or not, we'll still hold the
++        // MutexGuard.
++        let _m = MTX.lock();
++
++        let ctx = MockThing::one_context();
++        ctx.expect().returning(|| 1);
++        let expected = 1;
++        assert_eq!(expected, MockThing::one())
++    }
++
++    #[test]
++    fn test_2() {
++        let _m = MTX.lock();
++
++        let ctx = MockThing::one_context();
++        ctx.expect().returning(|| 2);
++        let expected = 2;
++        assert_eq!(expected, MockThing::one())
++    }
++}
+diff --git a/tests/anyhow.rs b/tests/anyhow.rs
+new file mode 100644
+index 0000000..f4f0fd4
+--- /dev/null
++++ b/tests/anyhow.rs
+@@ -0,0 +1,86 @@
++// vim: tw=80
++//! Mockall should be compatible with crates like Anyhow that redefine `Ok`.
++#![deny(warnings)]
++
++use mockall::*;
++
++// Define Error, Result, and Ok similarly to how anyhow defines them
++pub struct Error();
++impl Error {
++    pub fn new<E: std::error::Error>(_e: E) -> Self {
++        Self()
++    }
++}
++#[allow(non_snake_case)]
++pub fn Ok<T>(t: T) -> Result<T> {
++    Result::Ok(t)
++}
++pub type Result<T, E = Error> = std::result::Result<T, E>;
++
++#[automock]
++pub trait Foo {
++    fn foo(&self) -> Result<(), Error>;
++    fn reffoo(&self) -> &Result<(), Error>;
++    fn refmutfoo(&mut self) -> &mut Result<(), Error>;
++    fn staticfoo() -> Result<(), Error>;
++}
++
++mod static_method {
++    use super::*;
++
++    #[test]
++    fn ok() {
++        let mut foo = MockFoo::new();
++        foo.expect_foo()
++            .returning(|| Ok(()));
++        assert!(foo.foo().is_ok());
++    }
++
++    #[test]
++    fn err() {
++        let mut foo = MockFoo::new();
++        foo.expect_foo()
++            .returning(|| Err(Error::new(std::io::Error::last_os_error())));
++        assert!(foo.foo().is_err());
++    }
++}
++
++mod ref_method {
++    use super::*;
++
++    #[test]
++    fn ok() {
++        let mut foo = MockFoo::new();
++        foo.expect_reffoo()
++            .return_const(Ok(()));
++        assert!(foo.reffoo().is_ok());
++    }
++
++    #[test]
++    fn err() {
++        let mut foo = MockFoo::new();
++        foo.expect_reffoo()
++            .return_const(Err(Error::new(std::io::Error::last_os_error())));
++        assert!(foo.reffoo().is_err());
++    }
++}
++
++mod refmut_method {
++    use super::*;
++
++    #[test]
++    fn ok() {
++        let mut foo = MockFoo::new();
++        foo.expect_refmutfoo()
++            .return_var(Ok(()));
++        assert!(foo.refmutfoo().is_ok());
++    }
++
++    #[test]
++    fn err() {
++        let mut foo = MockFoo::new();
++        foo.expect_refmutfoo()
++            .return_var(Err(Error::new(std::io::Error::last_os_error())));
++        assert!(foo.refmutfoo().is_err());
++    }
++}
+diff --git a/tests/automock_associated_const.rs b/tests/automock_associated_const.rs
+new file mode 100644
+index 0000000..b7c14cf
+--- /dev/null
++++ b/tests/automock_associated_const.rs
+@@ -0,0 +1,56 @@
++// vim: tw=80
++//! A trait with an associated constant
++//!
++//! It's not possible to automock the trait, like:
++//! ```
++//! #[automock]
++//!     trait Foo {
++//!     const X: i32;
++//! }
++//! ```
++//! because there's no way to set the value of X on MockFoo.
++//!
++//! But it _is_ possible to automock the trait implementation, like this:
++//! ```
++//! struct Bar {}
++//! #[automock]
++//! impl Foo for Bar {
++//!     const X: i32;
++//! }
++//! ```
++//!
++//! https://github.com/asomers/mockall/issues/97
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++    const X: i32;
++
++    fn x_plus_one(&self) -> i32 {
++        Self::X + 1
++    }
++}
++
++pub struct Bar {}
++
++#[automock]
++impl Foo for Bar {
++    const X: i32 = 42;
++}
++
++pub struct Baz {}
++#[automock]
++impl Baz {
++    pub const Y: i32 = 69;
++}
++
++#[test]
++fn default_method() {
++    assert_eq!(MockBar::new().x_plus_one(), 43);
++}
++
++#[test]
++fn on_a_struct() {
++    assert_eq!(MockBaz::Y, 69);
++}
+diff --git a/tests/automock_associated_type_constructor.rs b/tests/automock_associated_type_constructor.rs
+new file mode 100644
+index 0000000..c9a5a1a
+--- /dev/null
++++ b/tests/automock_associated_type_constructor.rs
+@@ -0,0 +1,36 @@
++// vim: tw=80
++//! A constructor that returns Self as an associated type of some other trait.
++//! This is very useful when working with Futures.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub trait MyIterator {
++    type Item;
++}
++
++pub struct Foo{}
++
++#[automock]
++impl Foo {
++    pub fn open() -> impl MyIterator<Item=Self> {
++        struct Bar {}
++        impl MyIterator for Bar {
++            type Item=Foo;
++        }
++        Bar{}
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = MockFoo::open_context();
++    ctx.expect().returning(|| {
++        struct Baz {}
++        impl MyIterator for Baz {
++            type Item = MockFoo;
++        }
++        Box::new(Baz{})
++    });
++    let _a = MockFoo::open();
++}
+diff --git a/tests/automock_associated_types.rs b/tests/automock_associated_types.rs
+new file mode 100644
+index 0000000..82ffa78
+--- /dev/null
++++ b/tests/automock_associated_types.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! automatic-style mocking with associated types
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock(type T=u32;)]
++trait A {
++    type T: Clone;
++    fn foo(&self, x: Self::T) -> Self::T;
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockA::new();
++    mock.expect_foo()
++        .returning(|x| x);
++    assert_eq!(4, mock.foo(4));
++}
+diff --git a/tests/automock_associated_types_with_qself.rs b/tests/automock_associated_types_with_qself.rs
+new file mode 100644
+index 0000000..937e5b4
+--- /dev/null
++++ b/tests/automock_associated_types_with_qself.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++//! automatic-style mocking with associated types, with QSelf
++#![deny(warnings)]
++
++use mockall::*;
++
++trait SomeTrait<Q>{}
++struct Foo {}
++impl SomeTrait<u32> for Foo {}
++
++#[automock(type T=u32;)]
++trait A {
++    type T: Clone;
++    fn baz(&self) -> Box<dyn SomeTrait<<Self as A>::T>>;
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockA::new();
++    mock.expect_baz()
++        .returning(|| Box::new(Foo{}));
++    mock.baz();
++}
+diff --git a/tests/automock_async_trait.rs b/tests/automock_async_trait.rs
+new file mode 100644
+index 0000000..4e642b5
+--- /dev/null
++++ b/tests/automock_async_trait.rs
+@@ -0,0 +1,31 @@
++// vim: tw=80
++//! An async trait, for use with Futures
++#![deny(warnings)]
++
++use async_trait::async_trait;
++use futures::executor::block_on;
++use mockall::*;
++
++#[automock]
++#[async_trait]
++pub trait Foo {
++    async fn foo(&self) -> u32;
++    async fn bar() -> u32;
++}
++
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(42u32);
++    assert_eq!(block_on(mock.foo()), 42);
++}
++
++#[test]
++fn static_method() {
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .return_const(42u32);
++    assert_eq!(block_on(MockFoo::bar()), 42);
++}
+diff --git a/tests/automock_attrs.rs b/tests/automock_attrs.rs
+new file mode 100644
+index 0000000..bbae260
+--- /dev/null
++++ b/tests/automock_attrs.rs
+@@ -0,0 +1,57 @@
++// vim: tw=80
++//! Attributes are applied to the mock object, too.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub mod m {
++    #[cfg(target_os = "multics")]
++    pub fn bloob(x: DoesNotExist) -> i64 {unimplemented!()}
++    #[cfg(not(target_os = "multics"))]
++    pub fn blarg(_x: i32) -> i64 {unimplemented!()}
++}
++
++#[test]
++fn returning() {
++    let ctx = mock_m::blarg_context();
++    ctx.expect()
++        .returning(|x| i64::from(x) + 1);
++    assert_eq!(5, mock_m::blarg(4));
++}
++
++pub struct A{}
++#[automock]
++impl A {
++    // Neither A::foo nor MockA::foo should be defined
++    #[cfg(target_os = "multics")] pub fn foo(&self, x: DoesNotExist) {}
++    // Both A::bar and MockA::bar should be defined
++    #[cfg(not(target_os = "multics"))] pub fn bar(&self, _x: i32) -> i32 {0}
++}
++
++#[automock]
++pub mod ffi {
++    extern "C" {
++        // mock_ffi::baz should not be defined
++        #[cfg(target_os = "multics")]
++        pub fn baz(x: DoesNotExist) -> i64;
++        // mock_ffi::bean should be defined
++        #[cfg(not(target_os = "multics"))]
++        pub fn bean(x: u32) -> i64;
++    }
++}
++
++#[test]
++fn method() {
++    let mut mock = MockA::new();
++    mock.expect_bar()
++        .returning(|x| x);
++    assert_eq!(4, mock.bar(4));
++}
++
++#[test]
++fn foreign() {
++    let ctx = mock_ffi::bean_context();
++    ctx.expect().returning(i64::from);
++    assert_eq!(42, unsafe{mock_ffi::bean(42)});
++}
+diff --git a/tests/automock_boxed_constructor.rs b/tests/automock_boxed_constructor.rs
+new file mode 100644
+index 0000000..f0d13c9
+--- /dev/null
++++ b/tests/automock_boxed_constructor.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! A trait with a constructor method that returns Box<Self>
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub trait A {
++    fn new() -> Box<Self>;
++}
++
++#[test]
++fn returning() {
++    let ctx = MockA::new_context();
++    ctx.expect().returning(Box::default);
++    let _a: Box<MockA> = <MockA as A>::new();
++}
+diff --git a/tests/automock_concretize.rs b/tests/automock_concretize.rs
+new file mode 100644
+index 0000000..f169a20
+--- /dev/null
++++ b/tests/automock_concretize.rs
+@@ -0,0 +1,50 @@
++// vim: tw=80
++//! #[concretize] works with #[automock], too.
++#![deny(warnings)]
++
++use mockall::*;
++use std::path::{Path, PathBuf};
++
++#[automock]
++trait Foo {
++    #[concretize]
++    fn foo<P: AsRef<std::path::Path>>(&self, x: P);
++}
++
++#[automock]
++pub mod mymod {
++    #[mockall::concretize]
++    pub fn bang<P: AsRef<std::path::Path>>(_x: P) { unimplemented!() }
++}
++
++mod generic_arg {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_foo()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        foo.foo(Path::new("/tmp"));
++        foo.foo(PathBuf::from(Path::new("/tmp")));
++        foo.foo("/tmp");
++    }
++}
++
++mod module {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let ctx = mock_mymod::bang_context();
++        ctx.expect()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        mock_mymod::bang(Path::new("/tmp"));
++        mock_mymod::bang(PathBuf::from(Path::new("/tmp")));
++        mock_mymod::bang("/tmp");
++    }
++}
+diff --git a/tests/automock_constructor_impl_trait.rs b/tests/automock_constructor_impl_trait.rs
+new file mode 100644
+index 0000000..7384e11
+--- /dev/null
++++ b/tests/automock_constructor_impl_trait.rs
+@@ -0,0 +1,30 @@
++// vim: tw=80
++//! A trait with a constructor method that returns impl Trait
++#![deny(warnings)]
++
++use mockall::*;
++
++pub trait Foo {}
++
++pub struct A{}
++
++struct Bar {}
++impl Foo for Bar {}
++
++#[automock]
++impl A {
++    pub fn build() -> impl Foo {
++        Bar{}
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = MockA::build_context();
++    ctx.expect().returning(|| {
++        struct Baz {}
++        impl Foo for Baz {}
++        Box::new(Baz{})
++    });
++    let _a = MockA::build();
++}
+diff --git a/tests/automock_constructor_in_generic_trait.rs b/tests/automock_constructor_in_generic_trait.rs
+new file mode 100644
+index 0000000..550fcb3
+--- /dev/null
++++ b/tests/automock_constructor_in_generic_trait.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A generic trait with a non-generic constructor method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo<T: 'static> {
++    fn new(t: T) -> Self;
++}
++
++#[test]
++fn return_once() {
++    let mock = MockFoo::<u32>::default();
++
++    let ctx = MockFoo::<u32>::new_context();
++    ctx.expect()
++        .return_once(move |_| mock);
++
++    let _mock = MockFoo::new(5u32);
++}
+diff --git a/tests/automock_constructor_in_struct.rs b/tests/automock_constructor_in_struct.rs
+new file mode 100644
+index 0000000..1c3a895
+--- /dev/null
++++ b/tests/automock_constructor_in_struct.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A struct with a constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct A {}
++
++#[automock]
++#[allow(clippy::new_without_default)]
++impl A {
++    pub fn new() -> Self {
++        unimplemented!()
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = MockA::new_context();
++    ctx.expect().returning(MockA::default);
++    let _a: MockA = MockA::new();
++}
+diff --git a/tests/automock_constructor_in_trait.rs b/tests/automock_constructor_in_trait.rs
+new file mode 100644
+index 0000000..1bd0189
+--- /dev/null
++++ b/tests/automock_constructor_in_trait.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! A trait with a constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub trait A {
++    fn new() -> Self;
++}
++
++#[test]
++fn returning() {
++    let ctx = MockA::new_context();
++    ctx.expect().returning(MockA::default);
++    let _a: MockA = <MockA as A>::new();
++}
+diff --git a/tests/automock_constructor_in_trait_with_args.rs b/tests/automock_constructor_in_trait_with_args.rs
+new file mode 100644
+index 0000000..f7373ba
+--- /dev/null
++++ b/tests/automock_constructor_in_trait_with_args.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++//! A struct with a constructor method named "new" that has arguments.
++//! mockall should mock the provided method, and not autogenerate a 0-argument
++//! "new" method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++    fn new(x: u32) -> Self;
++}
++
++#[test]
++fn return_once() {
++    let mock = MockFoo::default();
++    let ctx = MockFoo::new_context();
++
++    ctx.expect()
++        .return_once(|_| mock);
++
++    let _mock = MockFoo::new(5);
++}
+diff --git a/tests/automock_constructor_with_args.rs b/tests/automock_constructor_with_args.rs
+new file mode 100644
+index 0000000..5a6f563
+--- /dev/null
++++ b/tests/automock_constructor_with_args.rs
+@@ -0,0 +1,25 @@
++// vim: tw=80
++//! A struct with a constructor method named "new" that has arguments.
++//! mockall should mock the provided method, and not autogenerate a 0-argument
++//! "new" method.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo{}
++
++#[automock]
++impl Foo {
++    pub fn new(_x: u32) -> Self {unimplemented!()}
++}
++
++#[test]
++fn return_once() {
++    let mock = MockFoo::default();
++    let ctx = MockFoo::new_context();
++
++    ctx.expect()
++        .return_once(|_| mock);
++
++    let _mock = MockFoo::new(5);
++}
+diff --git a/tests/automock_consume_arguments.rs b/tests/automock_consume_arguments.rs
+new file mode 100644
+index 0000000..eb47fe8
+--- /dev/null
++++ b/tests/automock_consume_arguments.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++struct NonCopy{}
++
++#[automock]
++trait T {
++    fn foo(&self, x: NonCopy);
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockT::new();
++    mock.expect_foo()
++        .returning(|_x: NonCopy| ());
++    mock.foo(NonCopy{});
++}
+diff --git a/tests/automock_custom_result.rs b/tests/automock_custom_result.rs
+new file mode 100644
+index 0000000..89f7591
+--- /dev/null
++++ b/tests/automock_custom_result.rs
+@@ -0,0 +1,42 @@
++// vim: tw=80
++//! It should be possible to use a custom Result type in the signature of a
++//! mocked method.  Regression test for
++//! https://github.com/asomers/mockall/issues/73
++#![deny(warnings)]
++
++use mockall::*;
++
++pub type Result<T> = std::result::Result<T, String>;
++
++pub struct MyStruct {}
++
++#[automock]
++impl MyStruct {
++    pub fn ret_static(&self) -> Result<i32> { unimplemented!() }
++    pub fn ret_ref(&self) -> &Result<i32> { unimplemented!() }
++    pub fn ret_refmut(&mut self) -> &mut Result<i32> { unimplemented!() }
++}
++
++#[test]
++fn ret_ref() {
++    let mut s = MockMyStruct::new();
++    s.expect_ret_ref()
++        .return_const(Ok(42));
++    assert_eq!(Ok(42), *s.ret_ref());
++}
++
++#[test]
++fn ret_ref_mut() {
++    let mut s = MockMyStruct::new();
++    s.expect_ret_refmut()
++        .return_var(Ok(42));
++    assert_eq!(Ok(42), *s.ret_refmut());
++}
++
++#[test]
++fn ret_static() {
++    let mut s = MockMyStruct::new();
++    s.expect_ret_static()
++        .return_const(Ok(42));
++    assert_eq!(Ok(42), s.ret_static());
++}
+diff --git a/tests/automock_debug.rs b/tests/automock_debug.rs
+new file mode 100644
+index 0000000..6341c75
+--- /dev/null
++++ b/tests/automock_debug.rs
+@@ -0,0 +1,35 @@
++// vim: tw=80
++//! A mocked struct should implement Debug
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub trait Foo {}
++
++pub trait Bar {}
++pub struct Baz {}
++#[automock]
++impl Bar for Baz{}
++
++pub struct Bean {}
++#[automock]
++impl Bean{}
++
++#[test]
++fn automock_trait() {
++    let foo = MockFoo::new();
++    assert_eq!("MockFoo", format!("{foo:?}"));
++}
++
++#[test]
++fn automock_struct_impl() {
++    let bean = MockBean::new();
++    assert_eq!("MockBean", format!("{bean:?}"));
++}
++
++#[test]
++fn automock_trait_impl() {
++    let baz = MockBaz::new();
++    assert_eq!("MockBaz", format!("{baz:?}"));
++}
+diff --git a/tests/automock_deref.rs b/tests/automock_deref.rs
+new file mode 100644
+index 0000000..61c55b3
+--- /dev/null
++++ b/tests/automock_deref.rs
+@@ -0,0 +1,74 @@
++// vim: tw=80
++//! A method that returns a type which is a common target for std::ops::Deref
++#![deny(warnings)]
++
++use mockall::*;
++use std::{
++    ffi::{CStr, CString, OsStr, OsString},
++    path::{Path, PathBuf},
++};
++
++#[automock]
++trait Foo {
++    fn name(&self) -> &CStr;
++    fn alias(&self) -> &str;
++    fn desc(&self) -> &OsStr;
++    fn path(&self) -> &Path;
++    fn text(&self) -> &'static str;
++    fn slice(&self) -> &[i32];
++}
++
++mod return_const {
++    use super::*;
++
++    #[test]
++    fn cstr() {
++        let mut mock = MockFoo::new();
++        let name = CString::new("abcd").unwrap();
++        mock.expect_name().return_const(name.clone());
++        assert_eq!(name.as_c_str(), mock.name());
++    }
++
++    #[test]
++    fn osstr() {
++        let mut mock = MockFoo::new();
++        let desc = OsString::from("abcd");
++        mock.expect_desc().return_const(desc.clone());
++        assert_eq!(desc.as_os_str(), mock.desc());
++    }
++
++    #[test]
++    fn path() {
++        let mut mock = MockFoo::new();
++        let mut pb = PathBuf::new();
++        pb.push("foo");
++        pb.push("bar");
++        pb.push("baz");
++        mock.expect_path().return_const(pb.clone());
++        assert_eq!(pb.as_path(), mock.path());
++    }
++
++    #[test]
++    fn str() {
++        let mut mock = MockFoo::new();
++        mock.expect_alias().return_const("abcd".to_owned());
++        assert_eq!("abcd", mock.alias());
++    }
++
++    #[allow(clippy::redundant_static_lifetimes)]
++    #[test]
++    fn static_str() {
++        const TEXT: &'static str = "abcd";
++        let mut mock = MockFoo::new();
++        mock.expect_text().return_const(TEXT);
++        assert_eq!("abcd", mock.text());
++    }
++
++    #[test]
++    fn slice() {
++        let r = vec![1, 2, 3];
++        let mut mock = MockFoo::new();
++        mock.expect_slice().return_const(r);
++        assert_eq!(&[1, 2, 3], mock.slice());
++    }
++}
+diff --git a/tests/automock_extern_std.rs b/tests/automock_extern_std.rs
+new file mode 100644
+index 0000000..3b67c68
+--- /dev/null
++++ b/tests/automock_extern_std.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! automocking a trait when std is only an extern crate (eg., as a testing
++//! support mod for a no_std library). This setup requires some extra "use"s
++//! to make, eg., Box, available.
++
++#![no_std]
++extern crate std;
++
++use mockall::*;
++
++#[automock]
++pub trait SimpleTrait {
++    fn foo(&self, x: u32) -> u32;
++}
++
++#[test]
++fn creating() {
++    let _ = MockSimpleTrait::new();
++}
+diff --git a/tests/automock_foreign_c.rs b/tests/automock_foreign_c.rs
+new file mode 100644
+index 0000000..07eb47d
+--- /dev/null
++++ b/tests/automock_foreign_c.rs
+@@ -0,0 +1,52 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++#[automock]
++mod ffi {
++    extern "C" {
++        pub(super) fn foo(x: u32) -> i64;
++    }
++}
++
++static FOO_MTX: Mutex<()> = Mutex::new(());
++
++// Ensure we can still use the original mocked function
++pub fn normal_usage() {
++    let _m = FOO_MTX.lock();
++    unsafe {
++        ffi::foo(42);
++    }
++}
++
++#[test]
++#[should_panic(expected = "mock_ffi::foo(5): No matching expectation found")]
++fn with_no_matches() {
++    let _m = FOO_MTX.lock();
++    let ctx = mock_ffi::foo_context();
++    ctx.expect()
++        .with(predicate::eq(4))
++        .returning(i64::from);
++    unsafe{ mock_ffi::foo(5) };
++}
++
++#[test]
++fn returning() {
++    let _m = FOO_MTX.lock();
++    let ctx = mock_ffi::foo_context();
++    ctx.expect().returning(i64::from);
++    assert_eq!(42, unsafe{mock_ffi::foo(42)});
++}
++
++/// Ensure that the mock function can be called from C by casting it to a C
++/// function pointer.
++#[test]
++fn c_abi() {
++    let _m = FOO_MTX.lock();
++    let ctx = mock_ffi::foo_context();
++    ctx.expect().returning(i64::from);
++    let p: unsafe extern "C" fn(u32) -> i64 = mock_ffi::foo;
++    assert_eq!(42, unsafe{p(42)});
++}
+diff --git a/tests/automock_foreign_c_variadic.rs b/tests/automock_foreign_c_variadic.rs
+new file mode 100644
+index 0000000..71a62ed
+--- /dev/null
++++ b/tests/automock_foreign_c_variadic.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++#![cfg_attr(feature = "nightly", feature(c_variadic))]
++#![deny(warnings)]
++
++#[cfg(feature = "nightly")]
++use mockall::*;
++
++#[automock]
++#[cfg(feature = "nightly")]
++pub mod ffi {
++    extern "C" {
++        pub fn foo(x: i32, y: i32, ...) -> i32;
++    }
++}
++
++#[test]
++#[cfg(feature = "nightly")]
++#[cfg_attr(miri, ignore)]
++fn mocked_c_variadic() {
++    let ctx = mock_ffi::foo_context();
++    ctx.expect().returning(|x, y| x * y);
++    assert_eq!(6, unsafe{mock_ffi::foo(2, 3, 1, 4, 1)});
++}
+diff --git a/tests/automock_foreign_rust.rs b/tests/automock_foreign_rust.rs
+new file mode 100644
+index 0000000..ccc7ee5
+--- /dev/null
++++ b/tests/automock_foreign_rust.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub mod ffi {
++    extern "Rust" {
++        pub fn foo(_x: u32) -> i64;
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = mock_ffi::foo_context();
++    ctx.expect().returning(i64::from);
++    assert_eq!(42, unsafe{mock_ffi::foo(42)});
++}
+diff --git a/tests/automock_gat.rs b/tests/automock_gat.rs
+new file mode 100644
+index 0000000..4fd4938
+--- /dev/null
++++ b/tests/automock_gat.rs
+@@ -0,0 +1,35 @@
++#! vim: tw=80
++//! automock a trait with Generic Associated Types
++#![deny(warnings)]
++
++use cfg_if::cfg_if;
++
++cfg_if! {
++    if #[cfg(feature = "nightly")] {
++        use mockall::*;
++
++        // The lifetime must have the same name as in the next() method.
++        #[automock(type Item=&'a u32;)]
++        trait LendingIterator {
++            type Item<'a> where Self: 'a;
++
++            // Clippy doesn't know that Mockall will need the lifetime when it
++            // expands the macro.
++            #[allow(clippy::needless_lifetimes)]
++            fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
++        }
++
++        // It isn't possible to safely set an expectation for a non-'static
++        // return value (because the mock object doesn't have any lifetime
++        // parameters itself), but unsafely setting such an expectation is a
++        // common use case.
++        #[test]
++        fn return_const() {
++            let mut mock = MockLendingIterator::new();
++            let x = 42u32;
++            let xstatic: &'static u32 = unsafe{ std::mem::transmute(&x) };
++            mock.expect_next().return_const(Some(xstatic));
++            assert_eq!(42u32, *mock.next().unwrap());
++        }
++    }
++}
+diff --git a/tests/automock_generic_arguments.rs b/tests/automock_generic_arguments.rs
+new file mode 100644
+index 0000000..5b8a9e6
+--- /dev/null
++++ b/tests/automock_generic_arguments.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! generic methods with generic arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++    fn foo<T: 'static>(&self, t: T);
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockA::new();
++    mock.expect_foo::<u32>()
++        .returning(|_x: u32| ());
++    mock.expect_foo::<i16>()
++        .returning(|_x: i16| ());
++    mock.foo(5u32);
++    mock.foo(-1i16);
++}
+diff --git a/tests/automock_generic_arguments_returning_references.rs b/tests/automock_generic_arguments_returning_references.rs
+new file mode 100644
+index 0000000..de1f5c1
+--- /dev/null
++++ b/tests/automock_generic_arguments_returning_references.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! generic methods with generic arguments returning immutable references
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++    fn foo<T: 'static>(&self, t: T) -> &u32;
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockA::new();
++    mock.expect_foo::<u32>().return_const(5);
++    assert_eq!(5, *mock.foo(42u32));
++}
+diff --git a/tests/automock_generic_arguments_with_where_clause.rs b/tests/automock_generic_arguments_with_where_clause.rs
+new file mode 100644
+index 0000000..2d619d9
+--- /dev/null
++++ b/tests/automock_generic_arguments_with_where_clause.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A method with generic arguments bounded by a where clause
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++    fn foo<T>(&self, t: T) where T: Clone + 'static;
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockA::new();
++    mock.expect_foo::<u32>()
++        .returning(|_x: u32| ());
++    mock.expect_foo::<i16>()
++        .returning(|_x: i16| ());
++    mock.foo(5u32);
++    mock.foo(-1i16);
++}
+diff --git a/tests/automock_generic_constructor.rs b/tests/automock_generic_constructor.rs
+new file mode 100644
+index 0000000..d9f7286
+--- /dev/null
++++ b/tests/automock_generic_constructor.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! A non-generic struct can have a generic constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++    fn build<T: 'static>(t: T) -> Self;
++}
++
++#[test]
++fn returning_once() {
++    let ctx = MockFoo::build_context();
++    ctx.expect::<i16>()
++        .return_once(|_| MockFoo::default());
++
++    let _mock: MockFoo = MockFoo::build::<i16>(-1);
++}
+diff --git a/tests/automock_generic_future.rs b/tests/automock_generic_future.rs
+new file mode 100644
+index 0000000..de26d92
+--- /dev/null
++++ b/tests/automock_generic_future.rs
+@@ -0,0 +1,36 @@
++// vim: tw=80
++//! A generic mock object that implements Future
++//!
++//! This is tricky because the Context object has a lifetime parameter, yet the
++//! poll method must not be treated as a generic method.
++#![deny(warnings)]
++
++use futures::executor::block_on;
++use mockall::*;
++use std::{
++    future::Future,
++    pin::Pin,
++    task::{Context, Poll},
++};
++
++struct Foo<T>(T);
++
++#[automock]
++impl<T> Future for Foo<T> {
++    type Output = ();
++
++    fn poll<'a>(self: Pin<&mut Self>, _cx: &mut Context<'a>)
++        -> Poll<Self::Output>
++    {
++        unimplemented!()
++    }
++}
++
++#[test]
++fn ready() {
++    let mut mock = MockFoo::<u32>::new();
++    mock.expect_poll()
++        .once()
++        .return_const(Poll::Ready(()));
++    block_on(mock);
++}
+diff --git a/tests/automock_generic_future_with_where_clause.rs b/tests/automock_generic_future_with_where_clause.rs
+new file mode 100644
+index 0000000..45e80d8
+--- /dev/null
++++ b/tests/automock_generic_future_with_where_clause.rs
+@@ -0,0 +1,36 @@
++// vim: tw=80
++//! A generic mock object with a method that has only lifetime generic
++//! parameters, and a where clause that bounds a generic type not used by the
++//! method.
++//!
++//! Mockall must not emit the where clause for the method's Expectation.
++#![deny(warnings)]
++#![allow(clippy::needless_lifetimes)]
++
++use mockall::*;
++
++struct Foo<T, V>((T, V));
++trait MyTrait {
++    type Item;
++
++    fn myfunc(&self, cx: &NonStatic) -> Self::Item;
++}
++#[allow(dead_code)]
++pub struct NonStatic<'ns>(&'ns i32);
++
++#[automock]
++impl<T, V> MyTrait for Foo<T, V> where T: Clone {
++    type Item = V;
++
++    fn myfunc<'a>(&self, _cx: &NonStatic<'a>) -> V { unimplemented!() }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::<u32, u32>::new();
++    let x = 5i32;
++    let ns = NonStatic(&x);
++    mock.expect_myfunc()
++        .return_const(42u32);
++    assert_eq!(42u32, mock.myfunc(&ns));
++}
+diff --git a/tests/automock_generic_method_with_bounds.rs b/tests/automock_generic_method_with_bounds.rs
+new file mode 100644
+index 0000000..6bc68b1
+--- /dev/null
++++ b/tests/automock_generic_method_with_bounds.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++//! generic methods with bounds on their generic parameters
++#![deny(warnings)]
++
++use mockall::*;
++use std::fmt::Debug;
++
++struct X<T: Debug>(T);
++
++#[automock]
++trait Foo {
++    fn foo<T: Debug + 'static>(&self, x: X<T>);
++}
++
++#[test]
++fn withf() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<u32>()
++        .withf(|x| x.0 == 42u32)
++        .return_const(());
++
++    mock.foo(X(42u32));
++}
+diff --git a/tests/automock_generic_method_with_lifetime_parameter.rs b/tests/automock_generic_method_with_lifetime_parameter.rs
+new file mode 100644
+index 0000000..0c1b65d
+--- /dev/null
++++ b/tests/automock_generic_method_with_lifetime_parameter.rs
+@@ -0,0 +1,48 @@
++// vim: tw=80
++//! A generic method whose only generic parameter is a lifetime parameter is,
++//! from Mockall's perspective, pretty much the same as a non-generic method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Debug, Eq)]
++struct X<'a>(&'a u32);
++
++impl<'a> PartialEq for X<'a> {
++    fn eq(&self, other: &X<'a>) -> bool {
++        self.0 == other.0
++    }
++}
++
++#[automock]
++trait Foo {
++    fn foo<'a>(&self, x: &'a X<'a>) -> u32;
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(42u32);
++    let x = X(&5);
++    assert_eq!(42, mock.foo(&x));
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|f| *f.0);
++    let x = X(&5);
++    assert_eq!(5, mock.foo(&x));
++}
++
++#[test]
++fn withf() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .withf(|f| *f.0 == 5)
++        .return_const(42u32);
++    let x = X(&5);
++    assert_eq!(42, mock.foo(&x));
++}
+diff --git a/tests/automock_generic_method_with_unknown_size_bounds.rs b/tests/automock_generic_method_with_unknown_size_bounds.rs
+new file mode 100644
+index 0000000..4182b2e
+--- /dev/null
++++ b/tests/automock_generic_method_with_unknown_size_bounds.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! generic methods with unknown size bounds on their generic parameters
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++    fn foo<T: 'static + ?Sized>(&self, input: Box<T>);
++}
++
++trait Bar {
++    fn get(&self) -> u32;
++}
++
++struct Foobar {
++    value: u32,
++}
++
++impl Bar for Foobar {
++    fn get(&self) -> u32 {
++        self.value
++    }
++}
++
++#[test]
++fn withf() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<dyn Bar>()
++        .withf(|x| x.get() == 42)
++        .return_const(());
++
++    mock.foo::<dyn Bar>(Box::new(Foobar { value: 42 }));
++}
+diff --git a/tests/automock_generic_method_without_generic_args_or_return.rs b/tests/automock_generic_method_without_generic_args_or_return.rs
+new file mode 100644
+index 0000000..63b297b
+--- /dev/null
++++ b/tests/automock_generic_method_without_generic_args_or_return.rs
+@@ -0,0 +1,44 @@
++// vim: tw=80
++//! generic methods whose generic parameters appear in neither inputs nor return
++//! types should still be mockable, and it should be possible to set
++//! simultaneous expectations for different generic types on the same object.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo{}
++
++#[automock]
++impl Foo {
++    #[allow(clippy::extra_unused_type_parameters)]
++    pub fn foo<T: 'static>(&self) -> i32 {
++        unimplemented!()
++    }
++    /// A static method
++    #[allow(clippy::extra_unused_type_parameters)]
++    pub fn bar<T: 'static>() -> i32 {
++        unimplemented!()
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<f32>()
++        .return_const(42);
++    mock.expect_foo::<f64>()
++        .return_const(69);
++    assert_eq!(42, mock.foo::<f32>());
++    assert_eq!(69, mock.foo::<f64>());
++}
++
++#[test]
++fn static_method() {
++    let ctx = MockFoo::bar_context();
++    ctx.expect::<f32>()
++        .return_const(42);
++    ctx.expect::<f64>()
++        .return_const(69);
++    assert_eq!(42, MockFoo::bar::<f32>());
++    assert_eq!(69, MockFoo::bar::<f64>());
++}
+diff --git a/tests/automock_generic_return.rs b/tests/automock_generic_return.rs
+new file mode 100644
+index 0000000..9ea8944
+--- /dev/null
++++ b/tests/automock_generic_return.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! generic methods with generic return values
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++    fn foo<T: 'static>(&self, t: T) -> T;
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockA::new();
++    mock.expect_foo::<u32>()
++        .returning(|_x: u32| 42u32);
++    mock.expect_foo::<i16>()
++        .returning(|_x: i16| 42i16);
++    assert_eq!(42u32, mock.foo(5u32));
++    assert_eq!(42i16, mock.foo(-1i16));
++}
+diff --git a/tests/automock_generic_static_method.rs b/tests/automock_generic_static_method.rs
+new file mode 100644
+index 0000000..3afc95e
+--- /dev/null
++++ b/tests/automock_generic_static_method.rs
+@@ -0,0 +1,33 @@
++// vim: tw=80
++//! generic static methods with generic arguments
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++static A_MTX: Mutex<()> = Mutex::new(());
++
++#[automock]
++trait A {
++    fn bar<T: 'static>(t: T) -> u32;
++}
++
++#[test]
++fn returning() {
++    let _m = A_MTX.lock().unwrap();
++
++    let ctx = MockA::bar_context();
++    ctx.expect::<i16>()
++        .returning(|_| 42);
++    assert_eq!(42, MockA::bar(-1i16));
++}
++
++#[test]
++fn return_const() {
++    let _m = A_MTX.lock().unwrap();
++
++    let ctx = MockA::bar_context();
++    ctx.expect::<i16>()
++        .return_const(42u32);
++    assert_eq!(42, MockA::bar(-1i16));
++}
+diff --git a/tests/automock_generic_struct.rs b/tests/automock_generic_struct.rs
+new file mode 100644
+index 0000000..2efaba3
+--- /dev/null
++++ b/tests/automock_generic_struct.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! generic structs
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct GenericStruct<T, V> {
++    _t: T,
++    _v: V
++}
++#[automock]
++impl<T, V> GenericStruct<T, V> {
++    pub fn foo(&self, _x: u32) -> i64 {
++        42
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockGenericStruct::<u8, i8>::new();
++    mock.expect_foo()
++        .returning(|x| i64::from(x) + 1);
++    assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_generic_struct_with_bounds.rs b/tests/automock_generic_struct_with_bounds.rs
+new file mode 100644
+index 0000000..b7ba3b4
+--- /dev/null
++++ b/tests/automock_generic_struct_with_bounds.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! generic structs with bounds on their generic parameters
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct GenericStruct<T: Copy, V: Clone> {
++    _t: T,
++    _v: V
++}
++#[automock]
++impl<T: Copy + Copy, V: Clone + Copy> GenericStruct<T, V> {
++    pub fn foo(&self, _x: u32) -> i64 {
++        42
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockGenericStruct::<u8, i8>::new();
++    mock.expect_foo()
++        .returning(|x| i64::from(x) + 1);
++    assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_generic_struct_with_static_method.rs b/tests/automock_generic_struct_with_static_method.rs
+new file mode 100644
+index 0000000..1410113
+--- /dev/null
++++ b/tests/automock_generic_struct_with_static_method.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++//! static non-generic methods of generic structs shouldn't require any special
++//! treatment when mocking.  Prior to version 0.3.0, the struct's generic
++//! parameters had to be duplicated as generic parameters of the method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo<T: 'static> {
++    fn foo(t: T);
++}
++
++#[test]
++fn returning() {
++    let ctx = MockFoo::<u32>::foo_context();
++    ctx.expect()
++        .returning(|_| ());
++    MockFoo::foo(42u32);
++}
+diff --git a/tests/automock_generic_struct_with_where_clause.rs b/tests/automock_generic_struct_with_where_clause.rs
+new file mode 100644
+index 0000000..f62996f
+--- /dev/null
++++ b/tests/automock_generic_struct_with_where_clause.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++//! A struct with generic parameters bounded by a where clause
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct GenericStruct<T> {
++    _t: T,
++}
++#[automock]
++impl<T> GenericStruct<T>
++    where T: Clone + Default
++{
++    #[allow(clippy::redundant_clone)]
++    pub fn foo(&self, x: T) -> T {
++        x.clone()
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockGenericStruct::<u8>::default();
++    mock.expect_foo()
++        .returning(|x| x);
++    assert_eq!(4, mock.foo(4u8));
++}
+diff --git a/tests/automock_generic_trait.rs b/tests/automock_generic_trait.rs
+new file mode 100644
+index 0000000..499ef08
+--- /dev/null
++++ b/tests/automock_generic_trait.rs
+@@ -0,0 +1,30 @@
++// vim: tw=80
++//! generic traits
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A<T> {
++    fn foo(&self, t: T);
++    fn bar(&self) -> T;
++}
++
++#[test]
++fn generic_arguments() {
++    let mut mock = MockA::<u32>::new();
++    mock.expect_foo()
++        .with(mockall::predicate::eq(16u32))
++        .once()
++        .returning(|_| ());
++    mock.foo(16u32);
++}
++
++#[test]
++fn generic_return() {
++    let mut mock = MockA::<u32>::new();
++    mock.expect_bar()
++        .returning(|| 42u32);
++    assert_eq!(42u32, mock.bar());
++}
++
+diff --git a/tests/automock_generic_trait_with_bounds.rs b/tests/automock_generic_trait_with_bounds.rs
+new file mode 100644
+index 0000000..a99e824
+--- /dev/null
++++ b/tests/automock_generic_trait_with_bounds.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! generic traits with bounds on the generic parameters
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A<T: Copy> {
++    fn foo(&self);
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockA::<u32>::new();
++    mock.expect_foo()
++        .returning(|| ());
++    mock.foo();
++}
+diff --git a/tests/automock_generic_trait_with_where_clause.rs b/tests/automock_generic_trait_with_where_clause.rs
+new file mode 100644
+index 0000000..e12be15
+--- /dev/null
++++ b/tests/automock_generic_trait_with_where_clause.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! A trait with generic parameters bounded by a where clause
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo<T> where T: Clone + Copy {
++    fn foo(&self);
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::<u8>::default();
++    mock.expect_foo()
++        .returning(|| ());
++    mock.foo();
++}
+diff --git a/tests/automock_impl_future.rs b/tests/automock_impl_future.rs
+new file mode 100644
+index 0000000..26086af
+--- /dev/null
++++ b/tests/automock_impl_future.rs
+@@ -0,0 +1,50 @@
++// vim: tw=80
++//! A trait with a constructor method that returns impl Future<...>.
++//!
++//! This needs special handling, because Box<dyn Future<...>> is pretty useless.
++//! You need Pin<Box<dyn Future<...>>> instead.
++#![deny(warnings)]
++
++use futures::{Future, FutureExt, Stream, StreamExt, future, stream};
++use mockall::*;
++
++pub struct Foo{}
++
++#[automock]
++impl Foo {
++    pub fn foo(&self) -> impl Future<Output=u32>
++    {
++        future::ready(42)
++    }
++
++    pub fn bar(&self) -> impl Stream<Item=u32>
++    {
++        stream::empty()
++    }
++}
++
++#[test]
++fn returning_future() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|| {
++            Box::pin(future::ready(42))
++        });
++    mock.foo()
++        .now_or_never()
++        .unwrap();
++}
++
++#[test]
++fn returning_stream() {
++    let mut mock = MockFoo::new();
++    mock.expect_bar()
++        .returning(|| {
++            Box::pin(stream::iter(vec![42]))
++        });
++    let all = mock.bar()
++        .collect::<Vec<u32>>()
++        .now_or_never()
++        .unwrap();
++    assert_eq!(&all[..], &[42][..]);
++}
+diff --git a/tests/automock_impl_generic_trait_for.rs b/tests/automock_impl_generic_trait_for.rs
+new file mode 100644
+index 0000000..6bd218a
+--- /dev/null
++++ b/tests/automock_impl_generic_trait_for.rs
+@@ -0,0 +1,28 @@
++// vim: tw=80
++//! A generic struct that implements a generic trait
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo<T> {
++    fn foo(&self, t: T) -> T;
++}
++
++pub struct SomeStruct<T> {
++    _t: std::marker::PhantomData<T>
++}
++
++#[automock]
++impl<T> Foo<T> for SomeStruct<T> {
++    fn foo(&self, t: T) -> T {
++        t
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockSomeStruct::<u32>::new();
++    mock.expect_foo()
++        .returning(|t| t);
++    assert_eq!(4, <MockSomeStruct<u32> as Foo<u32>>::foo(&mock, 4));
++}
+diff --git a/tests/automock_impl_trait.rs b/tests/automock_impl_trait.rs
+new file mode 100644
+index 0000000..eb14a13
+--- /dev/null
++++ b/tests/automock_impl_trait.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++//! A method that returns "impl Trait"
++#![deny(warnings)]
++
++use mockall::*;
++use std::fmt::Debug;
++
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++    pub fn foo(&self) -> impl Debug + Send { unimplemented!()}
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo().returning(|| Box::new(4));
++    format!("{:?}", mock.foo());
++}
+diff --git a/tests/automock_impl_trait_for.rs b/tests/automock_impl_trait_for.rs
+new file mode 100644
+index 0000000..6dc153a
+--- /dev/null
++++ b/tests/automock_impl_trait_for.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++//! A struct that implements a trait
++#![deny(warnings)]
++
++use mockall::*;
++
++pub trait Foo {
++    fn foo(&self, x: u32) -> i64;
++}
++
++pub struct SomeStruct {}
++
++#[automock]
++impl Foo for SomeStruct {
++    fn foo(&self, _x: u32) -> i64 {
++        42
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockSomeStruct::new();
++    mock.expect_foo()
++        .returning(|x| i64::from(x) + 1);
++    assert_eq!(5, <MockSomeStruct as Foo>::foo(&mock, 4));
++}
+diff --git a/tests/automock_impl_trait_for_generic.rs b/tests/automock_impl_trait_for_generic.rs
+new file mode 100644
+index 0000000..7d50ef4
+--- /dev/null
++++ b/tests/automock_impl_trait_for_generic.rs
+@@ -0,0 +1,28 @@
++// vim: tw=80
++//! A generic struct that implements a trait
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++    fn foo(&self, x: u32) -> i64;
++}
++
++pub struct SomeStruct<T> {
++    _t: std::marker::PhantomData<T>
++}
++
++#[automock]
++impl<T> Foo for SomeStruct<T> {
++    fn foo(&self, _x: u32) -> i64 {
++        42
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockSomeStruct::<u32>::new();
++    mock.expect_foo()
++        .returning(|x| i64::from(x) + 1);
++    assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_impl_trait_with_associated_types_for.rs b/tests/automock_impl_trait_with_associated_types_for.rs
+new file mode 100644
+index 0000000..17bcca7
+--- /dev/null
++++ b/tests/automock_impl_trait_with_associated_types_for.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A struct implements a trait with associated types
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo {}
++#[automock]
++impl Iterator for Foo {
++    type Item = u32;
++
++    fn next(&mut self) -> Option<Self::Item> {
++        unimplemented!()
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_next().returning(|| None);
++    assert!(mock.next().is_none());
++}
+diff --git a/tests/automock_inline.rs b/tests/automock_inline.rs
+new file mode 100644
+index 0000000..6ba2991
+--- /dev/null
++++ b/tests/automock_inline.rs
+@@ -0,0 +1,52 @@
++// vim: tw=80
++//! Mockall should ignore and not emit attributes like "inline" that affect
++//! code generation.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++    #[inline]
++    pub fn foo(&self) -> i32 {unimplemented!()}
++    #[inline]
++    pub fn bar() -> i32 {unimplemented!()}
++    #[cold]
++    pub fn baz(&self) -> i32 {unimplemented!()}
++    #[cold]
++    pub fn bean() -> i32 {unimplemented!()}
++}
++
++#[test]
++fn inline_method() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(42i32);
++    assert_eq!(mock.foo(), 42);
++}
++
++#[test]
++fn inline_static_method() {
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .return_const(42i32);
++    assert_eq!(MockFoo::bar(), 42);
++}
++
++#[test]
++fn cold_method() {
++    let mut mock = MockFoo::new();
++    mock.expect_baz()
++        .return_const(42i32);
++    assert_eq!(mock.baz(), 42);
++}
++
++#[test]
++fn cold_static_method() {
++    let ctx = MockFoo::bean_context();
++    ctx.expect()
++        .return_const(42i32);
++    assert_eq!(MockFoo::bean(), 42);
++}
+diff --git a/tests/automock_instrument.rs b/tests/automock_instrument.rs
+new file mode 100644
+index 0000000..4f210ff
+--- /dev/null
++++ b/tests/automock_instrument.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A trait that uses tracing::instrument should be automockable.  The mock
++//! method won't be instrumented, though.
++#![deny(warnings)]
++
++use mockall::*;
++use tracing::instrument;
++
++#[derive(Debug)]
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++    #[instrument]
++    fn foo(&self) {}
++    #[instrument]
++    fn bar() {}
++    #[tracing::instrument]
++    fn fooz(&self) {}
++    #[tracing::instrument]
++    fn barz() {}
++}
+diff --git a/tests/automock_many_args.rs b/tests/automock_many_args.rs
+new file mode 100644
+index 0000000..8393130
+--- /dev/null
++++ b/tests/automock_many_args.rs
+@@ -0,0 +1,81 @@
++// vim: tw=80
++//! mockall should be able to mock methods with at least 16 arguments
++#![allow(clippy::too_many_arguments)]    // Good job, Clippy!
++#![allow(clippy::type_complexity)]
++#![deny(warnings)]
++
++use mockall::{automock, predicate::*};
++
++#[automock]
++trait ManyArgs {
++    fn foo(&self, _a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
++           _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
++           _a12: u8, _a13: u8, _a14: u8, _a15: u8);
++    fn bar(&self, _a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
++           _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
++           _a12: u8, _a13: u8, _a14: u8, _a15: u8) -> &u32;
++    fn baz(&mut self, _a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
++           _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
++           _a12: u8, _a13: u8, _a14: u8, _a15: u8) -> &mut u32;
++    fn bean(_a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
++           _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
++           _a12: u8, _a13: u8, _a14: u8, _a15: u8);
++}
++
++#[test]
++#[should_panic(
++    expected = "MockManyArgs::foo: Expectation(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true) called 0 time(s) which is fewer than expected 1"
++)]
++fn not_yet_satisfied() {
++    let mut mock = MockManyArgs::new();
++    mock.expect_foo()
++        .with(always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), )
++        .times(1)
++        .returning(|_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _|  ());
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockManyArgs::new();
++    mock.expect_foo()
++        .returning(|_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _|  ());
++    mock.foo(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockManyArgs::new();
++    mock.expect_bar()
++        .return_const(42);
++    mock.bar(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
++
++#[test]
++fn return_var() {
++    let mut mock = MockManyArgs::new();
++    mock.expect_baz()
++        .return_var(42);
++    mock.baz(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
++
++#[test]
++fn static_method_returning() {
++    let ctx = MockManyArgs::bean_context();
++    ctx.expect()
++        .returning(|_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _|  ());
++    MockManyArgs::bean(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
++
++#[test]
++#[should_panic(
++    expected = "MockManyArgs::foo: Expectation(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true) called 2 times which is more than the expected 1"
++)]
++fn too_many() {
++    let mut mock = MockManyArgs::new();
++    mock.expect_foo()
++        .with(always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), always(), )
++        .times(1)
++        .returning(|_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _|  ());
++    mock.foo(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++    mock.foo(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
++}
+diff --git a/tests/automock_module.rs b/tests/automock_module.rs
+new file mode 100644
+index 0000000..ddfe53e
+--- /dev/null
++++ b/tests/automock_module.rs
+@@ -0,0 +1,50 @@
++// vim: tw=80
++//! Mocking an entire module of functions
++#![deny(warnings)]
++
++
++pub mod m {
++    use std::sync::Mutex;
++    use mockall::*;
++    type T = u32;
++
++    static BAR_MTX: Mutex<()> = Mutex::new(());
++
++    #[automock]
++    pub mod foo {
++        use super::T;
++        pub fn bar(_x: T) -> i64 {unimplemented!()}
++        // Module functions should be able to use impl Trait, too
++        pub fn baz() -> impl std::fmt::Debug + Send { unimplemented!()}
++        // Module functions can use mutable arguments
++        pub fn bean(mut _x: u32) { unimplemented!() }
++    }
++
++    #[test]
++    #[should_panic(expected = "mock_foo::bar(5): No matching expectation found")]
++    fn with_no_matches() {
++        let _m = BAR_MTX.lock();
++        let ctx = mock_foo::bar_context();
++        ctx.expect()
++            .with(predicate::eq(4))
++            .return_const(0);
++        mock_foo::bar(5);
++    }
++
++    #[test]
++    fn returning() {
++        let _m = BAR_MTX.lock();
++        let ctx = mock_foo::bar_context();
++        ctx.expect()
++            .returning(|x| i64::from(x) + 1);
++        assert_eq!(5, mock_foo::bar(4));
++    }
++
++    #[test]
++    fn impl_trait() {
++        let ctx = mock_foo::baz_context();
++        ctx.expect()
++            .returning(|| Box::new(4));
++        format!("{:?}", mock_foo::baz());
++    }
++}
+diff --git a/tests/automock_module_nonpub.rs b/tests/automock_module_nonpub.rs
+new file mode 100644
+index 0000000..d131197
+--- /dev/null
++++ b/tests/automock_module_nonpub.rs
+@@ -0,0 +1,45 @@
++// vim: tw=80
++//! bare functions can use non-public types, as long as the object's visibility is compatible.
++#![deny(warnings)]
++#![allow(dead_code)]
++
++mod outer {
++    struct SuperT();
++
++    mod inner {
++        use mockall::automock;
++
++        pub(crate) struct PubCrateT();
++        struct PrivT();
++
++        #[automock]
++        mod m {
++            use super::*;
++
++            pub(crate) fn foo(_x: PubCrateT) -> PubCrateT {
++                unimplemented!()
++            }
++            pub(super) fn bar(_x: PrivT) -> PrivT {
++                unimplemented!()
++            }
++            pub(in super::super) fn baz(_x: super::super::SuperT)
++                -> super::super::SuperT
++            {
++                unimplemented!()
++            }
++            pub(in crate::outer) fn bang(_x: crate::outer::SuperT)
++                -> crate::outer::SuperT
++            {
++                unimplemented!()
++            }
++        }
++
++        #[test]
++        fn returning() {
++            let ctx = mock_m::foo_context();
++            ctx.expect()
++                .returning(|x| x);
++            mock_m::foo(PubCrateT());
++        }
++    }
++}
+diff --git a/tests/automock_module_unused_import.rs b/tests/automock_module_unused_import.rs
+new file mode 100644
+index 0000000..7f09b43
+--- /dev/null
++++ b/tests/automock_module_unused_import.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++//! Mocking modules should not generated "unused_imports" warnings for imports
++//! used by the bodies of the mocked functions.
++//! https://github.com/asomers/mockall/issues/343
++#![deny(warnings)]
++
++use mockall::automock;
++
++#[automock]
++pub mod foo {
++    use std::convert::TryInto;
++
++    pub fn bar() {
++        let x = 42i32;
++        let _y: u32 = x.try_into().unwrap_or(0);
++    }
++}
++
++#[test]
++fn return_const() {
++    let ctx = mock_foo::bar_context();
++    ctx.expect()
++        .once()
++        .return_const(());
++    mock_foo::bar();
++}
+diff --git a/tests/automock_multiple_lifetime_parameters.rs b/tests/automock_multiple_lifetime_parameters.rs
+new file mode 100644
+index 0000000..8bdae38
+--- /dev/null
++++ b/tests/automock_multiple_lifetime_parameters.rs
+@@ -0,0 +1,15 @@
++// vim: tw=80
++//! Methods with multiple generic lifetime parameters should produce their
++//! generated code deterministically.
++//!
++//! This test is designed to work with "--cfg reprocheck"
++
++#![deny(warnings)]
++#![allow(clippy::needless_lifetimes)]
++
++use mockall::*;
++
++#[automock]
++pub trait Foo {
++    fn foo<'a, 'b, 'c, 'd, 'e, 'f>(&self, x: &'a &'b &'c &'d &'e &'f i32);
++}
+diff --git a/tests/automock_must_use.rs b/tests/automock_must_use.rs
+new file mode 100644
+index 0000000..d661fd4
+--- /dev/null
++++ b/tests/automock_must_use.rs
+@@ -0,0 +1,60 @@
++// vim: tw=80
++//! Mockall should be able to mock #[must_use] methods.  The generated code
++//! should contain #[must_use] on the mock method, but not the expect method.
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++    #[must_use]
++    pub fn bloob(&self) -> i32 {unimplemented!()}
++    #[must_use]
++    pub fn blarg() -> i32 {unimplemented!()}
++}
++
++// test that basic code generation works with must_use structs and traits.  The
++// exact output will be verified by the unit tests.
++#[must_use]
++pub struct MustUseStruct {}
++#[automock]
++impl MustUseStruct {}
++#[automock]
++#[must_use]
++pub trait MustUseTrait {}
++
++#[test]
++fn must_use_method() {
++    let mut mock = MockFoo::new();
++    mock.expect_bloob()
++        .return_const(42i32);
++    assert_eq!(42, mock.bloob());
++}
++
++#[cfg(feature = "nightly")]
++#[test]
++fn may_not_use_expectation() {
++    let mut mock = MockFoo::new();
++    // This should not produce a "must_use" warning.
++    mock.expect_bloob();
++}
++
++#[test]
++fn must_use_static_method() {
++    let ctx = MockFoo::blarg_context();
++    ctx.expect()
++        .return_const(42i32);
++    assert_eq!(MockFoo::blarg(), 42);
++}
++
++#[cfg(feature = "nightly")]
++#[test]
++fn may_not_use_static_expectation() {
++    let ctx = MockFoo::blarg_context();
++    // This should not produce a "must_use" warning.
++    ctx.expect();
++}
++
++
+diff --git a/tests/automock_mutable_args.rs b/tests/automock_mutable_args.rs
+new file mode 100644
+index 0000000..6bdb5f4
+--- /dev/null
++++ b/tests/automock_mutable_args.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! A method with mutable arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct Foo {}
++
++#[automock]
++impl Foo {
++    pub fn foo(&self, mut _x: u32) {}
++    pub fn bar(&mut self, _x: i32) -> i32 {0}
++}
++
++#[test]
++fn mutable_self() {
++    let mut mock = MockFoo::new();
++    let mut count = 0;
++    mock.expect_bar()
++        .returning(move |x| {
++            count += x;
++            count
++        });
++    assert_eq!(5, mock.bar(5));
++    assert_eq!(10, mock.bar(5));
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|_| ());
++    mock.foo(42);
++}
+diff --git a/tests/automock_nondebug.rs b/tests/automock_nondebug.rs
+new file mode 100644
+index 0000000..d6e2690
+--- /dev/null
++++ b/tests/automock_nondebug.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A method may have non-Debug arguments and/or return values.
++#![deny(warnings)]
++
++use mockall::*;
++
++// Don't derive Debug
++pub struct NonDebug{}
++
++#[automock]
++pub trait Foo {
++    fn foo(&self, x: NonDebug);
++}
++
++#[test]
++#[should_panic(expected = "MockFoo::foo(?): No matching expectation found")]
++fn with_no_matches() {
++    let mock = MockFoo::new();
++    mock.foo(NonDebug{});
++}
++
++
+diff --git a/tests/automock_nonpub_methods.rs b/tests/automock_nonpub_methods.rs
+new file mode 100644
+index 0000000..c534858
+--- /dev/null
++++ b/tests/automock_nonpub_methods.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! Using automock on a struct with private methods should not result in any
++//! "dead_code" warnings.  Such methods are often private helpers used only by
++//! other public methods.
++#[deny(dead_code)]
++
++pub mod mymod {
++    use mockall::automock;
++
++    pub struct Foo{}
++
++    #[automock]
++    impl Foo {
++        fn private_helper(&self) {}
++        fn static_private_helper() {}
++
++        pub fn pubfunc(&self) {
++            Self::static_private_helper();
++            self.private_helper()
++        }
++    }
++}
+diff --git a/tests/automock_nonsend.rs b/tests/automock_nonsend.rs
+new file mode 100644
+index 0000000..059879f
+--- /dev/null
++++ b/tests/automock_nonsend.rs
+@@ -0,0 +1,146 @@
++// vim: tw=80
++//! A method may have non-Send arguments and/or return values.
++#![deny(warnings)]
++
++use mockall::*;
++// Rc is not Send
++use std::rc::Rc;
++
++// Neither Send nor Clone
++pub struct NonSend(Rc<u32>);
++
++mod normal_method {
++    use super::*;
++
++    #[automock]
++    trait Foo {
++        fn foo(&self, x: Rc<u32>);
++        fn bar(&self) -> Rc<u32>;
++        fn baz(&self) -> NonSend;
++    }
++
++    #[test]
++    fn return_once_st() {
++        let mut mock = MockFoo::new();
++        let r = NonSend(Rc::new(42u32));
++        mock.expect_baz()
++            .return_once_st(move || r);
++        assert_eq!(42, *mock.baz().0);
++    }
++
++    #[test]
++    fn return_const_st() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .return_const_st(Rc::new(43u32));
++        assert_eq!(43, *mock.bar());
++    }
++
++    #[test]
++    fn returning_st() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .returning_st(|| Rc::new(43u32));
++        assert_eq!(43, *mock.bar());
++    }
++
++    #[test]
++    fn withf_st() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .withf_st(|x| **x == 42)
++            .return_const(());
++        mock.foo(Rc::new(42));
++    }
++}
++
++mod ref_method {
++    // ref methods don't have return_once_st because they don't return owned
++    // values, and they don't have returning_st because they don't have
++    // returning.  Instead, they only have return_const, which does not require
++    // Send.
++    // fn foo(&self) -> &Rc<u32>;
++}
++
++mod refmut_method {
++    use super::*;
++
++    #[automock]
++    trait Foo {
++        fn foo(&mut self, x: Rc<u32>);
++        fn bar(&mut self) -> &mut Rc<u32>;
++    }
++
++    // refmut methods don't have return_once_st because they don't return owned
++    // values.
++    #[test]
++    fn returning_st() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .returning_st(|| Rc::new(43u32));
++        assert_eq!(43, **mock.bar());
++    }
++
++    #[test]
++    fn withf_st() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .withf_st(|x| **x == 42)
++            .return_const(());
++        mock.foo(Rc::new(42));
++    }
++}
++
++pub mod static_method {
++    use super::*;
++    use std::sync::Mutex;
++
++    static FOO_MTX: Mutex<()> = Mutex::new(());
++    static BAR_MTX: Mutex<()> = Mutex::new(());
++    static BAZ_MTX: Mutex<()> = Mutex::new(());
++
++    #[automock]
++    trait Foo {
++        fn foo(x: Rc<u32>);
++        fn bar() -> Rc<u32>;
++        fn baz() -> NonSend;
++    }
++
++    #[test]
++    fn return_once_st() {
++        let _guard = BAZ_MTX.lock().unwrap();
++        let ctx = MockFoo::baz_context();
++        let r = NonSend(Rc::new(42u32));
++        ctx.expect()
++            .return_once_st(move || r);
++        assert_eq!(42, *MockFoo::baz().0);
++    }
++
++    #[test]
++    fn returning_st() {
++        let _guard = BAR_MTX.lock().unwrap();
++        let ctx = MockFoo::bar_context();
++        ctx.expect()
++            .returning_st(|| Rc::new(42));
++        assert_eq!(42, *MockFoo::bar());
++    }
++
++    #[test]
++    fn return_const_st() {
++        let _guard = BAR_MTX.lock().unwrap();
++        let ctx = MockFoo::bar_context();
++        ctx.expect()
++            .return_const_st(Rc::new(42));
++        assert_eq!(42, *MockFoo::bar());
++    }
++
++    #[test]
++    fn withf_st() {
++        let _guard = FOO_MTX.lock().unwrap();
++        let ctx = MockFoo::foo_context();
++        ctx.expect()
++            .withf_st(|x| **x == 42)
++            .return_const(());
++        MockFoo::foo(Rc::new(42));
++    }
++}
+diff --git a/tests/automock_nonstatic_struct.rs b/tests/automock_nonstatic_struct.rs
+new file mode 100644
+index 0000000..ecb3399
+--- /dev/null
++++ b/tests/automock_nonstatic_struct.rs
+@@ -0,0 +1,53 @@
++// vim: tw=80
++//! Mock a struct with a lifetime parameter
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct NonStaticStruct<'nss> {
++    _x: &'nss i32
++}
++
++#[automock]
++impl<'nss> NonStaticStruct<'nss> {
++    pub fn foo(&self) -> i64 {
++        42
++    }
++    pub fn bar() -> i64{
++        42
++    }
++    // XXX Constructors aren't yet supported for non-static Structs
++    //pub fn new(x: &'nss i32) -> Self {
++        //NonStaticStruct{x}
++    //}
++}
++
++#[test]
++fn normal_method() {
++    // This function serves to define a named lifetime
++    #[allow(clippy::trivially_copy_pass_by_ref)]
++    fn has_lt<'a>(_x: &'a i8) {
++        let mut mock = MockNonStaticStruct::<'a>::default();
++        mock.expect_foo()
++            .returning(|| 5);
++        assert_eq!(5, mock.foo());
++    }
++
++    let x = 42i8;
++    has_lt(&x);
++}
++
++#[test]
++fn static_method() {
++    // This function serves to define a named lifetime
++    #[allow(clippy::trivially_copy_pass_by_ref)]
++    fn has_lt<'a>(_x: &'a i8) {
++        let ctx = MockNonStaticStruct::<'a>::bar_context();
++        ctx.expect()
++            .returning(|| 5);
++        assert_eq!(5, MockNonStaticStruct::bar());
++    }
++
++    let x = 42i8;
++    has_lt(&x);
++}
+diff --git a/tests/automock_partial_eq.rs b/tests/automock_partial_eq.rs
+new file mode 100644
+index 0000000..2618b4e
+--- /dev/null
++++ b/tests/automock_partial_eq.rs
+@@ -0,0 +1,39 @@
++// vim: tw=80
++//! Mockall should deselfify `Self` types, even if they aren't named `self`.
++use mockall::*;
++
++mock! {
++    #[derive(Debug)]
++    pub Foo {
++        fn compare(&self, other: &Self) -> bool;
++    }
++    impl PartialEq for Foo {
++        fn eq(&self, other: &Self) -> bool;
++    }
++}
++
++#[test]
++fn inherent_method() {
++    let mut x = MockFoo::default();
++    let mut y = MockFoo::default();
++    x.expect_compare()
++        .return_const(true);
++    y.expect_compare()
++        .return_const(false);
++
++    assert!(x.compare(&y));
++    assert!(!y.compare(&x));
++}
++
++#[test]
++fn trait_method() {
++    let mut x = MockFoo::default();
++    let mut y = MockFoo::default();
++    x.expect_eq()
++        .return_const(true);
++    y.expect_eq()
++        .return_const(false);
++
++    assert_eq!(x, y);
++    assert!(y != x);
++}
+diff --git a/tests/automock_qself.rs b/tests/automock_qself.rs
+new file mode 100644
+index 0000000..2b10034
+--- /dev/null
++++ b/tests/automock_qself.rs
+@@ -0,0 +1,54 @@
++// vim: tw=80
++//! Using QSelf in an argument, a where clause, or a return type
++#![deny(warnings)]
++
++use mockall::*;
++
++pub trait Foo {
++    type Output;
++}
++
++pub struct SendFoo {}
++impl Foo for SendFoo {
++    type Output = u32;
++}
++
++pub struct A{}
++#[automock]
++impl A {
++    pub fn foo<T: Foo + 'static>(&self, _q: <T as Foo>::Output) {
++    }
++    pub fn bar<T: Foo + 'static>(&self, _t: T) -> <T as Foo>::Output {
++        unimplemented!()
++    }
++    pub fn bean<T>(&self, _t: T)
++        where T: Foo + 'static,
++              <T as Foo>::Output: Send
++    {
++    }
++}
++
++#[test]
++fn arguments() {
++    let mut mock = MockA::new();
++    mock.expect_foo::<SendFoo>()
++        .with(predicate::eq(42u32))
++        .return_const(());
++    mock.foo::<SendFoo>(42u32);
++}
++
++#[test]
++fn where_clause() {
++    let mut mock = MockA::new();
++    mock.expect_bean::<SendFoo>()
++        .return_const(());
++    mock.bean(SendFoo{});
++}
++
++#[test]
++fn return_value() {
++    let mut mock = MockA::new();
++    mock.expect_bar::<SendFoo>()
++        .return_const(42u32);
++    assert_eq!(42, mock.bar(SendFoo{}));
++}
+diff --git a/tests/automock_refmut_arguments.rs b/tests/automock_refmut_arguments.rs
+new file mode 100644
+index 0000000..d65a00e
+--- /dev/null
++++ b/tests/automock_refmut_arguments.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++//! A method that takes mutable reference arguments, returning information
++//! through its arguments like C functions often do.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait T {
++    fn foo(&self, x: &mut u32);
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockT::new();
++    let mut x = 5;
++    mock.expect_foo()
++        .returning(|x: &mut u32| {
++            *x = 42;
++        });
++    mock.foo(&mut x);
++    assert_eq!(42, x);
++}
+diff --git a/tests/automock_return_mutable_ref.rs b/tests/automock_return_mutable_ref.rs
+new file mode 100644
+index 0000000..705a3eb
+--- /dev/null
++++ b/tests/automock_return_mutable_ref.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A method that returns a mutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++    fn foo(&mut self) -> &mut u32;
++}
++
++#[test]
++fn return_var() {
++    let mut mock = MockA::new();
++    mock.expect_foo().return_var(5);
++    {
++        let r = mock.foo();
++        assert_eq!(5, *r);
++        *r = 6;
++    }
++    assert_eq!(6, *mock.foo());
++}
+diff --git a/tests/automock_return_owned.rs b/tests/automock_return_owned.rs
+new file mode 100644
+index 0000000..826d711
+--- /dev/null
++++ b/tests/automock_return_owned.rs
+@@ -0,0 +1,32 @@
++// vim: tw=80
++//! A method that returns ownership of a value, rather than returning by Copy
++#![deny(warnings)]
++
++use mockall::*;
++
++struct NonCopy {}
++
++#[automock]
++trait T {
++    fn foo(&self) -> NonCopy;
++}
++
++#[test]
++fn return_once() {
++    let mut mock = MockT::new();
++    let r = NonCopy{};
++    mock.expect_foo()
++        .return_once(|| r);
++    mock.foo();
++}
++
++#[test]
++#[should_panic(expected = "MockT::foo: Expectation(<anything>) called twice, but it returns by move")]
++fn return_once_too_many_times() {
++    let mut mock = MockT::new();
++    let r = NonCopy{};
++    mock.expect_foo()
++        .return_once(|| r);
++    mock.foo();
++    mock.foo();
++}
+diff --git a/tests/automock_return_reference.rs b/tests/automock_return_reference.rs
+new file mode 100644
+index 0000000..f312217
+--- /dev/null
++++ b/tests/automock_return_reference.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! A method that returns an immutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++    fn foo(&self) -> &u32;
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockA::new();
++    mock.expect_foo().return_const(5);
++    assert_eq!(5, *mock.foo());
++}
+diff --git a/tests/automock_return_static_ref.rs b/tests/automock_return_static_ref.rs
+new file mode 100644
+index 0000000..1f8c533
+--- /dev/null
++++ b/tests/automock_return_static_ref.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! A method that returns an immutable 'static reference
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++    fn foo(&self) -> &'static u32;
++}
++
++#[test]
++fn return_const() {
++    const X: u32 = 5;
++    let mut mock = MockA::new();
++    mock.expect_foo().return_const(&X);
++    assert_eq!(5, *mock.foo());
++}
+diff --git a/tests/automock_rpitit.rs b/tests/automock_rpitit.rs
+new file mode 100644
+index 0000000..4bf2974
+--- /dev/null
++++ b/tests/automock_rpitit.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! Return position Impl Trait in Traits
++//! https://rust-lang.github.io/rfcs/3425-return-position-impl-trait-in-traits.html
++#![cfg(feature = "nightly")]
++#![deny(warnings)]
++
++use std::fmt::Debug;
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++    fn bar(&self) -> impl Debug;
++}
++
++#[test]
++fn returning() {
++    let mut foo = MockFoo::default();
++    foo.expect_bar()
++        .returning(|| Box::new(42u32));
++    assert_eq!("42", format!("{:?}", foo.bar()));
++}
+diff --git a/tests/automock_self_by_value.rs b/tests/automock_self_by_value.rs
+new file mode 100644
+index 0000000..45af055
+--- /dev/null
++++ b/tests/automock_self_by_value.rs
+@@ -0,0 +1,30 @@
++// vim: tw=80
++//! A method that consumes self
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct MethodByValue {}
++
++#[automock]
++impl MethodByValue {
++    pub fn foo(self, _x: u32) -> i64 {0}
++    #[allow(unused_mut)]
++    pub fn bar(mut self) {}
++}
++
++#[test]
++fn immutable() {
++    let mut mock = MockMethodByValue::new();
++    mock.expect_foo()
++        .returning(|x| i64::from(x) + 1);
++    assert_eq!(5, mock.foo(4));
++}
++
++#[test]
++fn mutable() {
++    let mut mock = MockMethodByValue::new();
++    mock.expect_bar()
++        .returning(|| ());
++    mock.bar();
++}
+diff --git a/tests/automock_send.rs b/tests/automock_send.rs
+new file mode 100644
+index 0000000..1f7d468
+--- /dev/null
++++ b/tests/automock_send.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++//! A mock object should be Send
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub trait T {
++    fn foo(&self) -> u32;
++}
++
++#[test]
++#[allow(clippy::unnecessary_operation)] // The cast is the whole point
++fn cast_to_send() {
++    let mock = MockT::new();
++    let _m = Box::new(mock) as Box<dyn T + Send>;
++}
+diff --git a/tests/automock_seven_args.rs b/tests/automock_seven_args.rs
+new file mode 100644
+index 0000000..6760f02
+--- /dev/null
++++ b/tests/automock_seven_args.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! When mocking static functions just at the threshold of Clippy's type
++//! complexity limit, no warnings should be emitted regarding the generated
++//! code.
++#![deny(warnings)]
++
++use mockall::automock;
++
++#[automock]
++trait ManyArgs {
++    fn foo(_a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8, _a6: u8);
++}
++
++#[test]
++fn static_method_returning() {
++    let ctx = MockManyArgs::foo_context();
++    ctx.expect()
++        .returning(|_, _, _, _, _, _, _|  ());
++    MockManyArgs::foo(0, 0, 0, 0, 0, 0, 0);
++}
++
++
+diff --git a/tests/automock_slice_arguments.rs b/tests/automock_slice_arguments.rs
+new file mode 100644
+index 0000000..37044ac
+--- /dev/null
++++ b/tests/automock_slice_arguments.rs
+@@ -0,0 +1,35 @@
++// vim: tw=80
++//! a method with slice arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++    fn foo(&self, x: &[u8]);
++}
++
++mod withf {
++    use super::*;
++
++    #[test]
++    #[should_panic(expected = "MockFoo::foo([1, 2, 3, 4]): No matching expectation found")]
++    fn fail() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .withf(|sl| sl == [1, 2, 3])
++            .returning(|_| ());
++        let x = vec![1, 2, 3, 4];
++        mock.foo(&x);
++    }
++
++    #[test]
++    fn ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .withf(|sl| sl == [1, 2, 3])
++            .returning(|_| ());
++        let x = vec![1, 2, 3];
++        mock.foo(&x);
++    }
++}
+diff --git a/tests/automock_specializing_method_of_nongeneric_struct.rs b/tests/automock_specializing_method_of_nongeneric_struct.rs
+new file mode 100644
+index 0000000..8f82f57
+--- /dev/null
++++ b/tests/automock_specializing_method_of_nongeneric_struct.rs
+@@ -0,0 +1,29 @@
++// vim: tw=80
++//! Non-generic structs can have specializing methods, too.  For example, some
++//! methods place constraints on Self.  It's even possible for a where clause to
++//! place a constraint on types that appear nowhere in the struct's signatures.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Bar {
++    fn bar(&self) where Self: Sized;
++    fn baz() where Self: Sized;
++}
++
++#[test]
++fn nonstatic() {
++    let mut mock = MockBar::default();
++    mock.expect_bar()
++        .return_const(());
++    mock.bar();
++}
++
++#[test]
++fn static_method() {
++    let ctx = MockBar::baz_context();
++    ctx.expect()
++        .return_const(());
++    MockBar::baz();
++}
+diff --git a/tests/automock_specializing_methods.rs b/tests/automock_specializing_methods.rs
+new file mode 100644
+index 0000000..e4f3af4
+--- /dev/null
++++ b/tests/automock_specializing_methods.rs
+@@ -0,0 +1,33 @@
++// vim: tw=80
++//! A specializing method is a non-generic method of a generic struct that
++//! places additional bounds on the struct's generic types via a where
++//! clause.
++#![deny(warnings)]
++
++use mockall::*;
++
++struct G<T: Copy + Default>(T);
++
++#[derive(Clone, Copy)]
++struct NonDefault{}
++
++#[automock]
++trait Foo<T> where T: Copy {
++    fn foo(&self, t: T) -> G<T> where T: Default + 'static;
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::<u32>::default();
++    mock.expect_foo()
++        .returning(G);
++    assert_eq!(42u32, mock.foo(42u32).0);
++
++    // It's possible to instantiate a mock object that doesn't satisfy the
++    // specializing method's requirements:
++    let _mock2 = MockFoo::<NonDefault>::default();
++    // But you can't call the specializing method.  This won't work:
++    // _mock2.expect_foo()
++    //    .returning(|h| G(h));
++    // _mock2.foo(NonDefault{});
++}
+diff --git a/tests/automock_static_method.rs b/tests/automock_static_method.rs
+new file mode 100644
+index 0000000..bcdff4d
+--- /dev/null
++++ b/tests/automock_static_method.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! automocking a trait with a static method
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait A {
++    fn bar() -> u32;
++}
++
++#[test]
++fn returning() {
++    let ctx = MockA::bar_context();
++    ctx.expect()
++        .returning(|| 42);
++    assert_eq!(42, MockA::bar());
++}
+diff --git a/tests/automock_struct.rs b/tests/automock_struct.rs
+new file mode 100644
+index 0000000..d344167
+--- /dev/null
++++ b/tests/automock_struct.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! automocking a struct
++#![deny(warnings)]
++
++use mockall::*;
++
++pub struct SimpleStruct {}
++
++#[automock]
++impl SimpleStruct {
++    pub fn foo(&self, _x: u32) -> i64 {
++        42
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockSimpleStruct::new();
++    mock.expect_foo()
++        .returning(|x| i64::from(x) + 1);
++    assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_trait.rs b/tests/automock_trait.rs
+new file mode 100644
+index 0000000..81261d6
+--- /dev/null
++++ b/tests/automock_trait.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++//! automocking a trait
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait SimpleTrait {
++    fn foo(&self, x: u32) -> u32;
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockSimpleTrait::new();
++    mock.expect_foo()
++        .returning(|x| x + 1);
++    assert_eq!(5, mock.foo(4));
++}
+diff --git a/tests/automock_trait_object.rs b/tests/automock_trait_object.rs
+new file mode 100644
+index 0000000..78f93a0
+--- /dev/null
++++ b/tests/automock_trait_object.rs
+@@ -0,0 +1,42 @@
++// vim: tw=80
++//! a method that uses unboxed trait object arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++trait Foo {
++    fn foo(&self, x: &dyn PartialEq<u32>);
++}
++
++// It's almost impossible to construct a Predicate object that will work with
++// trait objects for two reasons:
++// * Mockall requires the predicates to be Debug, and any useful predicate will
++//   also be Eq, Ord, or similar, but Rust only allows up to one non-auto trait
++//   per trait object.
++// * The predicate is requird to meet the HRTB
++//   for<'a> Predicate<(dyn Trait + 'a)>
++//   That's not impossible, but Mockall doesn't provide any way to construct
++//   such a predicate.
++// So, use of `with` is pretty much limited to predicates like `always` and
++// `function`.
++#[test]
++fn with() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .with(predicate::always())
++        .return_const(());
++    mock.foo(&42u32)
++}
++
++/// trait object arguments can't be matched with `predicate::eq`, because
++/// `PartialEq<Self>` cannot be made into a trait object.  But withf still
++/// works.
++#[test]
++fn withf() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .withf(|x| *x == 42u32)
++        .return_const(());
++    mock.foo(&42u32);
++}
+diff --git a/tests/automock_unsafe_trait.rs b/tests/automock_unsafe_trait.rs
+new file mode 100644
+index 0000000..ff64eb7
+--- /dev/null
++++ b/tests/automock_unsafe_trait.rs
+@@ -0,0 +1,37 @@
++// vim: ts=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++#[allow(clippy::missing_safety_doc)]
++pub unsafe trait Foo {
++    fn foo(&self) -> i32;
++}
++
++pub struct Baz{}
++
++#[automock]
++unsafe impl Foo for Baz {
++    fn foo(&self) -> i32 {
++        unimplemented!()
++    }
++}
++
++#[test]
++fn automock_trait() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(42);
++
++    assert_eq!(42, mock.foo());
++}
++
++#[test]
++fn automock_trait_impl() {
++    let mut mock = MockBaz::new();
++    mock.expect_foo()
++        .return_const(42);
++
++    assert_eq!(42, mock.foo());
++}
+diff --git a/tests/automock_where_self.rs b/tests/automock_where_self.rs
+new file mode 100644
+index 0000000..eedf34f
+--- /dev/null
++++ b/tests/automock_where_self.rs
+@@ -0,0 +1,29 @@
++// vim: ts=80
++//! Methods with a "where Self: ..." where clause should be mocked as concrete,
++//! not generic.
++#![deny(warnings)]
++#![allow(clippy::needless_lifetimes)]
++
++// Enclose the mocked trait within a non-public module.  With some versions of
++// rustc, that causes "unused method" errors for the generic code, but not the
++// concrete code.
++// rustc 1.66.0-nightly (e7119a030 2022-09-22)
++mod mymod {
++
++    #[mockall::automock]
++    pub trait Server {
++        fn version<'a>(&'a self) -> Option<&'static str> where Self: Sized;
++    }
++
++}
++
++use mymod::{MockServer, Server};
++
++#[test]
++fn return_const() {
++    let mut mock = MockServer::new();
++    mock.expect_version()
++        .return_const(None);
++
++    mock.version();
++}
+diff --git a/tests/cfg_attr_concretize.rs b/tests/cfg_attr_concretize.rs
+new file mode 100644
+index 0000000..93af750
+--- /dev/null
++++ b/tests/cfg_attr_concretize.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++//! #[concretize] can be used inside of #[cfg_attr()]`
++#![deny(warnings)]
++
++use std::path::{Path, PathBuf};
++
++use mockall::{automock, concretize};
++
++#[automock]
++trait Foo {
++    #[cfg_attr(not(target_os = "ia64-unknown-multics"), concretize)]
++    fn foo<P: AsRef<Path>>(&self, p: P);
++}
++
++
++#[test]
++fn withf() {
++    let mut foo = MockFoo::new();
++    foo.expect_foo()
++        .withf(|p| p.as_ref() == Path::new("/tmp"))
++        .times(3)
++        .return_const(());
++    foo.foo(Path::new("/tmp"));
++    foo.foo(PathBuf::from(Path::new("/tmp")));
++    foo.foo("/tmp");
++}
+diff --git a/tests/clear_expectations_on_panic.rs b/tests/clear_expectations_on_panic.rs
+new file mode 100644
+index 0000000..a70df15
+--- /dev/null
++++ b/tests/clear_expectations_on_panic.rs
+@@ -0,0 +1,50 @@
++// vim: tw=80
++//! Static methods' expectations should be dropped during panic.
++//!
++//! https://github.com/asomers/mockall/issues/442
++#![deny(warnings)]
++
++use std::panic;
++
++use mockall::*;
++
++#[automock]
++pub trait Foo {
++    fn foo() -> i32;
++    fn bar() -> i32;
++}
++
++#[test]
++fn too_few_calls() {
++    panic::catch_unwind(|| {
++        let ctx = MockFoo::foo_context();
++        ctx.expect()
++            .times(1)
++            .return_const(42);
++    }).unwrap_err();
++
++    // The previously set expectation should've been cleared during the panic,
++    // so we must set a new one.
++    let ctx = MockFoo::foo_context();
++    ctx.expect()
++        .times(1)
++        .return_const(42);
++    assert_eq!(42, MockFoo::foo());
++}
++
++// We shouldn't panic during drop in this case.  Regression test for
++// https://github.com/asomers/mockall/issues/491
++#[cfg_attr(not(feature = "nightly"), ignore)]
++#[test]
++fn too_many_calls() {
++    panic::catch_unwind(|| {
++        let ctx = MockFoo::bar_context();
++        ctx.expect()
++            .times(0);
++        MockFoo::bar();
++    }).unwrap_err();
++
++    // This line will panic with a PoisonError, at least until issue #515 is
++    // complete.
++    let _ctx = MockFoo::bar_context();
++}
+diff --git a/tests/link_name.rs b/tests/link_name.rs
+new file mode 100644
+index 0000000..0987cce
+--- /dev/null
++++ b/tests/link_name.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[automock]
++pub mod ffi {
++    extern "C" {
++        #[link_name = "foo__extern"]
++        pub fn foo() -> u32;
++    }
++}
++
++#[test]
++fn return_const() {
++    let ctx = mock_ffi::foo_context();
++    ctx.expect().return_const(42u32);
++    assert_eq!(42, unsafe{mock_ffi::foo()});
++}
+diff --git a/tests/mock_associated_const.rs b/tests/mock_associated_const.rs
+new file mode 100644
+index 0000000..eae84ff
+--- /dev/null
++++ b/tests/mock_associated_const.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! A trait with an associated constant
++//!
++//! https://github.com/asomers/mockall/issues/97
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++    const X: i32;
++
++    fn x_plus_one(&self) -> i32 {
++        Self::X + 1
++    }
++}
++
++mock! {
++    Foo {
++        const Y: i32 = 69;
++    }
++    impl Foo for Foo {
++        const X: i32 = 42;
++    }
++}
++
++#[test]
++fn default_method() {
++    assert_eq!(MockFoo::new().x_plus_one(), 43);
++}
++
++#[test]
++fn on_the_struct() {
++    assert_eq!(MockFoo::Y, 69);
++}
+diff --git a/tests/mock_associated_types.rs b/tests/mock_associated_types.rs
+new file mode 100644
+index 0000000..8cf7aa9
+--- /dev/null
++++ b/tests/mock_associated_types.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    MyIter {}
++    impl Iterator for MyIter {
++        type Item=u32;
++
++        fn next(&mut self) -> Option<u32>;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockMyIter::new();
++    mock.expect_next()
++        .returning(|| Some(5));
++    assert_eq!(5, mock.next().unwrap());
++}
++
+diff --git a/tests/mock_async_fn.rs b/tests/mock_async_fn.rs
+new file mode 100644
+index 0000000..0988559
+--- /dev/null
++++ b/tests/mock_async_fn.rs
+@@ -0,0 +1,39 @@
++// vim: tw=80
++//! A struct with an async function
++#![deny(warnings)]
++
++use futures::executor::block_on;
++use mockall::*;
++
++mock! {
++    pub Foo {
++        async fn foo(&self) -> u32;
++        async fn bar() -> u32;
++        async fn baz<T: 'static>(&self, t: T) -> T;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(42u32);
++    assert_eq!(block_on(mock.foo()), 42);
++}
++
++#[test]
++fn static_method() {
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .return_const(42u32);
++    assert_eq!(block_on(MockFoo::bar()), 42);
++}
++
++#[test]
++fn generic_method() {
++    let mut mock = MockFoo::new();
++    mock.expect_baz()
++        .with(predicate::eq(69u32))
++        .return_const(42u32);
++    assert_eq!(block_on(mock.baz(69u32)), 42u32);
++}
+diff --git a/tests/mock_async_trait.rs b/tests/mock_async_trait.rs
+new file mode 100644
+index 0000000..7493dd9
+--- /dev/null
++++ b/tests/mock_async_trait.rs
+@@ -0,0 +1,28 @@
++// vim: tw=80
++//! An async trait, for use with Futures
++#![deny(warnings)]
++
++use async_trait::async_trait;
++use futures::executor::block_on;
++use mockall::*;
++
++#[async_trait]
++pub trait Foo {
++    async fn foo(&self) -> u32;
++}
++
++mock! {
++    pub Bar { }
++    #[async_trait]
++    impl Foo for Bar {
++        async fn foo(&self) -> u32;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockBar::new();
++    mock.expect_foo()
++        .return_const(42u32);
++    assert_eq!(block_on(mock.foo()), 42);
++}
+diff --git a/tests/mock_box_self.rs b/tests/mock_box_self.rs
+new file mode 100644
+index 0000000..8d17754
+--- /dev/null
++++ b/tests/mock_box_self.rs
+@@ -0,0 +1,68 @@
++// vim: tw=80
++//! Methods that take receivers like Box<Self> instead of &self
++#![allow(clippy::borrowed_box, clippy::boxed_local)]
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Arc;
++use std::pin::Pin;
++use std::rc::Rc;
++
++mock! {
++    Foo {
++        fn foo(self: &Box<Self>);
++        fn baz(mut self: Box<Self>);
++        fn bar(self: Box<Self>);
++        fn bean(self: Arc<Self>);
++        fn booz(self: Pin<Box<Self>>);
++        fn blez(self: Rc<Self>);
++    }
++}
++
++#[test]
++fn arc() {
++    let mut mock = MockFoo::new();
++    mock.expect_bean()
++        .returning(|| ());
++    Arc::new(mock).bean();
++}
++
++#[test]
++fn pin() {
++    let mut mock = MockFoo::new();
++    mock.expect_booz()
++        .returning(|| ());
++    Pin::new(Box::new(mock)).booz();
++}
++
++#[test]
++fn rc() {
++    let mut mock = MockFoo::new();
++    mock.expect_blez()
++        .returning(|| ());
++    Rc::new(mock).blez();
++}
++
++#[test]
++fn ref_box() {
++    let mut mock = Box::new(MockFoo::new());
++    mock.expect_foo()
++        .returning(|| ());
++    mock.foo();
++}
++
++#[test]
++fn mutable() {
++    let mut mock = Box::new(MockFoo::new());
++    mock.expect_baz()
++        .returning(|| ());
++    mock.baz();
++}
++
++#[test]
++fn owned() {
++    let mut mock = Box::new(MockFoo::new());
++    mock.expect_bar()
++        .returning(|| ());
++    mock.bar();
++}
+diff --git a/tests/mock_cfg.rs b/tests/mock_cfg.rs
+new file mode 100644
+index 0000000..b846a87
+--- /dev/null
++++ b/tests/mock_cfg.rs
+@@ -0,0 +1,65 @@
++// vim: tw=80
++//! mock's methods and trait impls can be conditionally compiled
++#![deny(warnings)]
++
++use mockall::*;
++
++// For this test, use the "nightly" feature as the cfg gate, because it's tested
++// both ways in CI.
++#[cfg(feature = "nightly")]
++pub trait Beez {
++    fn beez(&self);
++}
++#[cfg(not(feature = "nightly"))]
++pub trait Beez {
++    fn beez(&self, x: i32) -> i32;
++}
++
++mock! {
++    pub Foo {
++        #[cfg(feature = "nightly")]
++        pub fn foo(&self);
++        #[cfg(not(feature = "nightly"))]
++        pub fn foo(&self, x: i32) -> i32;
++    }
++    #[cfg(feature = "nightly")]
++    impl Beez for Foo {
++        fn beez(&self);
++    }
++    #[cfg(not(feature = "nightly"))]
++    impl Beez for Foo {
++        fn beez(&self, x: i32) -> i32;
++    }
++}
++
++#[test]
++#[cfg(feature = "nightly")]
++fn test_nightly_method() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|| ());
++}
++
++#[test]
++#[cfg(feature = "nightly")]
++fn test_nightly_trait() {
++    let mut mock = MockFoo::new();
++    mock.expect_beez()
++        .returning(|| ());
++}
++
++#[test]
++#[cfg(not(feature = "nightly"))]
++fn test_not_nightly_method() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|x| x + 1);
++}
++
++#[test]
++#[cfg(not(feature = "nightly"))]
++fn test_not_nightly_trait() {
++    let mut mock = MockFoo::new();
++    mock.expect_beez()
++        .returning(|x| x + 1);
++}
+diff --git a/tests/mock_clone.rs b/tests/mock_clone.rs
+new file mode 100644
+index 0000000..8f4a227
+--- /dev/null
++++ b/tests/mock_clone.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! Clone-like methods (non-static method with Self return type) need the return
++//! type to be deselfified.
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    pub A {}
++    impl Clone for A {
++        fn clone(&self) -> Self;
++    }
++}
++
++#[allow(clippy::redundant_clone)]
++#[test]
++fn returning() {
++    let mut mock0 = MockA::new();
++    mock0.expect_clone()
++        .returning(MockA::new);
++    let _mock1 = mock0.clone();
++}
+diff --git a/tests/mock_closure.rs b/tests/mock_closure.rs
+new file mode 100644
+index 0000000..412f0f4
+--- /dev/null
++++ b/tests/mock_closure.rs
+@@ -0,0 +1,89 @@
++// vim: tw=80
++//! A method with a closure argument can be mocked, by turning the closure into
++//! a Boxed Fn.
++#![deny(warnings)]
++
++use mockall::*;
++
++struct NonCopy(u32);
++
++mock!{
++    Foo {
++        fn foo<F: Fn(u32) -> u32 + 'static>(&self, f: F) -> u32;
++        fn bar<F: FnMut(u32) -> u32 + 'static>(&self, f: F) -> u32;
++        fn baz<F: FnOnce(u32) -> NonCopy + 'static>(&self, f: F) -> NonCopy;
++        fn bean<F: Fn(u32) -> u32 + 'static>(f: F) -> u32;
++        // Not technically a closure, but it should work too
++        fn bang(&self, f: fn(u32) -> u32) -> u32;
++        // Identical to foo, but it uses a where clause
++        fn food<F>(&self, f: F) -> u32 where F: Fn(u32) -> u32 + 'static;
++        // Identical to foo, but with extra unrelated where predicates
++        fn foody<F, G>(&self, f: F, g:G) -> u32
++            where F: Fn(u32) -> u32 + 'static,
++                  G: 'static;
++    }
++}
++
++mod returning {
++    use super::*;
++
++    #[test]
++    fn bare_fn() {
++        let mut mock = MockFoo::new();
++        mock.expect_bang()
++            .returning(|f| f(42));
++        assert_eq!(84, mock.bang(|x| 2 * x));
++    }
++
++    #[test]
++    fn immutable() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|f| f(42));
++        assert_eq!(84, mock.foo(|x| 2 * x));
++    }
++
++    #[test]
++    fn mutable() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .returning(|mut f| {f(42); f(5) } );
++        let mut counter = 0;
++        assert_eq!(47, mock.bar(move |x| { counter += x; counter } ));
++    }
++
++    #[test]
++    fn once() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|f| f(42));
++        let initial = NonCopy(5);
++        assert_eq!(47, mock.baz(move |x| NonCopy(initial.0 + x)).0);
++    }
++
++    #[test]
++    fn static_method() {
++        let ctx = MockFoo::bean_context();
++        ctx.expect()
++            .returning(|f| f(42));
++        assert_eq!(84, MockFoo::bean(|x| 2 * x));
++    }
++
++    // food's where clause should be completely deleted in the mock
++    // implementation.
++    #[test]
++    fn deleted_where_clause() {
++        let mut mock = MockFoo::new();
++        mock.expect_food()
++            .returning(|f| f(42));
++        assert_eq!(84, mock.food(|x| 2 * x));
++    }
++
++    #[test]
++    fn where_clause() {
++        let mut mock = MockFoo::new();
++        mock.expect_foody()
++            .returning(|f, _g: u32| f(42));
++        assert_eq!(84, mock.foody(|x| 2u32 * x, 0u32));
++    }
++}
+diff --git a/tests/mock_concrete_struct_with_generic_trait.rs b/tests/mock_concrete_struct_with_generic_trait.rs
+new file mode 100644
+index 0000000..2fd07f5
+--- /dev/null
++++ b/tests/mock_concrete_struct_with_generic_trait.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! A concrete struct that implements a generic trait
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo<T> {
++    fn foo(&self, x: T) -> T;
++}
++mock! {
++    Bar {}
++    impl Foo<i32> for Bar {
++        fn foo(&self, x: i32) -> i32;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockBar::new();
++    mock.expect_foo()
++        .with(predicate::eq(42))
++        .returning(|x| x + 1);
++    assert_eq!(43, mock.foo(42));
++}
+diff --git a/tests/mock_concretize.rs b/tests/mock_concretize.rs
+new file mode 100644
+index 0000000..f9d73ef
+--- /dev/null
++++ b/tests/mock_concretize.rs
+@@ -0,0 +1,140 @@
++// vim: tw=80
++//! Some generic methods with non-`'static` generic parameters can be mocked by
++//! transforming the function arguments into trait objects.
++#![deny(warnings)]
++
++use mockall::*;
++use std::path::{Path, PathBuf};
++
++trait AsRefMut<T: ?Sized>: AsRef<T> + AsMut<T> {}
++impl<Q, T> AsRefMut<T> for Q where Q: AsRef<T> + AsMut<T>, T: ?Sized {}
++
++mock! {
++    Foo {
++        /// Base concretized function
++        #[mockall::concretize]
++        fn foo<P: AsRef<std::path::Path>>(&self, x: P);
++
++        /// With a where clause
++        #[mockall::concretize]
++        fn boom<P>(&self, x: P) where P: AsRef<std::path::Path>;
++
++        /// Static function
++        #[mockall::concretize]
++        fn bang<P: AsRef<std::path::Path>>(x: P);
++
++        /// Reference argument
++        #[mockall::concretize]
++        fn boomref<P: AsRef<std::path::Path>>(&self, x: &P);
++
++        /// Mutable reference argument
++        #[mockall::concretize]
++        fn boom_mutref<T: AsRefMut<str>>(&self, x: &mut T);
++
++        /// Slice argument
++        #[mockall::concretize]
++        fn boomv<P>(&self, x: &[P]) where P: AsRef<std::path::Path>;
++
++        /// Public visiblity
++        #[mockall::concretize]
++        pub fn foopub<P: AsRef<std::path::Path>>(&self, x: P);
++    }
++}
++
++mod generic_arg {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_foo()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        foo.foo(Path::new("/tmp"));
++        foo.foo(PathBuf::from(Path::new("/tmp")));
++        foo.foo("/tmp");
++    }
++}
++
++mod where_clause {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_boom()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        foo.boom(Path::new("/tmp"));
++        foo.boom(PathBuf::from(Path::new("/tmp")));
++        foo.boom("/tmp");
++    }
++}
++
++mod mutable_reference_arg {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_boom_mutref()
++            .withf(|p| p.as_ref() == "/tmp")
++            .once()
++            .returning(|s| s.as_mut().make_ascii_uppercase());
++        let mut s = String::from("/tmp");
++        foo.boom_mutref(&mut s);
++        assert_eq!(s, "/TMP");
++    }
++}
++
++mod reference_arg {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_boomref()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        foo.boomref(&Path::new("/tmp"));
++        foo.boomref(&PathBuf::from(Path::new("/tmp")));
++        foo.boomref(&"/tmp");
++    }
++}
++
++mod slice {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_boomv()
++            .withf(|v|
++                   v[0].as_ref() == Path::new("/tmp") &&
++                   v[1].as_ref() == Path::new("/mnt")
++            ).times(3)
++            .return_const(());
++        foo.boomv(&[Path::new("/tmp"), Path::new("/mnt")]);
++        foo.boomv(&[PathBuf::from("/tmp"), PathBuf::from("/mnt")]);
++        foo.boomv(&["/tmp", "/mnt"]);
++    }
++}
++
++mod static_method {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let ctx = MockFoo::bang_context();
++        ctx.expect()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        MockFoo::bang(Path::new("/tmp"));
++        MockFoo::bang(PathBuf::from(Path::new("/tmp")));
++        MockFoo::bang("/tmp");
++    }
++}
+diff --git a/tests/mock_concretize_with_bounds.rs b/tests/mock_concretize_with_bounds.rs
+new file mode 100644
+index 0000000..76b55a8
+--- /dev/null
++++ b/tests/mock_concretize_with_bounds.rs
+@@ -0,0 +1,135 @@
++// vim: tw=80
++//! Using #[concretize] on generic types with trait bounds
++#![deny(warnings)]
++
++use mockall::*;
++use std::path::{Path, PathBuf};
++
++trait AsRefMut<T: ?Sized>: AsRef<T> + AsMut<T> {}
++impl<Q, T> AsRefMut<T> for Q where Q: AsRef<T> + AsMut<T>, T: ?Sized {}
++
++mock! {
++    Foo {
++        /// Base concretized function
++        #[mockall::concretize]
++        fn foo<P: AsRef<std::path::Path> + Send>(&self, x: P);
++
++        /// With a where clause
++        #[mockall::concretize]
++        fn boom<P>(&self, x: P) where P: AsRef<std::path::Path> + Send;
++
++        /// Static function
++        #[mockall::concretize]
++        fn bang<P: AsRef<std::path::Path> + Send>(x: P);
++
++        /// Reference argument
++        #[mockall::concretize]
++        fn boomref<P: AsRef<std::path::Path> + Send>(&self, x: &P);
++
++        /// Mutable reference argument
++        #[mockall::concretize]
++        fn boom_mutref<T: AsRefMut<str> + Send>(&self, x: &mut T);
++
++        /// Slice argument
++        #[mockall::concretize]
++        fn boomv<P>(&self, x: &[P]) where P: AsRef<std::path::Path> + Send;
++    }
++}
++
++mod generic_arg {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_foo()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        foo.foo(Path::new("/tmp"));
++        foo.foo(PathBuf::from(Path::new("/tmp")));
++        foo.foo("/tmp");
++    }
++}
++
++mod where_clause {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_boom()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        foo.boom(Path::new("/tmp"));
++        foo.boom(PathBuf::from(Path::new("/tmp")));
++        foo.boom("/tmp");
++    }
++}
++
++mod mutable_reference_arg {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_boom_mutref()
++            .withf(|p| p.as_ref() == "/tmp")
++            .once()
++            .returning(|s| s.as_mut().make_ascii_uppercase());
++        let mut s = String::from("/tmp");
++        foo.boom_mutref(&mut s);
++        assert_eq!(s, "/TMP");
++    }
++}
++
++mod reference_arg {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_boomref()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        foo.boomref(&Path::new("/tmp"));
++        foo.boomref(&PathBuf::from(Path::new("/tmp")));
++        foo.boomref(&"/tmp");
++    }
++}
++
++mod slice {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let mut foo = MockFoo::new();
++        foo.expect_boomv()
++            .withf(|v|
++                   v[0].as_ref() == Path::new("/tmp") &&
++                   v[1].as_ref() == Path::new("/mnt")
++            ).times(3)
++            .return_const(());
++        foo.boomv(&[Path::new("/tmp"), Path::new("/mnt")]);
++        foo.boomv(&[PathBuf::from("/tmp"), PathBuf::from("/mnt")]);
++        foo.boomv(&["/tmp", "/mnt"]);
++    }
++}
++
++mod static_method {
++    use super::*;
++
++    #[test]
++    fn withf() {
++        let ctx = MockFoo::bang_context();
++        ctx.expect()
++            .withf(|p| p.as_ref() == Path::new("/tmp"))
++            .times(3)
++            .return_const(());
++        MockFoo::bang(Path::new("/tmp"));
++        MockFoo::bang(PathBuf::from(Path::new("/tmp")));
++        MockFoo::bang("/tmp");
++    }
++}
+diff --git a/tests/mock_constructor_with_args.rs b/tests/mock_constructor_with_args.rs
+new file mode 100644
+index 0000000..c12c442
+--- /dev/null
++++ b/tests/mock_constructor_with_args.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! A struct with a constructor method named "new" that has arguments.
++//! mockall should mock the provided method, and not autogenerate a 0-argument
++//! "new" method.
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    pub Foo {
++        fn new(x: u32) -> Self;
++    }
++}
++
++#[test]
++fn returning_once() {
++    let mock = MockFoo::default();
++
++    let ctx = MockFoo::new_context();
++    ctx.expect()
++        .return_once(|_| mock);
++
++    let _mock = MockFoo::new(5);
++}
+diff --git a/tests/mock_debug.rs b/tests/mock_debug.rs
+new file mode 100644
+index 0000000..81e30cd
+--- /dev/null
++++ b/tests/mock_debug.rs
+@@ -0,0 +1,40 @@
++// vim: tw=80
++//! A mocked struct should implement Debug
++#![deny(warnings)]
++
++use mockall::*;
++use std::fmt::{self, Debug, Formatter};
++
++// using derive(Debug) tells mockall to generate the Debug impl automatically
++mock!{
++    #[derive(Debug)]
++    pub Bar { }
++    impl Clone for Bar {
++        fn clone(&self) -> Self;
++    }
++}
++
++// With no derive(Debug), mockall won't genetate the debug impl automatically
++mock!{
++    pub Baz { }
++    impl Clone for Baz {
++        fn clone(&self) -> Self;
++    }
++}
++impl Debug for MockBaz {
++    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
++        f.debug_struct("XXX").finish()
++    }
++}
++
++#[test]
++fn automatic() {
++    let bar = MockBar::new();
++    assert_eq!("MockBar", format!("{bar:?}"));
++}
++
++#[test]
++fn manual() {
++    let baz = MockBaz::new();
++    assert_eq!("XXX", format!("{baz:?}"));
++}
+diff --git a/tests/mock_deref.rs b/tests/mock_deref.rs
+new file mode 100644
+index 0000000..852b891
+--- /dev/null
++++ b/tests/mock_deref.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! A method that returns a type which is a common target for std::ops::Deref
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn foo(&self) -> &str;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const("Stuff".to_owned());
++    assert_eq!("Stuff", mock.foo());
++}
+diff --git a/tests/mock_deref_args.rs b/tests/mock_deref_args.rs
+new file mode 100644
+index 0000000..d0789d6
+--- /dev/null
++++ b/tests/mock_deref_args.rs
+@@ -0,0 +1,120 @@
++// vim: tw=80
++//! A method whose argument is a common `Deref` implementor
++#![deny(warnings)]
++
++use mockall::*;
++use std::{
++    ffi::{CStr, CString, OsStr, OsString},
++    path::{Path, PathBuf},
++};
++
++mock! {
++    Foo {
++        fn foo<T: 'static>(&self, x: Vec<T>);
++        fn bar(&self, x: String);
++        fn baz(&self, x: CString);
++        fn bean(&self, x: OsString);
++        fn boom(&self, x: PathBuf);
++    }
++}
++
++mod with {
++    use super::*;
++
++    #[test]
++    fn cstr() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .with(predicate::eq(CString::new("xxx").unwrap()))
++            .return_const(());
++        mock.baz(CString::new("xxx").unwrap());
++    }
++
++    #[test]
++    fn osstr() {
++        let mut mock = MockFoo::new();
++        mock.expect_bean()
++            .with(predicate::eq(OsStr::new("xxx").to_owned()))
++            .return_const(());
++        mock.bean(OsString::from("xxx"));
++    }
++
++    #[test]
++    fn path() {
++        let mut mock = MockFoo::new();
++        mock.expect_boom()
++            .with(predicate::eq(Path::new("dir/file").to_owned()))
++            .return_const(());
++        mock.boom(PathBuf::from("dir/file"));
++    }
++
++    #[test]
++    fn string() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .with(predicate::eq("xxx".to_owned()))
++            .return_const(());
++        mock.bar(String::from("xxx"));
++    }
++
++    #[test]
++    fn vec() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo::<i32>()
++            .with(predicate::eq(vec![1, 2, 3]))
++            .return_const(());
++        mock.foo(vec![1, 2, 3]);
++    }
++}
++
++mod withf {
++    use super::*;
++
++    #[test]
++    fn cstr() {
++        let mut mock = MockFoo::new();
++        const WANT: [u8; 4] = [120u8, 120, 120, 0];
++        let want = CStr::from_bytes_with_nul(&WANT[..]).unwrap();
++        mock.expect_baz()
++            .withf(move |s| s.as_c_str() == want)
++            .return_const(());
++        mock.baz(CString::new("xxx").unwrap());
++    }
++
++    #[test]
++    fn osstr() {
++        let mut mock = MockFoo::new();
++        mock.expect_bean()
++            .withf(move |s| s.as_os_str() == OsStr::new("xxx"))
++            .return_const(());
++        mock.bean(OsString::from("xxx"));
++    }
++
++    #[test]
++    fn path() {
++        let mut mock = MockFoo::new();
++        mock.expect_boom()
++            .withf(move |s| s.as_path() == Path::new("dir/file"))
++            .return_const(());
++        mock.boom(PathBuf::from("dir/file"));
++    }
++
++    #[test]
++    fn string() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .withf(|sl: &String| sl == "xxx")
++            .return_const(());
++        mock.bar(String::from("xxx"));
++    }
++
++    #[test]
++    fn vec() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo::<i32>()
++            .withf(|sl: &Vec<i32>| sl == &[1, 2, 3])
++            .return_const(());
++        mock.foo(vec![1, 2, 3]);
++    }
++
++}
+diff --git a/tests/mock_docs.rs b/tests/mock_docs.rs
+new file mode 100644
+index 0000000..f1fd7ce
+--- /dev/null
++++ b/tests/mock_docs.rs
+@@ -0,0 +1,26 @@
++// vim: tw=80
++#![deny(missing_docs)]
++#![deny(warnings)]
++
++use mockall::*;
++
++// mock! should allow doc comments in all reasonable positions.  This test
++// ensures that the code will compile.  mockall_derive has a unit test to ensure
++// that the doc comments are correctly placed.
++
++pub trait Tr {
++    fn bar(&self);
++}
++
++mock!{
++    /// Struct docs
++    pub Foo {
++        /// Method docs
++        fn foo(&self);
++    }
++    /// Trait docs
++    impl Tr for Foo {
++        /// Trait method docs
++        fn bar(&self);
++    }
++}
+diff --git a/tests/mock_generic_and_reference_arguments.rs b/tests/mock_generic_and_reference_arguments.rs
+new file mode 100644
+index 0000000..02f3767
+--- /dev/null
++++ b/tests/mock_generic_and_reference_arguments.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++//! A generic method may have non-generic reference arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn foo<T: 'static>(&self, t: T, x: &i16) -> u32;
++    }
++}
++
++#[test]
++fn with() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<i32>()
++        .with(predicate::eq(4), predicate::eq(5))
++        .return_const(42u32);
++    assert_eq!(42, mock.foo(4i32, &5i16));
++}
+diff --git a/tests/mock_generic_arguments.rs b/tests/mock_generic_arguments.rs
+new file mode 100644
+index 0000000..aa3aaf4
+--- /dev/null
++++ b/tests/mock_generic_arguments.rs
+@@ -0,0 +1,68 @@
++// vim: tw=80
++//! A struct with a generic method that has generic arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn foo<T: 'static + std::fmt::Debug>(&self, t: T) -> i32;
++        fn bar<T: 'static>(&self, t: T) -> i32;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<i16>()
++        .return_const(0);
++    assert_eq!(0, mock.foo(0i16));
++}
++
++mod with {
++    use super::*;
++
++    /// Multiple generic methods with the same set of generic parameters are in
++    /// scope at the same time.  Their expectations should not get scrambled.
++    #[test]
++    fn multiple_methods() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo::<i16>()
++            .with(predicate::eq(4))
++            .return_const(0);
++        mock.expect_bar::<i16>()
++            .with(predicate::eq(5))
++            .return_const(0);
++        mock.bar(5i16);
++        mock.foo(4i16);
++    }
++
++    #[test]
++    fn ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo::<i16>()
++            .with(predicate::eq(4))
++            .return_const(0);
++        mock.foo(4i16);
++    }
++
++    #[test]
++    #[should_panic(expected = "MockFoo::foo(4): No matching expectation found")]
++    fn wrong_generic_type() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo::<i16>()
++            .with(predicate::eq(4))
++            .return_const(0);
++        mock.foo(4i32);
++    }
++
++    #[test]
++    #[should_panic(expected = "MockFoo::bar(?): No matching expectation found")]
++    fn no_debug_trait_bound() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar::<i16>()
++            .with(predicate::eq(4))
++            .return_const(0);
++        mock.bar(4i32);
++    }
++}
+diff --git a/tests/mock_generic_arguments_returning_reference.rs b/tests/mock_generic_arguments_returning_reference.rs
+new file mode 100644
+index 0000000..ea0ea31
+--- /dev/null
++++ b/tests/mock_generic_arguments_returning_reference.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++    fn foo<T: 'static>(&self, t: T) -> &u32;
++}
++
++mock!{
++    MyStruct {}
++    impl Foo for MyStruct {
++        fn foo<T: 'static>(&self, t: T) -> &u32;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockMyStruct::new();
++    mock.expect_foo::<i16>().return_const(5u32);
++    assert_eq!(5u32, *mock.foo(99i16));
++}
+diff --git a/tests/mock_generic_constructor.rs b/tests/mock_generic_constructor.rs
+new file mode 100644
+index 0000000..c81b0cf
+--- /dev/null
++++ b/tests/mock_generic_constructor.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A generic struct with bounds on its generic parameters can have a
++//! constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    pub Foo<T: Default + 'static> {
++        fn build() -> MockFoo<T>;
++    }
++}
++
++#[test]
++fn returning_once() {
++    let ctx = MockFoo::<i16>::build_context();
++    ctx.expect()
++        .return_once(MockFoo::<i16>::default);
++
++    let _mock: MockFoo<i16> = MockFoo::<i16>::build();
++}
+diff --git a/tests/mock_generic_constructor_with_where_clause.rs b/tests/mock_generic_constructor_with_where_clause.rs
+new file mode 100644
+index 0000000..2298ccc
+--- /dev/null
++++ b/tests/mock_generic_constructor_with_where_clause.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A generic struct with a where clause on its generic parameters can have a
++//! constructor method
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    pub Foo<T> where T: Default + 'static {
++        fn build() -> MockFoo<T>;
++    }
++}
++
++#[test]
++fn returning_once() {
++    let ctx = MockFoo::<i16>::build_context();
++    ctx.expect()
++        .return_once(MockFoo::<i16>::default);
++
++    let _mock: MockFoo<i16> = MockFoo::<i16>::build();
++}
+diff --git a/tests/mock_generic_method_on_generic_struct_returning_nonstatic.rs b/tests/mock_generic_method_on_generic_struct_returning_nonstatic.rs
+new file mode 100644
+index 0000000..819e70a
+--- /dev/null
++++ b/tests/mock_generic_method_on_generic_struct_returning_nonstatic.rs
+@@ -0,0 +1,116 @@
++//! Mocking a generic method whose return value's lifetime is a generic
++//! parameter on a generic struct requires extra care for the Expectation
++//! object's type generics.
++//! https://github.com/asomers/mockall/issues/306
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Clone)]
++struct X<'a>(&'a u32);
++
++trait Bong {
++    fn trait_foo<'a>(&self) -> X<'a>;
++    fn trait_baz<'a>(&self) -> &X<'a>;
++}
++
++mock! {
++    Thing<T> {
++        fn foo<'a>(&self) -> X<'a>;
++
++        // XXX static methods don't work yet.
++        // fn bar<'a>() -> X<'a>;
++
++        fn baz<'a>(&self) -> &X<'a>;
++
++        // Methods returning a mutable reference to a non-static value won't
++        // work unless 'a is static.  I doubt there are any real-life methods
++        // that fit this pattern; open an issue if you find one.
++         //fn bang<'a>(&mut self) -> &mut X<'a>;
++
++        // Generic methods can't return non-static values either, because
++        // Mockall requires generic methods' generic parameters to implement
++        // std::any::Any, which means they must be 'static.
++        //fn bean<'a, T: 'static>(&self, t: T) -> X<'a>;
++    }
++    // The same types of methods should work if they are Trait methods.
++    impl<T> Bong for Thing<T> {
++        fn trait_foo<'a>(&self) -> X<'a>;
++        fn trait_baz<'a>(&self) -> &X<'a>;
++    }
++}
++
++#[test]
++fn return_static() {
++    const D: u32 = 42;
++    let x = X(&D);
++    let mut thing = MockThing::<u32>::new();
++    thing.expect_foo()
++        .return_const(x);
++
++    assert_eq!(42u32, *thing.foo().0);
++}
++
++#[test]
++fn return_static_ref() {
++    const D: u32 = 42;
++    let x = X(&D);
++    let mut thing = MockThing::<u32>::new();
++    thing.expect_baz()
++        .return_const(x);
++
++    assert_eq!(42u32, *thing.baz().0);
++}
++
++// It isn't possible to safely set an expectation for a non-'static return value
++// (because the mock object doesn't have any lifetime parameters itself), but
++// unsafely setting such an expectation is a common use case.
++#[test]
++fn return_nonstatic() {
++    let d = 42u32;
++    let x = X(&d);
++    let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++    let mut thing = MockThing::<u32>::new();
++    thing.expect_foo()
++        .returning(move || xstatic.clone());
++
++    assert_eq!(42u32, *thing.foo().0);
++}
++
++mod trait_methods {
++    use super::*;
++
++    #[test]
++    fn return_static() {
++        const D: u32 = 42;
++        let x = X(&D);
++        let mut thing = MockThing::<u32>::new();
++        thing.expect_trait_foo()
++            .return_const(x);
++
++        assert_eq!(42u32, *thing.trait_foo().0);
++    }
++
++    #[test]
++    fn return_static_ref() {
++        const D: u32 = 42;
++        let x = X(&D);
++        let mut thing = MockThing::<u32>::new();
++        thing.expect_trait_baz()
++            .return_const(x);
++
++        assert_eq!(42u32, *thing.trait_baz().0);
++    }
++
++    #[test]
++    fn return_nonstatic() {
++        let d = 42u32;
++        let x = X(&d);
++        let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++        let mut thing = MockThing::<u32>::new();
++        thing.expect_trait_foo()
++            .returning(move || xstatic.clone());
++
++        assert_eq!(42u32, *thing.trait_foo().0);
++    }
++}
+diff --git a/tests/mock_generic_method_returning_nonstatic.rs b/tests/mock_generic_method_returning_nonstatic.rs
+new file mode 100644
+index 0000000..7b85ee1
+--- /dev/null
++++ b/tests/mock_generic_method_returning_nonstatic.rs
+@@ -0,0 +1,117 @@
++// vim: tw=80
++//! A generic method whose return value's lifetime is a generic parameter is a
++//! special case.  Mockall can only mock such methods if the expectation is
++//! 'static.
++//! https://github.com/asomers/mockall/issues/76
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Clone)]
++struct X<'a>(&'a u32);
++
++trait Bong {
++    fn trait_foo<'a>(&self) -> X<'a>;
++    fn trait_baz<'a>(&self) -> &X<'a>;
++}
++
++mock! {
++    Thing {
++        fn foo<'a>(&self) -> X<'a>;
++
++        // XXX static methods don't work yet.
++        // fn bar<'a>() -> X<'a>;
++
++        fn baz<'a>(&self) -> &X<'a>;
++
++        // Methods returning a mutable reference to a non-static value won't
++        // work unless 'a is static.  I doubt there are any real-life methods
++        // that fit this pattern; open an issue if you find one.
++        // fn bang<'a>(&mut self) -> &mut X<'a>;
++
++        // Generic methods can't return non-static values either, because
++        // Mockall requires generic methods' generic parameters to implement
++        // std::any::Any, which means they must be 'static.
++        //fn bean<'a, T: 'static>(&self, t: T) -> X<'a>;
++    }
++    // The same types of methods should work if they are Trait methods.
++    impl Bong for Thing {
++        fn trait_foo<'a>(&self) -> X<'a>;
++        fn trait_baz<'a>(&self) -> &X<'a>;
++    }
++}
++
++#[test]
++fn return_static() {
++    const D: u32 = 42;
++    let x = X(&D);
++    let mut thing = MockThing::new();
++    thing.expect_foo()
++        .return_const(x);
++
++    assert_eq!(42u32, *thing.foo().0);
++}
++
++#[test]
++fn return_static_ref() {
++    const D: u32 = 42;
++    let x = X(&D);
++    let mut thing = MockThing::new();
++    thing.expect_baz()
++        .return_const(x);
++
++    assert_eq!(42u32, *thing.baz().0);
++}
++
++// It isn't possible to safely set an expectation for a non-'static return value
++// (because the mock object doesn't have any lifetime parameters itself), but
++// unsafely setting such an expectation is a common use case.
++#[test]
++fn return_nonstatic() {
++    let d = 42u32;
++    let x = X(&d);
++    let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++    let mut thing = MockThing::new();
++    thing.expect_foo()
++        .returning(move || xstatic.clone());
++
++    assert_eq!(42u32, *thing.foo().0);
++}
++
++mod trait_methods {
++    use super::*;
++
++    #[test]
++    fn return_static() {
++        const D: u32 = 42;
++        let x = X(&D);
++        let mut thing = MockThing::new();
++        thing.expect_trait_foo()
++            .return_const(x);
++
++        assert_eq!(42u32, *thing.trait_foo().0);
++    }
++
++    #[test]
++    fn return_static_ref() {
++        const D: u32 = 42;
++        let x = X(&D);
++        let mut thing = MockThing::new();
++        thing.expect_trait_baz()
++            .return_const(x);
++
++        assert_eq!(42u32, *thing.trait_baz().0);
++    }
++
++    #[test]
++    fn return_nonstatic() {
++        let d = 42u32;
++        let x = X(&d);
++        let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++        let mut thing = MockThing::new();
++        thing.expect_trait_foo()
++            .returning(move || xstatic.clone());
++
++        assert_eq!(42u32, *thing.trait_foo().0);
++    }
++}
+diff --git a/tests/mock_generic_method_with_lifetime_parameter.rs b/tests/mock_generic_method_with_lifetime_parameter.rs
+new file mode 100644
+index 0000000..3a3d97d
+--- /dev/null
++++ b/tests/mock_generic_method_with_lifetime_parameter.rs
+@@ -0,0 +1,65 @@
++// vim: tw=80
++//! A generic method whose only generic parameter is a lifetime parameter is,
++//! from Mockall's perspective, pretty much the same as a non-generic method.
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Debug, Eq)]
++struct X<'a>(&'a u32);
++
++impl<'a> PartialEq for X<'a> {
++    fn eq(&self, other: &X<'a>) -> bool {
++        self.0 == other.0
++    }
++}
++
++mock!{
++    Foo {
++        fn foo<'a>(&self, x: &'a X<'a>) -> u32;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(42u32);
++    let x = X(&5);
++    assert_eq!(42, mock.foo(&x));
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|f| *f.0);
++    let x = X(&5);
++    assert_eq!(5, mock.foo(&x));
++}
++
++// I can't get this to work.  How can I create a Predicate that's valid for all
++// lifetimes?  'static should be reduceable to any other lifetime, but rustc
++// doesn't seem to understand that.
++//#[test]
++//fn with() {
++    //const X1: u32 = 5;
++    //const OTHER: X<'static> = X(&X1);
++    //let mut mock = MockFoo::new();
++    //mock.expect_foo()
++        //.with(mockall::predicate::eq(&OTHER))
++        //.return_const(42u32);
++    //let inner = 5;
++    //let x = X(&5);
++    //assert_eq!(42, mock.foo(&x));
++//}
++
++#[test]
++fn withf() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .withf(|f| *f.0 == 5)
++        .return_const(42u32);
++    let x = X(&5);
++    assert_eq!(42, mock.foo(&x));
++}
+diff --git a/tests/mock_generic_method_with_where_clause.rs b/tests/mock_generic_method_with_where_clause.rs
+new file mode 100644
+index 0000000..8aaa7cb
+--- /dev/null
++++ b/tests/mock_generic_method_with_where_clause.rs
+@@ -0,0 +1,43 @@
++// vim: tw=80
++#![deny(warnings)]
++use mockall::*;
++
++struct G<T> where T: Copy {t: T}
++
++mock! {
++    Foo {
++        fn foo<T>(&self, t: T) -> G<T> where T: Copy + 'static;
++        fn bar<T>(&self, g: G<T>) -> T where T: Copy + 'static;
++        fn baz<T>(&self) -> &G<T> where T: Copy + 'static;
++        fn bean<T>(&mut self) -> &mut G<T> where T: Copy + 'static;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<u32>()
++        .returning(|t| G{t});
++    assert_eq!(42, mock.foo(42u32).t);
++
++    mock.expect_bar::<u32>()
++        .returning(|g| g.t);
++    assert_eq!(42u32, mock.bar(G{t: 42}));
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_baz::<u32>()
++        .return_const(G{t: 42});
++    assert_eq!(42u32, mock.baz().t);
++}
++
++#[test]
++fn return_var() {
++    let mut mock = MockFoo::new();
++    mock.expect_bean::<u32>()
++        .return_var(G{t: 42});
++    mock.bean::<u32>().t += 1;
++    assert_eq!(43u32, mock.bean().t);
++}
+diff --git a/tests/mock_generic_methods_returning_mutable_reference.rs b/tests/mock_generic_methods_returning_mutable_reference.rs
+new file mode 100644
+index 0000000..1e708b6
+--- /dev/null
++++ b/tests/mock_generic_methods_returning_mutable_reference.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++    MyStruct {
++        fn foo<T: 'static>(&mut self, t: T) -> &mut u32;
++    }
++}
++
++#[test]
++fn return_var() {
++    let mut mock = MockMyStruct::new();
++    mock.expect_foo::<i16>().return_var(5u32);
++    *mock.foo(1i16) += 1;
++    assert_eq!(6u32, *mock.foo(2i16));
++}
+diff --git a/tests/mock_generic_return.rs b/tests/mock_generic_return.rs
+new file mode 100644
+index 0000000..8fd2a0a
+--- /dev/null
++++ b/tests/mock_generic_return.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn foo<O: 'static>(&self) -> O;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<i32>().return_const(42i32);
++    mock.expect_foo::<u16>().return_const(69u16);
++    assert_eq!(42i32, mock.foo());
++    assert_eq!(69u16, mock.foo());
++}
+diff --git a/tests/mock_generic_static_method_with_where_clause.rs b/tests/mock_generic_static_method_with_where_clause.rs
+new file mode 100644
+index 0000000..f70d4c7
+--- /dev/null
++++ b/tests/mock_generic_static_method_with_where_clause.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++#![deny(warnings)]
++// multiple bound locations is deliberate; we want to ensure that Mockall can
++// handle it correctly.
++#![allow(clippy::multiple_bound_locations)]
++
++use mockall::*;
++
++struct G<T> where T: Copy {t: T}
++
++mock! {
++    Foo {
++        fn make_g<T: 'static>(x: T) -> G<T> where T: Copy;
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = MockFoo::make_g_context();
++    ctx.expect::<i16>()
++        .returning(|t| G{t});
++    let g = MockFoo::make_g(42i16);
++    assert_eq!(g.t, 42i16);
++}
+diff --git a/tests/mock_generic_struct.rs b/tests/mock_generic_struct.rs
+new file mode 100644
+index 0000000..0863b44
+--- /dev/null
++++ b/tests/mock_generic_struct.rs
+@@ -0,0 +1,33 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Clone)]
++struct NonCopy(u32);
++
++// A struct with a definition like this:
++// pub struct ExtGenericStruct<T: Clone> {
++//     _x: i16
++// }
++// impl<T: Clone> ExtGenericStruct<T> {
++//     fn foo(&self, _x: T) -> T {
++//         42
++//     }
++// }
++// Could be mocked like this:
++mock!{
++    pub ExtGenericStruct<T: Clone> {
++        fn foo(&self, x: T) -> T;
++    }
++}
++
++#[test]
++#[allow(clippy::redundant_clone)]
++fn returning() {
++    let mut mock = MockExtGenericStruct::<NonCopy>::new();
++    // An explicit .clone() is required so as not to return by move
++    mock.expect_foo()
++        .returning(|x| x.clone());
++    assert_eq!(5, mock.foo(NonCopy(5)).0);
++}
+diff --git a/tests/mock_generic_struct_with_bounds.rs b/tests/mock_generic_struct_with_bounds.rs
+new file mode 100644
+index 0000000..4f15836
+--- /dev/null
++++ b/tests/mock_generic_struct_with_bounds.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    pub Foo<T: Clone + Copy> {
++        fn foo(&self, x: u32) -> i64;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::<i16>::new();
++    mock.expect_foo().returning(i64::from);
++    assert_eq!(5, mock.foo(5));
++}
+diff --git a/tests/mock_generic_struct_with_generic_method.rs b/tests/mock_generic_struct_with_generic_method.rs
+new file mode 100644
+index 0000000..92fc46f
+--- /dev/null
++++ b/tests/mock_generic_struct_with_generic_method.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++    pub Foo<T: Clone + 'static> {
++        fn foo<Q: 'static>(&self, q: Q) -> T;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::<u32>::new();
++    mock.expect_foo::<i16>()
++        .return_const(100_000u32);
++    assert_eq!(100_000, mock.foo(-5i16));
++}
+diff --git a/tests/mock_generic_struct_with_generic_static_method.rs b/tests/mock_generic_struct_with_generic_static_method.rs
+new file mode 100644
+index 0000000..1f93f3f
+--- /dev/null
++++ b/tests/mock_generic_struct_with_generic_static_method.rs
+@@ -0,0 +1,102 @@
++// vim: tw=80
++//! A generic struct with a generic method on a different parameter
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++mock! {
++    Foo<T: 'static + std::fmt::Debug> {
++        fn foo<Q: 'static + std::fmt::Debug>(t: T, q: Q) -> u64;
++    }
++}
++
++static FOO_MTX: Mutex<()> = Mutex::new(());
++
++// Checkpointing the mock object should not checkpoint static methods too
++#[test]
++fn checkpoint() {
++    let _m = FOO_MTX.lock();
++
++    let mut mock = MockFoo::<u32>::new();
++    let ctx = MockFoo::<u32>::foo_context();
++    ctx.expect::<i16>()
++        .returning(|_, _| 0)
++        .times(1..3);
++    mock.checkpoint();
++    MockFoo::foo(42u32, 69i16);
++}
++
++// It should also be possible to checkpoint just the context object
++#[test]
++#[should_panic(expected =
++    "MockFoo::foo: Expectation(<anything>) called 0 time(s) which is fewer than expected 1")]
++fn ctx_checkpoint() {
++    let _m = FOO_MTX.lock();
++    let ctx = MockFoo::<u32>::foo_context();
++    ctx.expect::<i16>()
++        .returning(|_, _| 0)
++        .times(1..3);
++    ctx.checkpoint();
++    panic!("Shouldn't get here!");
++}
++
++// Expectations should be cleared when a context object drops
++#[test]
++#[should_panic(expected = "MockFoo::foo(42, 69): No matching expectation found")]
++fn ctx_hygiene() {
++    let _m = FOO_MTX.lock();
++    {
++        let ctx0 = MockFoo::<u32>::foo_context();
++        ctx0.expect::<i16>()
++            .returning(|_, _| 0);
++    }
++    MockFoo::foo(42, 69);
++}
++
++#[cfg_attr(not(feature = "nightly"), ignore)]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++#[test]
++fn return_default() {
++    let _m = FOO_MTX.lock();
++
++    let ctx = MockFoo::<u32>::foo_context();
++    ctx.expect::<i16>();
++    MockFoo::foo(5u32, 6i16);
++}
++
++#[test]
++fn returning() {
++    let _m = FOO_MTX.lock();
++
++    let ctx = MockFoo::<u32>::foo_context();
++    ctx.expect::<i16>()
++        .returning(|_, _| 0);
++    MockFoo::foo(41u32, 42i16);
++}
++
++#[test]
++fn two_matches() {
++    let _m = FOO_MTX.lock();
++
++    let ctx = MockFoo::<u32>::foo_context();
++    ctx.expect::<i16>()
++        .with(predicate::eq(42u32), predicate::eq(0i16))
++        .return_const(99u64);
++    ctx.expect::<i16>()
++        .with(predicate::eq(69u32), predicate::eq(0i16))
++        .return_const(101u64);
++    assert_eq!(101, MockFoo::foo(69u32, 0i16));
++    assert_eq!(99, MockFoo::foo(42u32, 0i16));
++}
++
++#[test]
++fn with() {
++    let _m = FOO_MTX.lock();
++
++    let ctx = MockFoo::<u32>::foo_context();
++    ctx.expect::<i16>()
++        .with(predicate::eq(42u32), predicate::eq(99i16))
++        .returning(|_, _| 0);
++    MockFoo::foo(42u32, 99i16);
++}
+diff --git a/tests/mock_generic_struct_with_generic_trait.rs b/tests/mock_generic_struct_with_generic_trait.rs
+new file mode 100644
+index 0000000..c955441
+--- /dev/null
++++ b/tests/mock_generic_struct_with_generic_trait.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo<T> {
++    fn foo(&self, x: T) -> T;
++}
++mock! {
++    Bar<T, Z> {}
++    impl<T, Z> Foo<T> for Bar<T, Z> {
++        fn foo(&self, x: T) -> T;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockBar::<u32, u64>::new();
++    mock.expect_foo()
++        .returning(|x| x);
++    assert_eq!(5u32, mock.foo(5u32));
++}
+diff --git a/tests/mock_generic_struct_with_generic_trait_with_different_bounds.rs b/tests/mock_generic_struct_with_generic_trait_with_different_bounds.rs
+new file mode 100644
+index 0000000..efb0d58
+--- /dev/null
++++ b/tests/mock_generic_struct_with_generic_trait_with_different_bounds.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo<T> {
++    fn foo(&self, x: T) -> T;
++}
++mock! {
++    Bar<T> {}
++    impl<T: Copy> Foo<T> for Bar<T> {
++        fn foo(&self, x: T) -> T;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockBar::<u32>::new();
++    mock.expect_foo()
++        .returning(|x| x);
++    assert_eq!(5u32, mock.foo(5u32));
++}
+diff --git a/tests/mock_generic_struct_with_nondefault_parameter.rs b/tests/mock_generic_struct_with_nondefault_parameter.rs
+new file mode 100644
+index 0000000..40bfd82
+--- /dev/null
++++ b/tests/mock_generic_struct_with_nondefault_parameter.rs
+@@ -0,0 +1,37 @@
++// vim: tw=80
++//! mock a generic struct and instantiate it with a parameter type that does not
++//! implement Default
++#![deny(warnings)]
++
++use mockall::*;
++
++struct NonDefault();
++
++trait Foo<T> {
++    fn foo(&self) -> T;
++}
++mock! {
++    ExternalStruct<T> {}
++    impl<T> Foo<T> for ExternalStruct<T> {
++        fn foo(&self) -> T;
++    }
++}
++
++#[test]
++#[should_panic(expected =
++    "MockExternalStruct::foo: Expectation(<anything>) Can only return default values for types that impl std::Default")]
++#[cfg_attr(not(feature = "nightly"), ignore)]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++fn return_default() {
++    let mut mock = MockExternalStruct::<NonDefault>::new();
++    mock.expect_foo();
++    mock.foo();
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockExternalStruct::<NonDefault>::new();
++    mock.expect_foo()
++        .returning(NonDefault);
++    mock.foo();
++}
+diff --git a/tests/mock_generic_struct_with_static_method.rs b/tests/mock_generic_struct_with_static_method.rs
+new file mode 100644
+index 0000000..6b2928b
+--- /dev/null
++++ b/tests/mock_generic_struct_with_static_method.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! static non-generic methods of generic structs shouldn't require any special
++//! treatment when mocking.  Prior to version 0.3.0, the struct's generic
++//! parameters had to be duplicated as generic parameters of the method.
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo<T: 'static> {
++        fn foo(t: T);
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = MockFoo::<u32>::foo_context();
++    ctx.expect()
++        .returning(|_| ());
++    MockFoo::foo(42u32);
++}
+diff --git a/tests/mock_generic_struct_with_trait.rs b/tests/mock_generic_struct_with_trait.rs
+new file mode 100644
+index 0000000..a772c99
+--- /dev/null
++++ b/tests/mock_generic_struct_with_trait.rs
+@@ -0,0 +1,23 @@
++// vim: ts=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++    fn foo(&self, x: u32) -> u32;
++}
++
++mock! {
++    Bar<T: Copy> {}
++    impl<T: Copy> Foo for Bar<T> {
++        fn foo(&self, x: u32) -> u32;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockBar::<u32>::new();
++    mock.expect_foo()
++        .return_const(43u32);
++    assert_eq!(43, mock.foo(42));
++}
+diff --git a/tests/mock_generic_struct_with_trait_with_associated_types.rs b/tests/mock_generic_struct_with_trait_with_associated_types.rs
+new file mode 100644
+index 0000000..ced6e9e
+--- /dev/null
++++ b/tests/mock_generic_struct_with_trait_with_associated_types.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo<T> {}
++    impl<T> Iterator for Foo<T> {
++        type Item=T;
++        fn next(&mut self) -> Option<T>;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::<u32>::new();
++    mock.expect_next()
++        .return_const(None);
++    assert!(mock.next().is_none());
++}
+diff --git a/tests/mock_generic_struct_with_where_clause.rs b/tests/mock_generic_struct_with_where_clause.rs
+new file mode 100644
+index 0000000..14a8e10
+--- /dev/null
++++ b/tests/mock_generic_struct_with_where_clause.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++//! A generic struct with a where clause
++#![deny(warnings)]
++
++// An explicit clone is required so as not to return by move
++#![allow(clippy::clone_on_copy)]
++
++use mockall::*;
++
++mock! {
++    Foo<T> where T:Clone {
++        fn foo(&self, t: T) -> T;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|t: u32| t.clone());
++    assert_eq!(5u32, mock.foo(5u32));
++}
+diff --git a/tests/mock_generic_struct_with_where_clause_and_trait.rs b/tests/mock_generic_struct_with_where_clause_and_trait.rs
+new file mode 100644
+index 0000000..fd9b5ac
+--- /dev/null
++++ b/tests/mock_generic_struct_with_where_clause_and_trait.rs
+@@ -0,0 +1,31 @@
++// vim: tw=80
++//! A generic struct with a where clause, that also implements a trait
++#![deny(warnings)]
++
++// An explicit clone is required so as not to return by move
++#![allow(clippy::clone_on_copy)]
++
++use mockall::*;
++
++trait Bar {
++    fn bar(&self);
++}
++mock! {
++    Foo<T> where T: Clone {
++        fn foo(&self, t: T) -> T;
++    }
++    impl<T> Bar for Foo<T> where T: Clone {
++        fn bar(&self);
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|t: u32| t.clone());
++    mock.expect_bar()
++        .returning(|| ());
++    assert_eq!(5u32, mock.foo(5u32));
++    mock.bar();
++}
+diff --git a/tests/mock_generic_trait.rs b/tests/mock_generic_trait.rs
+new file mode 100644
+index 0000000..24413bc
+--- /dev/null
++++ b/tests/mock_generic_trait.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++    fn foo(&self);
++}
++
++mock! {
++    Bar<T> {}
++    impl<T> Foo for Bar<T> {
++        fn foo(&self);
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockBar::<u32>::new();
++    mock.expect_foo().return_const(());
++    mock.foo();
++}
+diff --git a/tests/mock_impl_generic_trait.rs b/tests/mock_impl_generic_trait.rs
+new file mode 100644
+index 0000000..6819c81
+--- /dev/null
++++ b/tests/mock_impl_generic_trait.rs
+@@ -0,0 +1,22 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait MyTrait<T> {}
++
++struct MyStruct<T>(T);
++impl<T> MyTrait<T> for MyStruct<T> {}
++
++mock!{
++    Foo {
++        fn foo<R: 'static>(&self) -> impl MyTrait<R>;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<u32>().returning(|| Box::new(MyStruct(42u32)));
++    let _mto: Box<dyn MyTrait<u32>> = mock.foo();
++}
+diff --git a/tests/mock_impl_trait.rs b/tests/mock_impl_trait.rs
+new file mode 100644
+index 0000000..fb1bb7a
+--- /dev/null
++++ b/tests/mock_impl_trait.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++//! a method that returns impl Trait
++#![deny(warnings)]
++
++use mockall::*;
++use std::fmt::Debug;
++
++mock!{
++    Foo {
++        fn foo(&self) -> impl Debug + Send;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo().returning(|| Box::new(4));
++    format!("{:?}", mock.foo());
++}
+diff --git a/tests/mock_inherited_traits.rs b/tests/mock_inherited_traits.rs
+new file mode 100644
+index 0000000..940b822
+--- /dev/null
++++ b/tests/mock_inherited_traits.rs
+@@ -0,0 +1,32 @@
++// vim: tw=80
++//! A struct that implements a trait that inherits another trait
++#![deny(warnings)]
++
++use mockall::*;
++
++trait A {
++    fn foo(&self);
++}
++
++trait B: A {
++    fn bar(&self);
++}
++
++mock!{
++    B {}
++    impl A for B {
++        fn foo(&self);
++    }
++    impl B for B {
++        fn bar(&self);
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockB::new();
++    mock.expect_foo().returning(|| ());
++    mock.expect_bar().returning(|| ());
++    mock.foo();
++    mock.bar();
++}
+diff --git a/tests/mock_life0.rs b/tests/mock_life0.rs
+new file mode 100644
+index 0000000..722f78e
+--- /dev/null
++++ b/tests/mock_life0.rs
+@@ -0,0 +1,16 @@
++// vim: tw=80
++//! mock a method whose self parameter has an explicit lifetime
++//! https://github.com/asomers/mockall/issues/95
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++    Foo {
++        fn foo<'life0>(&'life0 self, x: u32) -> u32;
++    }
++}
++
++// TODO: test that the mock method respects the lifetime bound, once Mockall
++// supports mocking non-static structs
++// (https://github.com/asomers/mockall/issues/4)
+diff --git a/tests/mock_multiple_generic_arguments.rs b/tests/mock_multiple_generic_arguments.rs
+new file mode 100644
+index 0000000..1221c71
+--- /dev/null
++++ b/tests/mock_multiple_generic_arguments.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++
++mock! {
++    Foo {
++        fn foo<T: 'static, Q: 'static>(&self, t: T, q: Q);
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo::<i16, i32>().return_const(());
++    mock.foo(0i16, 1i32)
++}
+diff --git a/tests/mock_multiple_traits.rs b/tests/mock_multiple_traits.rs
+new file mode 100644
+index 0000000..df4c0e1
+--- /dev/null
++++ b/tests/mock_multiple_traits.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++//! A struct that implements multiple traits
++#![deny(warnings)]
++
++use mockall::*;
++
++trait A {}
++trait B {}
++mock!{
++    MultiTrait {}
++    impl A for MultiTrait {}
++    impl B for MultiTrait {}
++}
++
++#[test]
++fn new() {
++    fn foo<T: A + B>(_t: T) {}
++
++    let mock = MockMultiTrait::new();
++    foo(mock);
++}
+diff --git a/tests/mock_nonlocal_trait.rs b/tests/mock_nonlocal_trait.rs
+new file mode 100644
+index 0000000..5a140c6
+--- /dev/null
++++ b/tests/mock_nonlocal_trait.rs
+@@ -0,0 +1,28 @@
++// vim: tw=80
++//! A trait that isn't imported directly into the local namespace
++#![deny(warnings)]
++
++use mockall::*;
++
++mod my_module {
++    pub trait Foo {
++        fn foo(&self) -> i32;
++    }
++}
++
++mock! {
++    Bar {}
++    impl my_module::Foo for Bar {
++        fn foo(&self) -> i32;
++    }
++}
++
++#[test]
++fn returning() {
++    use my_module::Foo;
++
++    let mut mock = MockBar::new();
++    mock.expect_foo()
++        .returning(|| 42);
++    assert_eq!(42, mock.foo());
++}
+diff --git a/tests/mock_nonpub.rs b/tests/mock_nonpub.rs
+new file mode 100644
+index 0000000..a349175
+--- /dev/null
++++ b/tests/mock_nonpub.rs
+@@ -0,0 +1,37 @@
++// vim: tw=80
++//! methods can use non-public types, as long as the object's visibility is
++//! compatible.
++#![deny(warnings)]
++
++use mockall::*;
++
++mod outer {
++    struct SuperT();
++    trait SuperTrait {}
++
++    mod inner {
++        use super::super::mock;
++
++        pub(crate) struct PubCrateT();
++        struct PrivT();
++
++        mock! {
++            Foo {
++                fn foo(&self, x: PubCrateT) -> PubCrateT;
++                fn bar(&self, x: PrivT) -> PrivT;
++                fn baz(&self, x: super::SuperT) -> super::SuperT;
++                fn refbaz(&self, x: super::SuperT) -> &super::SuperT;
++                fn refmutbaz(&mut self, x: super::SuperT) -> &mut super::SuperT;
++                fn staticbaz(x: super::SuperT) -> super::SuperT;
++                fn bang(&self, x: crate::outer::SuperT) -> crate::outer::SuperT;
++                fn bean(&self, x: self::PrivT) -> self::PrivT;
++                fn goo<T: super::SuperTrait + 'static>(t: T);
++                fn goo_wc<T>(t: T) where T: super::SuperTrait + 'static;
++                fn boob<F: Fn(u32) -> super::SuperT + 'static>(&self, f: F)
++                    -> u32;
++                fn boobwc<F>(&self, f: F) -> u32
++                    where F: Fn(u32) -> super::SuperT + 'static;
++            }
++        }
++    }
++}
+diff --git a/tests/mock_ref_and_nonref_arguments.rs b/tests/mock_ref_and_nonref_arguments.rs
+new file mode 100644
+index 0000000..b5330df
+--- /dev/null
++++ b/tests/mock_ref_and_nonref_arguments.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! A method that has both a reference and a nonreference argument
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++    Foo {
++        fn foo(&self, i0: i32, i1: &u16) -> i32;
++    }
++}
++
++#[test]
++fn with() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .with(predicate::eq(42), predicate::eq(1))
++        .returning(|x, y| x + i32::from(*y));
++    let x = 42i32;
++    let y = 1u16;
++    assert_eq!(43i32, mock.foo(x, &y));
++}
++
++#[test]
++fn withf() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .withf(|x, y| *x == i32::from(*y))
++        .returning(|x, y| x + i32::from(*y));
++    let x = 42i32;
++    let y = 42u16;
++    assert_eq!(84i32, mock.foo(x, &y));
++}
++
+diff --git a/tests/mock_reference_arguments.rs b/tests/mock_reference_arguments.rs
+new file mode 100644
+index 0000000..53761b5
+--- /dev/null
++++ b/tests/mock_reference_arguments.rs
+@@ -0,0 +1,142 @@
++// vim: tw=80
++//! A struct with methods that take arguments by reference
++#![deny(warnings)]
++
++use mockall::*;
++
++const X: u32 = 99;
++
++mock!{
++    Foo {
++        fn foo(&self, x: &u32) -> u32;
++        fn bar(&self, y: &'static u32);
++    }
++}
++
++mod r#match {
++    use super::*;
++
++    #[test]
++    fn with() {
++        const Y: u32 = 5;
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .with(predicate::eq(5u32))
++            .returning(|x| *x);
++        mock.expect_bar()
++            .with(predicate::eq(99u32))
++            .returning(|_| ());
++        let r = mock.foo(&Y);
++        assert_eq!(5, r);
++        mock.bar(&X);
++    }
++
++    #[test]
++    fn withf() {
++        const Y: u32 = 5;
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .withf(|x| *x == 5)
++            .returning(|x| *x);
++        mock.expect_bar()
++            .withf(|x| *x == 99)
++            .returning(|_| ());
++        let r = mock.foo(&Y);
++        assert_eq!(5, r);
++        mock.bar(&X);
++    }
++}
++
++mod times {
++    use super::*;
++    const X: u32 = 42;
++
++    #[test]
++    fn ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 0)
++            .times(2);
++        mock.foo(&X);
++        mock.foo(&X);
++    }
++
++    #[test]
++    #[should_panic(
++        expected = "MockFoo::foo: Expectation(<anything>) called 1 time(s) which is fewer than expected 2"
++    )]
++    fn too_few() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 0)
++            .times(2);
++        mock.foo(&X);
++    }
++
++    #[test]
++    #[should_panic(
++        expected = "MockFoo::foo: Expectation(<anything>) called 3 times which is more than the expected 2"
++    )]
++    fn too_many() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 0)
++            .times(2);
++        mock.foo(&X);
++        mock.foo(&X);
++        mock.foo(&X);
++        // Verify that we panic quickly and don't reach code below this point.
++        panic!("Shouldn't get here!");
++    }
++
++    #[test]
++    fn range_ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 0)
++            .times(2..4);
++        mock.foo(&X);
++        mock.foo(&X);
++    }
++
++    #[test]
++    #[should_panic(
++        expected = "MockFoo::foo: Expectation(<anything>) called 1 time(s) which is fewer than expected 2"
++    )]
++    fn range_too_few() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 0)
++            .times(2..4);
++        mock.foo(&X);
++    }
++
++    #[test]
++    #[should_panic(
++        expected = "MockFoo::foo: Expectation(<anything>) called 4 times which is more than the expected 3"
++    )]
++    fn range_too_many() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 0)
++            .times(2..4);
++        mock.foo(&X);
++        mock.foo(&X);
++        mock.foo(&X);
++        mock.foo(&X);
++        // Verify that we panic quickly and don't reach code below this point.
++        panic!("Shouldn't get here!");
++    }
++}
++
++#[test]
++fn times_full() {
++    const X: u32 = 42;
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|_| 0)
++        .times(1)
++        .times(..);
++    mock.foo(&X);
++    mock.foo(&X);
++}
+diff --git a/tests/mock_refmut_arguments.rs b/tests/mock_refmut_arguments.rs
+new file mode 100644
+index 0000000..66589c4
+--- /dev/null
++++ b/tests/mock_refmut_arguments.rs
+@@ -0,0 +1,52 @@
++// vim: tw=80
++//! A struct with methods that take arguments by mutable reference.
++#![deny(warnings)]
++
++use std::mem;
++
++use mockall::*;
++
++mock!{
++    Foo {
++        fn foo(&self, x: &mut u32);
++        // This is almost never safe, but it should still work.
++        fn bar(&self, y: &'static mut u32);
++    }
++}
++
++#[test]
++fn returning() {
++    let mut x: u32 = 5;
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .withf(|x| *x == 5)
++        .returning(|x| { *x = 42;} );
++    mock.foo(&mut x);
++    assert_eq!(x, 42);
++}
++
++#[test]
++fn with() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .with(predicate::eq(0u32))
++        .returning(|x| {*x = 6;});
++    mock.expect_foo()
++        .with(predicate::eq(42u32))
++        .returning(|x| {*x = 5;});
++    let mut x = 42u32;
++    mock.foo(&mut x);
++    assert_eq!(5, x);
++}
++
++#[test]
++fn static_mut() {
++    let mut x: u32 = 5;
++    let mut mock = MockFoo::new();
++    mock.expect_bar()
++        .withf(|x| *x == 5)
++        .returning(|x| { *x = 42;} );
++    // Safe because mock leaves scope before x
++    unsafe { mock.bar(mem::transmute(&mut x)); }
++    assert_eq!(x, 42);
++}
+diff --git a/tests/mock_return_anonymous_lifetime.rs b/tests/mock_return_anonymous_lifetime.rs
+new file mode 100644
+index 0000000..1713c57
+--- /dev/null
++++ b/tests/mock_return_anonymous_lifetime.rs
+@@ -0,0 +1,54 @@
++// vim: tw=80
++//! A mock method should be able to return an object parameterized on the
++//! anonymous lifetime.
++//! https://github.com/asomers/mockall/issues/87
++#![deny(warnings)]
++
++use mockall::*;
++
++#[derive(Clone)]
++struct X<'a>(&'a u32);
++
++trait T {
++    fn trait_method(&self) -> X<'_>;
++}
++
++mock! {
++    Foo {
++        fn inherent_method(&self) -> X<'_>;
++    }
++    impl T for Foo {
++        fn trait_method(&self) -> X<'_>;
++    }
++}
++
++// It isn't possible to safely set an expectation for a non-'static return value
++// (because the mock object doesn't have any lifetime parameters itself), but
++// unsafely setting such an expectation is a common use case.
++mod return_nonstatic {
++    use super::*;
++
++    #[test]
++    fn inherent_method() {
++        let d = 42u32;
++        let x = X(&d);
++        let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++        let mut mock = MockFoo::new();
++        mock.expect_inherent_method()
++            .returning(move || xstatic.clone());
++
++        assert_eq!(42u32, *mock.inherent_method().0);
++    }
++    #[test]
++    fn trait_method() {
++        let d = 42u32;
++        let x = X(&d);
++        let xstatic: X<'static> = unsafe{ std::mem::transmute(x) };
++        let mut mock = MockFoo::new();
++        mock.expect_trait_method()
++            .returning(move || xstatic.clone());
++
++        assert_eq!(42u32, *mock.trait_method().0);
++    }
++
++}
+diff --git a/tests/mock_return_dyn_trait.rs b/tests/mock_return_dyn_trait.rs
+new file mode 100644
+index 0000000..a22ea60
+--- /dev/null
++++ b/tests/mock_return_dyn_trait.rs
+@@ -0,0 +1,57 @@
++// vim: tw=80
++//! a method that returns a reference to a trait object
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Test: Sync {
++    fn value(&self) -> i32;
++    fn mutate(&mut self);
++}
++
++impl Test for i32 {
++    fn value(&self) -> i32 {
++        *self
++    }
++
++    fn mutate(&mut self) {
++        *self = 0;
++    }
++}
++
++mock! {
++    Foo {
++        fn ref_dyn(&self) -> &dyn Test;
++        fn static_dyn(&self) -> &'static dyn Test;
++        fn mut_dyn(&mut self) -> &mut dyn Test;
++    }
++}
++
++#[test]
++fn ref_dyn() {
++    let mut mock = MockFoo::new();
++    mock.expect_ref_dyn()
++        .return_const(Box::new(42) as Box<dyn Test>);
++
++    assert_eq!(42, mock.ref_dyn().value());
++}
++
++#[test]
++fn static_dyn() {
++    let mut mock = MockFoo::new();
++    mock.expect_static_dyn()
++        .return_const(&42 as &'static dyn Test);
++
++    assert_eq!(42, mock.static_dyn().value());
++}
++
++#[test]
++fn mut_dyn() {
++    let mut mock = MockFoo::new();
++    mock.expect_mut_dyn()
++        .return_var(Box::new(42) as Box<dyn Test>);
++
++    assert_eq!(42, mock.mut_dyn().value());
++    mock.mut_dyn().mutate();
++    assert_eq!(0, mock.mut_dyn().value());
++}
+diff --git a/tests/mock_return_mutable_reference.rs b/tests/mock_return_mutable_reference.rs
+new file mode 100644
+index 0000000..7bc0ed4
+--- /dev/null
++++ b/tests/mock_return_mutable_reference.rs
+@@ -0,0 +1,89 @@
++// vim: tw=80
++//! A struct with a method that returns a mutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn foo(&mut self, i: u32) -> &mut u32;
++    }
++}
++
++#[test]
++#[cfg_attr(not(feature = "nightly"),
++    should_panic(expected = "MockFoo::foo: Expectation(<anything>) Returning default values requires"))]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++fn return_default() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo();
++    let r = mock.foo(0);
++    assert_eq!(u32::default(), *r);
++}
++
++#[test]
++fn return_var() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_var(5u32);
++    {
++        let r = mock.foo(0);
++        assert_eq!(5, *r);
++        *r = 6;
++    }
++    assert_eq!(6, *mock.foo(0));
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|_| 5u32);
++    let r = mock.foo(0);
++    assert_eq!(5, *r);
++}
++
++mod sequence {
++    use super::*;
++
++    #[test]
++    #[should_panic(expected = "MockFoo::foo(4): Method sequence violation")]
++    fn fail() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .with(predicate::eq(3))
++            .times(1)
++            .return_var(0)
++            .in_sequence(&mut seq);
++
++        mock.expect_foo()
++            .with(predicate::eq(4))
++            .times(1)
++            .return_var(0)
++            .in_sequence(&mut seq);
++
++        mock.foo(4);
++    }
++
++    #[test]
++    fn ok() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .with(predicate::eq(3))
++            .times(1)
++            .return_var(0)
++            .in_sequence(&mut seq);
++
++        mock.expect_foo()
++            .with(predicate::eq(4))
++            .times(1)
++            .return_var(0)
++            .in_sequence(&mut seq);
++
++        mock.foo(3);
++        mock.foo(4);
++    }
++
++}
+diff --git a/tests/mock_return_reference.rs b/tests/mock_return_reference.rs
+new file mode 100644
+index 0000000..d3fc71d
+--- /dev/null
++++ b/tests/mock_return_reference.rs
+@@ -0,0 +1,105 @@
++// vim: tw=80
++//! A struct with a method that returns an immutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn foo(&self, x: i32) -> &u32;
++        fn bar(&self) -> &u32;
++    }
++}
++
++mod never {
++    use super::*;
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::bar: Expectation(<anything>) should not have been called")]
++    fn fail() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .return_const(0)
++            .never();
++        mock.bar();
++    }
++
++    #[test]
++    fn ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .never();
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(5u32);
++    assert_eq!(5, *mock.foo(4));
++}
++
++#[test]
++#[cfg_attr(not(feature = "nightly"),
++    should_panic(expected = "MockFoo::foo: Expectation(<anything>) Returning default values requires"))]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++fn return_default() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo();
++    let r = mock.foo(4);
++    assert_eq!(u32::default(), *r);
++}
++
++mod sequence {
++    use super::*;
++
++    #[test]
++    #[should_panic(expected = "exact call count")]
++    fn ambiguous() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .times(1..3)
++            .in_sequence(&mut seq);
++        mock.foo(4);
++    }
++
++    #[test]
++    #[should_panic(expected = "MockFoo::foo(4): Method sequence violation")]
++    fn fail() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .times(1)
++            .return_const(0)
++            .in_sequence(&mut seq);
++
++        mock.expect_foo()
++            .times(1)
++            .return_const(0)
++            .in_sequence(&mut seq);
++
++        mock.foo(4);
++        mock.bar();
++    }
++
++    #[test]
++    fn ok() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .times(1)
++            .return_const(0)
++            .in_sequence(&mut seq);
++
++        mock.expect_bar()
++            .times(1)
++            .return_const(0)
++            .in_sequence(&mut seq);
++
++        mock.foo(4);
++        mock.bar();
++    }
++}
+diff --git a/tests/mock_same_trait_twice_on_generic_struct.rs b/tests/mock_same_trait_twice_on_generic_struct.rs
+new file mode 100644
+index 0000000..51dd88f
+--- /dev/null
++++ b/tests/mock_same_trait_twice_on_generic_struct.rs
+@@ -0,0 +1,32 @@
++// vim: ts=80
++//! Mock the same generic trait twice on a single struct (with different generic
++//! arguments, of course).
++//!
++#![deny(warnings)]
++#![allow(clippy::from_over_into)]
++
++use mockall::*;
++
++mock! {
++    pub Foo<T> {}
++    impl Into<u32> for Foo<u32> {
++        fn into(self) -> u32;
++    }
++    impl Into<i32> for Foo<i32> {
++        fn into(self) -> i32;
++    }
++}
++
++/// Ensure we can set expectations for both methods simultaneously
++#[test]
++fn return_once() {
++    let mut mocku = MockFoo::<u32>::new();
++    mocku.expect_into()
++        .return_once(|| 42);
++    let mut mocki = MockFoo::<i32>::new();
++    mocki.expect_into()
++        .return_once(|| -42);
++
++    assert_eq!(<MockFoo<u32> as Into<u32>>::into(mocku), 42u32);
++    assert_eq!(<MockFoo<i32> as Into<i32>>::into(mocki), -42);
++}
+diff --git a/tests/mock_specializing_methods.rs b/tests/mock_specializing_methods.rs
+new file mode 100644
+index 0000000..f2c0256
+--- /dev/null
++++ b/tests/mock_specializing_methods.rs
+@@ -0,0 +1,34 @@
++// vim: tw=80
++//! A specializing method is a non-generic method of a generic struct that
++//! places additional bounds on the struct's generic types via a where
++//! clause.
++#![deny(warnings)]
++
++use mockall::*;
++
++struct G<T: Copy + Default>(T);
++
++#[derive(Clone, Copy)]
++struct NonDefault{}
++
++mock!{
++    Foo<T> where T: Copy {
++        fn foo(&self, t: T) -> G<T> where T: Default + 'static;
++    }
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::<u32>::default();
++    mock.expect_foo()
++        .returning(G);
++    assert_eq!(42u32, mock.foo(42u32).0);
++
++    // It's possible to instantiate a mock object that doesn't satisfy the
++    // specializing method's requirements:
++    let _mock2 = MockFoo::<NonDefault>::default();
++    // But you can't call the specializing method.  This won't work:
++    // _mock2.expect_foo()
++    //    .returning(|h| G(h));
++    // _mock2.foo(NonDefault{});
++}
+diff --git a/tests/mock_static_method_with_generic_args.rs b/tests/mock_static_method_with_generic_args.rs
+new file mode 100644
+index 0000000..5a8d0fe
+--- /dev/null
++++ b/tests/mock_static_method_with_generic_args.rs
+@@ -0,0 +1,17 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn bar<T: 'static>(x: T);
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = MockFoo::bar_context();
++    ctx.expect::<i16>().returning(|_| ());
++    MockFoo::bar(0i16)
++}
+diff --git a/tests/mock_static_method_with_generic_return.rs b/tests/mock_static_method_with_generic_return.rs
+new file mode 100644
+index 0000000..98c0cae
+--- /dev/null
++++ b/tests/mock_static_method_with_generic_return.rs
+@@ -0,0 +1,18 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn bar<T: 'static>(x: T) -> Vec<T>;
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = MockFoo::bar_context();
++    ctx.expect::<i16>().returning(|x| vec![x]);
++    let v = MockFoo::bar(42i16);
++    assert_eq!(v[0], 42i16);
++}
+diff --git a/tests/mock_static_method_with_lifetime_parameters.rs b/tests/mock_static_method_with_lifetime_parameters.rs
+new file mode 100644
+index 0000000..c71ece5
+--- /dev/null
++++ b/tests/mock_static_method_with_lifetime_parameters.rs
+@@ -0,0 +1,57 @@
++// vim: tw=80
++//! A static generic method whose only generic parameter is a lifetime parameter
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++#[derive(Debug, Eq)]
++struct X<'a>(&'a u32);
++
++impl<'a> PartialEq for X<'a> {
++    fn eq(&self, other: &X<'a>) -> bool {
++        self.0 == other.0
++    }
++}
++
++mock!{
++    Foo {
++        fn foo<'a>(x: &'a X<'a>) -> u32;
++    }
++}
++
++static FOO_MTX: Mutex<()> = Mutex::new(());
++
++#[test]
++fn return_const() {
++    let _m = FOO_MTX.lock().unwrap();
++
++    let ctx = MockFoo::foo_context();
++    ctx.expect()
++        .return_const(42u32);
++    let x = X(&5);
++    assert_eq!(42, MockFoo::foo(&x));
++}
++
++#[test]
++fn returning() {
++    let _m = FOO_MTX.lock().unwrap();
++
++    let ctx = MockFoo::foo_context();
++    ctx.expect()
++        .returning(|f| *f.0);
++    let x = X(&5);
++    assert_eq!(5, MockFoo::foo(&x));
++}
++
++#[test]
++fn withf() {
++    let _m = FOO_MTX.lock().unwrap();
++
++    let ctx = MockFoo::foo_context();
++    ctx.expect()
++        .withf(|f| *f.0 == 5)
++        .return_const(42u32);
++    let x = X(&5);
++    assert_eq!(42, MockFoo::foo(&x));
++}
+diff --git a/tests/mock_static_method_with_reference_arguments.rs b/tests/mock_static_method_with_reference_arguments.rs
+new file mode 100644
+index 0000000..1785ddc
+--- /dev/null
++++ b/tests/mock_static_method_with_reference_arguments.rs
+@@ -0,0 +1,19 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock!{
++    Foo {
++        fn bar(x: &u32) -> u64;
++    }
++}
++
++#[test]
++fn with() {
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .with(predicate::eq(42))
++        .return_const(99u64);
++    assert_eq!(99, MockFoo::bar(&42));
++}
+diff --git a/tests/mock_struct.rs b/tests/mock_struct.rs
+new file mode 100644
+index 0000000..71b91e8
+--- /dev/null
++++ b/tests/mock_struct.rs
+@@ -0,0 +1,461 @@
++// vim: tw=80
++//! Structs can be mocked with mock!  This is useful when the struct's original
++//! definition is not accessible.
++#![deny(warnings)]
++
++use mockall::*;
++
++// A struct with a definition like this:
++// struct Foo {
++//     _x: i16
++// }
++// impl Foo {
++//     fn foo(&self, _x: u32) -> u32 {
++//         42
++//     }
++// }
++// Could be mocked like this:
++mock!{
++    Foo {
++        fn foo(&self, x: u32) -> u32;
++        fn bar(&self, x: u32);
++        fn baz(&self);
++    }
++}
++
++mod checkpoint {
++    use std::panic;
++    use super::*;
++
++    #[test]
++    fn expect_again() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 5)
++            .times(1..3);
++        mock.foo(0);
++        mock.checkpoint();
++
++        mock.expect_foo()
++            .returning(|_| 25);
++        assert_eq!(25, mock.foo(0));
++    }
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::foo: Expectation(<anything>) called 0 time(s) which is fewer than expected 1")]
++    fn not_yet_satisfied() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 42)
++            .times(1);
++        mock.checkpoint();
++        panic!("Shouldn't get here!");
++    }
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::foo: Expectation(<anything>) called 1 time(s) which is more than expected 0")]
++    fn too_many_calls() {
++        let mut mock = MockFoo::default();
++        mock.expect_foo()
++            .returning(|_| 42)
++            .times(0);
++        let _ = panic::catch_unwind(|| {
++            mock.foo(0);
++        });
++        mock.checkpoint();
++        panic!("Shouldn't get here!");
++    }
++
++    #[test]
++    fn ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 5)
++            .times(1..3);
++        mock.foo(0);
++        mock.checkpoint();
++    }
++
++    #[test]
++    #[should_panic(expected = "MockFoo::foo(0): No matching expectation found")]
++    fn removes_old_expectations() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .returning(|_| 42)
++            .times(1..3);
++        mock.foo(0);
++        mock.checkpoint();
++        mock.foo(0);
++        panic!("Shouldn't get here!");
++    }
++}
++
++mod r#match {
++    use super::*;
++
++    /// Unlike Mockers, Mockall calls should use the oldest matching
++    /// expectation, if multiple expectations match
++    #[test]
++    fn fifo_order() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .with(predicate::eq(5))
++            .returning(|_| 99);
++        mock.expect_foo()
++            .with(predicate::always())
++            .returning(|_| 42);
++
++        assert_eq!(99, mock.foo(5));
++    }
++
++    #[test]
++    fn one_match() {
++        let mut mock0 = MockFoo::new();
++        mock0.expect_foo()
++            .with(predicate::eq(5))
++            .returning(|_| 99);
++        mock0.expect_foo()
++            .with(predicate::eq(6))
++            .returning(|_| 42);
++        assert_eq!(42, mock0.foo(6));
++
++        // And in reverse order
++        let mut mock1 = MockFoo::new();
++        mock1.expect_foo()
++            .with(predicate::eq(5))
++            .returning(|_| 99);
++        mock1.expect_foo()
++            .with(predicate::eq(6))
++            .returning(|_| 42);
++        assert_eq!(99, mock0.foo(5));
++    }
++
++    #[test]
++    #[should_panic(expected = "MockFoo::bar(5): No matching expectation found")]
++    fn with_no_matches() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .with(predicate::eq(4))
++            .return_const(());
++        mock.bar(5);
++    }
++
++    #[test]
++    fn with_ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .with(predicate::eq(5))
++            .return_const(());
++        mock.bar(5);
++    }
++
++    #[test]
++    fn withf_ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .withf(|x: &u32| *x == 5)
++            .return_const(());
++        mock.bar(5);
++    }
++
++    #[test]
++    #[should_panic(expected = "MockFoo::bar(5): No matching expectation found")]
++    fn withf_no_matches() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .withf(|x: &u32| *x == 6)
++            .return_const(());
++        mock.bar(5);
++    }
++
++}
++
++mod never {
++    use super::*;
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::bar: Expectation(<anything>) should not have been called")]
++    fn fail() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .returning(|_| ())
++            .never();
++        mock.bar(0);
++    }
++
++    #[test]
++    fn ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .never();
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(42u32);
++    assert_eq!(42, mock.foo(5));
++}
++
++#[cfg_attr(not(feature = "nightly"),
++    should_panic(expected = "MockFoo::foo: Expectation(<anything>) Returning default values requires"))]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++#[test]
++fn return_default() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo();
++    let r = mock.foo(5);
++    assert_eq!(u32::default(), r);
++}
++
++#[test]
++fn returning() {
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .returning(|x| x + 1);
++    assert_eq!(6, mock.foo(5));
++}
++
++mod sequence {
++    use super::*;
++
++    #[test]
++    #[should_panic(expected = "exact call count")]
++    fn ambiguous() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .times(1..3)
++            .in_sequence(&mut seq);
++        mock.baz();
++    }
++
++    #[test]
++    #[should_panic(expected = "MockFoo::baz(): Method sequence violation")]
++    fn fail() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .times(1)
++            .returning(|_| ())
++            .in_sequence(&mut seq);
++
++        mock.expect_baz()
++            .times(1)
++            .returning(|| ())
++            .in_sequence(&mut seq);
++
++        mock.baz();
++        mock.bar(0);
++    }
++
++    #[test]
++    fn ok() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .times(1)
++            .returning(|| ())
++            .in_sequence(&mut seq);
++
++        mock.expect_bar()
++            .times(1)
++            .returning(|_| ())
++            .in_sequence(&mut seq);
++
++        mock.baz();
++        mock.bar(0);
++    }
++
++    /// When adding multiple calls of a single method, with the same arguments,
++    /// to a sequence, expectations should not be called after they are done if
++    /// there are more expectations to follow.
++    #[test]
++    fn single_method() {
++        let mut seq = Sequence::new();
++        let mut mock = MockFoo::new();
++        mock.expect_foo()
++            .times(1)
++            .in_sequence(&mut seq)
++            .returning(|_| 1);
++        mock.expect_foo()
++            .times(1)
++            .in_sequence(&mut seq)
++            .returning(|_| 2);
++        mock.expect_foo()
++            .times(1)
++            .in_sequence(&mut seq)
++            .returning(|_| 3);
++
++        assert_eq!(1, mock.foo(0));
++        assert_eq!(2, mock.foo(0));
++        assert_eq!(3, mock.foo(0));
++    }
++
++}
++
++mod times {
++    use super::*;
++
++    #[test]
++    fn ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|| ())
++            .times(2);
++        mock.baz();
++        mock.baz();
++    }
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::bar: Expectation(var == 5) called 1 time(s) which is fewer than expected 2")]
++    fn too_few() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .with(predicate::eq(5))
++            .returning(|_| ())
++            .times(2);
++        mock.bar(5);
++    }
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::baz: Expectation(<anything>) called 3 times which is more than the expected 2")]
++    fn too_many() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|| ())
++            .times(2);
++        mock.baz();
++        mock.baz();
++        mock.baz();
++        // Verify that we panic quickly and don't reach code below this point.
++        panic!("Shouldn't get here!");
++    }
++
++    #[test]
++    fn range_ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|| ())
++            .times(2..4);
++        mock.baz();
++        mock.baz();
++
++        mock.expect_bar()
++            .returning(|_| ())
++            .times(2..4);
++        mock.bar(0);
++        mock.bar(0);
++        mock.bar(0);
++    }
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::baz: Expectation(<anything>) called 1 time(s) which is fewer than expected 2")]
++    fn range_too_few() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|| ())
++            .times(2..4);
++        mock.baz();
++    }
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::baz: Expectation(<anything>) called 4 times which is more than the expected 3")]
++    fn range_too_many() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|| ())
++            .times(2..4);
++        mock.baz();
++        mock.baz();
++        mock.baz();
++        mock.baz();
++        // Verify that we panic quickly and don't reach code below this point.
++        panic!("Shouldn't get here!");
++    }
++
++    #[test]
++    fn rangeto_ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .returning(|_| ())
++            .times(..4);
++        mock.bar(0);
++        mock.bar(0);
++        mock.bar(0);
++    }
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::baz: Expectation(<anything>) called 4 times which is more than the expected 3")]
++    fn rangeto_too_many() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|| ())
++            .times(..4);
++        mock.baz();
++        mock.baz();
++        mock.baz();
++        mock.baz();
++    }
++
++    #[test]
++    fn rangeinclusive_ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_bar()
++            .returning(|_| ())
++            .times(2..=4);
++        mock.bar(0);
++        mock.bar(0);
++        mock.bar(0);
++        mock.bar(0);
++    }
++
++    #[test]
++    fn rangefrom_ok() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|| ())
++            .times(2..);
++        mock.baz();
++        mock.baz();
++
++        mock.expect_bar()
++            .returning(|_| ())
++            .times(2..);
++        mock.bar(0);
++        mock.bar(0);
++        mock.bar(0);
++    }
++
++    #[test]
++    #[should_panic(expected =
++        "MockFoo::baz: Expectation(<anything>) called 1 time(s) which is fewer than expected 2")]
++    fn rangefrom_too_few() {
++        let mut mock = MockFoo::new();
++        mock.expect_baz()
++            .returning(|| ())
++            .times(2..);
++        mock.baz();
++    }
++}
++
++#[test]
++fn times_full() {
++    let mut mock = MockFoo::new();
++    mock.expect_baz()
++        .returning(|| ())
++        .times(1)
++        .times(..);
++    mock.baz();
++    mock.baz();
++}
+diff --git a/tests/mock_struct_with_static_method.rs b/tests/mock_struct_with_static_method.rs
+new file mode 100644
+index 0000000..ffaebd0
+--- /dev/null
++++ b/tests/mock_struct_with_static_method.rs
+@@ -0,0 +1,103 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++use std::sync::Mutex;
++
++mock!{
++    Foo {
++        fn bar(x: u32) -> u64;
++    }
++}
++
++static BAR_MTX: Mutex<()> = Mutex::new(());
++
++// Checkpointing the mock object should not checkpoint static methods
++#[test]
++fn checkpoint() {
++    let _m = BAR_MTX.lock();
++
++    let mut mock = MockFoo::new();
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .returning(|_| 32)
++        .times(1..3);
++    mock.checkpoint();
++    MockFoo::bar(0);
++}
++
++// It should also be possible to checkpoint just the context object
++#[test]
++#[should_panic(expected =
++    "MockFoo::bar: Expectation(<anything>) called 0 time(s) which is fewer than expected 1")]
++fn ctx_checkpoint() {
++    let _m = BAR_MTX.lock();
++
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .returning(|_| 32)
++        .times(1..3);
++    ctx.checkpoint();
++    panic!("Shouldn't get here!");
++}
++
++// Expectations should be cleared when a context object drops
++#[test]
++#[should_panic(expected = "MockFoo::bar(42): No matching expectation found")]
++fn ctx_hygiene() {
++    let _m = BAR_MTX.lock();
++
++    {
++        let ctx0 = MockFoo::bar_context();
++        ctx0.expect()
++            .returning(|x| u64::from(x + 1));
++    }
++    MockFoo::bar(42);
++}
++
++#[test]
++fn return_const() {
++    let _m = BAR_MTX.lock();
++
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .return_const(42u64);
++    assert_eq!(42, MockFoo::bar(41));
++}
++
++#[cfg_attr(not(feature = "nightly"), ignore)]
++#[cfg_attr(not(feature = "nightly"), allow(unused_must_use))]
++#[test]
++fn return_default() {
++    let _m = BAR_MTX.lock();
++
++    let ctx = MockFoo::bar_context();
++    ctx.expect();
++    let r = MockFoo::bar(5);
++    assert_eq!(u64::default(), r);
++}
++
++#[test]
++fn returning() {
++    let _m = BAR_MTX.lock();
++
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .returning(|x| u64::from(x + 1));
++    assert_eq!(42, MockFoo::bar(41));
++}
++
++#[test]
++fn two_matches() {
++    let _m = BAR_MTX.lock();
++
++    let ctx = MockFoo::bar_context();
++    ctx.expect()
++        .with(predicate::eq(42))
++        .return_const(99u64);
++    ctx.expect()
++        .with(predicate::eq(69))
++        .return_const(101u64);
++    assert_eq!(101, MockFoo::bar(69));
++    assert_eq!(99, MockFoo::bar(42));
++}
+diff --git a/tests/mock_struct_with_trait.rs b/tests/mock_struct_with_trait.rs
+new file mode 100644
+index 0000000..bdf13d4
+--- /dev/null
++++ b/tests/mock_struct_with_trait.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++    fn foo(&self, x: u32) -> i64;
++}
++
++mock!{
++    pub Bar {}
++    impl Foo for Bar {
++        fn foo(&self, x: u32) -> i64;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockBar::new();
++    mock.expect_foo()
++        .return_const(6);
++    assert_eq!(6, mock.foo(5));
++}
++
+diff --git a/tests/mock_struct_with_trait_with_associated_types.rs b/tests/mock_struct_with_trait_with_associated_types.rs
+new file mode 100644
+index 0000000..03a26e5
+--- /dev/null
++++ b/tests/mock_struct_with_trait_with_associated_types.rs
+@@ -0,0 +1,21 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    pub MyIter {}
++    impl Iterator for MyIter {
++        type Item=u32;
++
++        fn next(&mut self) -> Option<u32>;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockMyIter::new();
++    mock.expect_next()
++        .return_const(None);
++    assert!(mock.next().is_none());
++}
+diff --git a/tests/mock_trait_returning_reference.rs b/tests/mock_trait_returning_reference.rs
+new file mode 100644
+index 0000000..746acbd
+--- /dev/null
++++ b/tests/mock_trait_returning_reference.rs
+@@ -0,0 +1,24 @@
++// vim: tw=80
++//! A trait with a method that returns an immutable reference
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Foo {
++    fn foo(&self) -> &u32;
++}
++
++mock! {
++    pub Bar {}
++    impl Foo for Bar {
++        fn foo(&self) -> &u32;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockBar::new();
++    mock.expect_foo()
++        .return_const(5u32);
++    assert_eq!(5, *mock.foo());
++}
+diff --git a/tests/mock_trait_returning_static_reference.rs b/tests/mock_trait_returning_static_reference.rs
+new file mode 100644
+index 0000000..75900d9
+--- /dev/null
++++ b/tests/mock_trait_returning_static_reference.rs
+@@ -0,0 +1,20 @@
++// vim: tw=80
++//! A struct with a method that returns an immutable static reference
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn foo(&self) -> &'static u32;
++    }
++}
++
++#[test]
++fn return_const() {
++    const X: u32 = 5;
++    let mut mock = MockFoo::new();
++    mock.expect_foo()
++        .return_const(&X);
++    assert_eq!(5, *mock.foo());
++}
+diff --git a/tests/mock_trait_with_static_method.rs b/tests/mock_trait_with_static_method.rs
+new file mode 100644
+index 0000000..e0d5b1c
+--- /dev/null
++++ b/tests/mock_trait_with_static_method.rs
+@@ -0,0 +1,23 @@
++// vim: tw=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Bar {
++    fn baz(x: u32) -> u64;
++}
++
++mock!{
++    pub Foo {}
++    impl Bar for Foo {
++        fn baz(x: u32) -> u64;
++    }
++}
++
++#[test]
++fn returning() {
++    let ctx = MockFoo::baz_context();
++    ctx.expect()
++        .returning(|x| u64::from(x + 1));
++    assert_eq!(42, MockFoo::baz(41));
++}
+diff --git a/tests/mock_unsafe_trait.rs b/tests/mock_unsafe_trait.rs
+new file mode 100644
+index 0000000..8368338
+--- /dev/null
++++ b/tests/mock_unsafe_trait.rs
+@@ -0,0 +1,25 @@
++// vim: ts=80
++#![deny(warnings)]
++
++use mockall::*;
++
++#[allow(clippy::missing_safety_doc)]
++pub unsafe trait Bar {
++    fn bar(&self) -> i32;
++}
++
++mock! {
++    pub Foo{}
++    unsafe impl Bar for Foo {
++        fn bar(&self) -> i32;
++    }
++}
++
++#[test]
++fn return_const() {
++    let mut mock = MockFoo::new();
++    mock.expect_bar()
++        .return_const(42);
++
++    assert_eq!(42, mock.bar());
++}
+diff --git a/tests/mock_unsized.rs b/tests/mock_unsized.rs
+new file mode 100644
+index 0000000..5753510
+--- /dev/null
++++ b/tests/mock_unsized.rs
+@@ -0,0 +1,52 @@
++// vim: tw=80
++//! All types of predicate should work for methods with unsized arguments
++#![deny(warnings)]
++
++use mockall::*;
++
++mock! {
++    Foo {
++        fn foo(&self, arg: &str);
++    }
++}
++
++#[test]
++fn with_always() {
++    let mut foo = MockFoo::new();
++    foo.expect_foo()
++        .with(predicate::always())
++        .return_const(());
++
++    foo.foo("xxx");
++}
++
++#[test]
++fn with_eq() {
++    let mut foo = MockFoo::new();
++    foo.expect_foo()
++        .with(predicate::eq("xxx"))
++        .return_const(());
++
++    foo.foo("xxx");
++}
++
++#[test]
++#[should_panic(expected = "MockFoo::foo(\"xxx\"): No matching expectation found")]
++fn with_never() {
++    let mut foo = MockFoo::new();
++    foo.expect_foo()
++        .with(predicate::never())
++        .return_const(());
++
++    foo.foo("xxx");
++}
++
++#[test]
++fn withf() {
++    let mut foo = MockFoo::new();
++    foo.expect_foo()
++        .withf(|a| a == "xxx")
++        .return_const(());
++
++    foo.foo("xxx");
++}
+diff --git a/tests/raw_identifier.rs b/tests/raw_identifier.rs
+new file mode 100644
+index 0000000..2d56e37
+--- /dev/null
++++ b/tests/raw_identifier.rs
+@@ -0,0 +1,72 @@
++// vim: tw=80
++//! It should be possible to mock things that use raw identifiers
++#![deny(warnings)]
++#![allow(non_camel_case_types)]
++
++use mockall::*;
++
++#[automock]
++trait r#while {
++    fn r#match(&self);
++    fn r#loop();
++}
++
++#[automock]
++pub mod r#break {
++    pub fn r#if() {unimplemented!() }
++}
++
++mock! {
++    r#do {}
++    impl r#while for r#do {
++        fn r#match(&self);
++        fn r#loop();
++    }
++}
++
++struct r#else {}
++#[automock]
++impl r#while for r#else {
++    fn r#match(&self) {unimplemented!()}
++    fn r#loop() {unimplemented!()}
++}
++
++#[test]
++fn by_ref() {
++    let mut foo = Mockwhile::new();
++    foo.expect_match()
++        .return_const(());
++    foo.r#match();
++}
++
++#[test]
++fn static_method() {
++    let ctx = Mockwhile::loop_context();
++    ctx.expect()
++        .returning(|| ());
++    Mockwhile::r#loop();
++}
++
++#[test]
++fn manual_mock() {
++    let mut foo = Mockdo::new();
++    foo.expect_match()
++        .return_const(());
++    foo.r#match();
++}
++
++#[test]
++fn module() {
++    let ctx = mock_break::if_context();
++    ctx.expect()
++        .returning(|| ());
++    mock_break::r#if();
++}
++
++#[test]
++fn trait_impl() {
++    let mut mock = Mockelse::new();
++    mock.expect_match()
++        .returning(|| ());
++    mock.r#match();
++}
+diff --git a/tests/specific_impl.rs b/tests/specific_impl.rs
+new file mode 100644
+index 0000000..e16a48e
+--- /dev/null
++++ b/tests/specific_impl.rs
+@@ -0,0 +1,74 @@
++// vim: ts=80
++#![deny(warnings)]
++
++use mockall::*;
++
++trait Bar {
++    fn bar(&self);
++}
++//trait Baz {
++    //fn baz<Y: 'static>(&self, y: Y);
++//}
++
++mock! {
++    pub Foo<T: 'static> {
++    }
++    impl Bar for Foo<u32> {
++        fn bar(&self);
++    }
++    impl Bar for Foo<i32> {
++        fn bar(&self);
++    }
++    // TODO: support specific impls with generic methods, like this
++    //impl Baz for Foo<u32> {
++        //fn baz<Y: 'static>(&self, y: Y);
++    //}
++}
++
++#[test]
++fn specific_impl() {
++    let mut mocku = MockFoo::<u32>::new();
++    mocku.expect_bar()
++        .return_const(());
++    let mut mocki = MockFoo::<i32>::new();
++    mocki.expect_bar()
++        .return_const(());
++
++    mocku.bar();
++    mocki.bar();
++}
++
++///// Make sure generic methods work with specific impls, too
++//#[test]
++//fn withf() {
++    //let mut mocku = MockFoo::<u32>::new();
++    //mocku.expect_baz::<f32>()
++        //.withf(|y| y == 3.14159)
++        //.return_const(());
++    //mocku.baz::<f32>(3.14159);
++//}
++
++// Here's a partially specific impl: Bar is implemented for Bean where one of
++// the generic types is concrete, but the other isn't.
++mock! {
++    pub Bean<X: 'static, Y: 'static> {}
++    impl<Y: 'static> Bar for Bean<u32, Y> {
++        fn bar(&self);
++    }
++    impl<Y: 'static> Bar for Bean<i32, Y> {
++        fn bar(&self);
++    }
++}
++
++#[test]
++fn partially_specific_impl() {
++    let mut mocku = MockBean::<u32, f32>::new();
++    mocku.expect_bar()
++        .return_const(());
++    let mut mocki = MockBean::<i32, f32>::new();
++    mocki.expect_bar()
++        .return_const(());
++
++    mocku.bar();
++    mocki.bar();
++}

base-commit: aec00d246ecc12846560d15eae2c9fc9c6e6cc74
-- 
2.41.0





^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
  2024-03-17 15:59 [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10 Aaron Covrig via Guix-patches via
@ 2024-03-19 10:45 ` Efraim Flashner
  2024-03-20 14:52   ` Aaron Covrig via Guix-patches via
  0 siblings, 1 reply; 4+ messages in thread
From: Efraim Flashner @ 2024-03-19 10:45 UTC (permalink / raw)
  To: Aaron Covrig; +Cc: 69859

[-- Attachment #1: Type: text/plain, Size: 2287 bytes --]

On Sun, Mar 17, 2024 at 11:59:17AM -0400, Aaron Covrig wrote:
> * gnu/packages/crates-io.scm (rust-pcap-1): New variable
> * gnu/packages/crates-io.scm (rust-pcap-0.11): New variable
> * gnu/packages/crates-io.scm (rust-pcap-0.10): New variable
> * gnu/packages/crates-io.scm (rust-gat-std-0.1): New variable
> * gnu/packages/crates-io.scm (rust-gat-std-proc-0.1): New variable
> * gnu/packages/crates-io.scm (rust-etherparse-0.14): New variable
> * gnu/packages/crates-io.scm (rust-etherparse-0.9): New variable
> * gnu/packages/crates-io.scm (rust-eui48-1): New variable
> * gnu/packages/crates-io.scm (rust-tun-tap-0.1): New variable
> * gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch:
>   New file (provides tests and examples rust-mockall)
> * gnu/packages/crates-io.scm (rust-mockall-0.12): New variable
> * gnu/packages/crates-io.scm (rust-mockall-derive-0.12): New variable
> * gnu/packages/crates-io.scm (rust-mockall-0.11): Bumps to 0.11.4
> * gnu/packages/crates-io.scm (rust-mockall-derive-0.11): Bumps to 0.11.4
> * gnu/packages/crates-io.scm (rust-mockall-double-0.3): Bumps to 0.3.1
> * gnu/packages/crates-io.scm (rust-fragile-2): New variable
> * gnu/packages/crates-io.scm (rust-fragile-1): Bumps to 1.2.2
> * gnu/packages/crates-io.scm (rust-slab-0.4): Bumps to 0.4.9
> ---
>  gnu/packages/crates-io.scm                    |  453 +-
>  ...t-mockall-restore-examples-and-tests.patch | 7611 +++++++++++++++++
>  2 files changed, 7976 insertions(+), 88 deletions(-)
>  create mode 100644 gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch

I want to thank you for all your work on these patches and on the other
ones too. Unfortunately with some of these ones I had already done a
bunch of them on the rust-team branch which I've finally pushed back
upstream.

Also, in order to keep with the standard practices of Guix each commit
should only have 1 change at a time, in this case adding or updating a
package. If you can split them into individual patches I'll be happy to
apply them.

-- 
Efraim Flashner   <efraim@flashner.co.il>   רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
  2024-03-19 10:45 ` Efraim Flashner
@ 2024-03-20 14:52   ` Aaron Covrig via Guix-patches via
  2024-03-25  7:17     ` Efraim Flashner
  0 siblings, 1 reply; 4+ messages in thread
From: Aaron Covrig via Guix-patches via @ 2024-03-20 14:52 UTC (permalink / raw)
  To: Efraim Flashner; +Cc: 69859

[-- Attachment #1: Type: text/plain, Size: 2710 bytes --]

On Tue, 19 Mar 2024 12:45:55 +0200
Efraim Flashner <efraim@flashner.co.il> wrote:

> On Sun, Mar 17, 2024 at 11:59:17AM -0400, Aaron Covrig wrote:
> > * gnu/packages/crates-io.scm (rust-pcap-1): New variable
> > * gnu/packages/crates-io.scm (rust-pcap-0.11): New variable
> > * gnu/packages/crates-io.scm (rust-pcap-0.10): New variable
> > * gnu/packages/crates-io.scm (rust-gat-std-0.1): New variable
> > * gnu/packages/crates-io.scm (rust-gat-std-proc-0.1): New variable
> > * gnu/packages/crates-io.scm (rust-etherparse-0.14): New variable
> > * gnu/packages/crates-io.scm (rust-etherparse-0.9): New variable
> > * gnu/packages/crates-io.scm (rust-eui48-1): New variable
> > * gnu/packages/crates-io.scm (rust-tun-tap-0.1): New variable
> > *
> > gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch:
> > New file (provides tests and examples rust-mockall)
> > * gnu/packages/crates-io.scm (rust-mockall-0.12): New variable
> > * gnu/packages/crates-io.scm (rust-mockall-derive-0.12): New
> > variable
> > * gnu/packages/crates-io.scm (rust-mockall-0.11): Bumps to 0.11.4
> > * gnu/packages/crates-io.scm (rust-mockall-derive-0.11): Bumps to
> > 0.11.4
> > * gnu/packages/crates-io.scm (rust-mockall-double-0.3): Bumps to
> > 0.3.1
> > * gnu/packages/crates-io.scm (rust-fragile-2): New variable
> > * gnu/packages/crates-io.scm (rust-fragile-1): Bumps to 1.2.2
> > * gnu/packages/crates-io.scm (rust-slab-0.4): Bumps to 0.4.9
> > ---
> >  gnu/packages/crates-io.scm                    |  453 +-
> >  ...t-mockall-restore-examples-and-tests.patch | 7611
> > +++++++++++++++++ 2 files changed, 7976 insertions(+), 88
> > deletions(-) create mode 100644
> > gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
> 
> I want to thank you for all your work on these patches and on the
> other ones too. Unfortunately with some of these ones I had already
> done a bunch of them on the rust-team branch which I've finally
> pushed back upstream.
> 
> Also, in order to keep with the standard practices of Guix each commit
> should only have 1 change at a time, in this case adding or updating a
> package. If you can split them into individual patches I'll be happy
> to apply them.
> 

Ok, I can rebase and resubmit them; when you say each should be a
separate commit, should I update a single package per
issue (and open a new issue for each package in this commit (and does
this apply to subversions (an issue for both fragile-1 and fragile-2 or
just one for fragile-*)) or should I resubmit this (and the others) as
a patch series where each commit is one package (but they are all under
a single issue)?

v/r,

Aaron Covrig

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
  2024-03-20 14:52   ` Aaron Covrig via Guix-patches via
@ 2024-03-25  7:17     ` Efraim Flashner
  0 siblings, 0 replies; 4+ messages in thread
From: Efraim Flashner @ 2024-03-25  7:17 UTC (permalink / raw)
  To: Aaron Covrig; +Cc: 69859

[-- Attachment #1: Type: text/plain, Size: 3179 bytes --]

On Wed, Mar 20, 2024 at 10:52:38AM -0400, Aaron Covrig wrote:
> On Tue, 19 Mar 2024 12:45:55 +0200
> Efraim Flashner <efraim@flashner.co.il> wrote:
> 
> > On Sun, Mar 17, 2024 at 11:59:17AM -0400, Aaron Covrig wrote:
> > > * gnu/packages/crates-io.scm (rust-pcap-1): New variable
> > > * gnu/packages/crates-io.scm (rust-pcap-0.11): New variable
> > > * gnu/packages/crates-io.scm (rust-pcap-0.10): New variable
> > > * gnu/packages/crates-io.scm (rust-gat-std-0.1): New variable
> > > * gnu/packages/crates-io.scm (rust-gat-std-proc-0.1): New variable
> > > * gnu/packages/crates-io.scm (rust-etherparse-0.14): New variable
> > > * gnu/packages/crates-io.scm (rust-etherparse-0.9): New variable
> > > * gnu/packages/crates-io.scm (rust-eui48-1): New variable
> > > * gnu/packages/crates-io.scm (rust-tun-tap-0.1): New variable
> > > *
> > > gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch:
> > > New file (provides tests and examples rust-mockall)
> > > * gnu/packages/crates-io.scm (rust-mockall-0.12): New variable
> > > * gnu/packages/crates-io.scm (rust-mockall-derive-0.12): New
> > > variable
> > > * gnu/packages/crates-io.scm (rust-mockall-0.11): Bumps to 0.11.4
> > > * gnu/packages/crates-io.scm (rust-mockall-derive-0.11): Bumps to
> > > 0.11.4
> > > * gnu/packages/crates-io.scm (rust-mockall-double-0.3): Bumps to
> > > 0.3.1
> > > * gnu/packages/crates-io.scm (rust-fragile-2): New variable
> > > * gnu/packages/crates-io.scm (rust-fragile-1): Bumps to 1.2.2
> > > * gnu/packages/crates-io.scm (rust-slab-0.4): Bumps to 0.4.9
> > > ---
> > >  gnu/packages/crates-io.scm                    |  453 +-
> > >  ...t-mockall-restore-examples-and-tests.patch | 7611
> > > +++++++++++++++++ 2 files changed, 7976 insertions(+), 88
> > > deletions(-) create mode 100644
> > > gnu/packages/patches/rust-mockall-restore-examples-and-tests.patch
> > 
> > I want to thank you for all your work on these patches and on the
> > other ones too. Unfortunately with some of these ones I had already
> > done a bunch of them on the rust-team branch which I've finally
> > pushed back upstream.
> > 
> > Also, in order to keep with the standard practices of Guix each commit
> > should only have 1 change at a time, in this case adding or updating a
> > package. If you can split them into individual patches I'll be happy
> > to apply them.
> > 
> 
> Ok, I can rebase and resubmit them; when you say each should be a
> separate commit, should I update a single package per
> issue (and open a new issue for each package in this commit (and does
> this apply to subversions (an issue for both fragile-1 and fragile-2 or
> just one for fragile-*)) or should I resubmit this (and the others) as
> a patch series where each commit is one package (but they are all under
> a single issue)?

Sorry, I meant to respond earlier.

The way you have the patches broken up in v3 of bug#69620 is perfect.


-- 
Efraim Flashner   <efraim@flashner.co.il>   רנשלפ םירפא
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-03-25  7:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-17 15:59 [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10 Aaron Covrig via Guix-patches via
2024-03-19 10:45 ` Efraim Flashner
2024-03-20 14:52   ` Aaron Covrig via Guix-patches via
2024-03-25  7:17     ` Efraim Flashner

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).