GNU bug report logs - #69859
[PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10

Previous Next

Package: guix-patches;

Reported by: Aaron Covrig <aaron.covrig.us <at> ieee.org>

Date: Sun, 17 Mar 2024 16:04:02 UTC

Severity: normal

Tags: patch

To reply to this bug, email your comments to 69859 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to efraim <at> flashner.co.il, guix-patches <at> gnu.org:
bug#69859; Package guix-patches. (Sun, 17 Mar 2024 16:04:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Aaron Covrig <aaron.covrig.us <at> ieee.org>:
New bug report received and forwarded. Copy sent to efraim <at> flashner.co.il, guix-patches <at> gnu.org. (Sun, 17 Mar 2024 16:04:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Aaron Covrig <aaron.covrig.us <at> ieee.org>
To: guix-patches <at> gnu.org
Cc: Aaron Covrig <aaron.covrig.us <at> ieee.org>
Subject: [PATCH rust-team] gnu: Adds rust-pcap version 1.3, 0.11, and 0.10
Date: Sun, 17 Mar 2024 11:59:17 -0400
* 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





Information forwarded to guix-patches <at> gnu.org:
bug#69859; Package guix-patches. (Tue, 19 Mar 2024 10:48:01 GMT) Full text and rfc822 format available.

Message #8 received at 69859 <at> debbugs.gnu.org (full text, mbox):

From: Efraim Flashner <efraim <at> flashner.co.il>
To: Aaron Covrig <aaron.covrig.us <at> ieee.org>
Cc: 69859 <at> debbugs.gnu.org
Subject: Re: [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3,
 0.11, and 0.10
Date: Tue, 19 Mar 2024 12:45:55 +0200
[Message part 1 (text/plain, inline)]
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 <at> 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
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#69859; Package guix-patches. (Wed, 20 Mar 2024 14:55:02 GMT) Full text and rfc822 format available.

Message #11 received at 69859 <at> debbugs.gnu.org (full text, mbox):

From: Aaron Covrig <aaron.covrig.us <at> ieee.org>
To: Efraim Flashner <efraim <at> flashner.co.il>
Cc: 69859 <at> debbugs.gnu.org
Subject: Re: [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3,
 0.11, and 0.10
Date: Wed, 20 Mar 2024 10:52:38 -0400
[Message part 1 (text/plain, inline)]
On Tue, 19 Mar 2024 12:45:55 +0200
Efraim Flashner <efraim <at> 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
[Message part 2 (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#69859; Package guix-patches. (Mon, 25 Mar 2024 07:20:02 GMT) Full text and rfc822 format available.

Message #14 received at 69859 <at> debbugs.gnu.org (full text, mbox):

From: Efraim Flashner <efraim <at> flashner.co.il>
To: Aaron Covrig <aaron.covrig.us <at> ieee.org>
Cc: 69859 <at> debbugs.gnu.org
Subject: Re: [bug#69859] [PATCH rust-team] gnu: Adds rust-pcap version 1.3,
 0.11, and 0.10
Date: Mon, 25 Mar 2024 09:17:15 +0200
[Message part 1 (text/plain, inline)]
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 <at> 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 <at> 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
[signature.asc (application/pgp-signature, inline)]

This bug report was last modified 39 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.