From bc3faf208ebb5ac1dfb1b995be088554e6766430 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sat, 2 Nov 2019 11:46:11 -0600 Subject: [PATCH] Fix hygiene violations in some warnings Pull request #37 added some must_use warnings conditionalized on the "nightly" feature. However, because proc macros are unhygienic, the warnings were actually conditionalized on the instantiating crate's nightly feature, not on mockall_derive's nightly feature. I didn't notice at the time because Mockall _also_ has a nightly feature, and so does the only crate of mine that uses Mockall. Fix the hygiene errors, and rename mockall_derive's feature to "nightly_derive", which will help to catch similar errors in the future. --- CHANGELOG.md | 3 +++ mockall/Cargo.toml | 2 +- mockall_derive/Cargo.toml | 4 ++- mockall_derive/src/expectation.rs | 41 ++++++++++++++++++++----------- mockall_derive/src/lib.rs | 4 +-- mockall_derive/src/mock.rs | 12 ++++++--- 6 files changed, 44 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcf15671..c6aca94c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed ### Fixed +- Fixed hygiene violations in some of mockall_derive's warnings. + ([#63](https://github.com/asomers/mockall/pull/63)) + - Fixed using super:: in the signature of a bare function ([#54](https://github.com/asomers/mockall/pull/54)) diff --git a/mockall/Cargo.toml b/mockall/Cargo.toml index aa7649af..0996e9c8 100644 --- a/mockall/Cargo.toml +++ b/mockall/Cargo.toml @@ -18,7 +18,7 @@ features = ["nightly"] [features] # Extra features for the nightly compiler only -nightly = ["mockall_derive/nightly"] +nightly = ["mockall_derive/nightly_derive"] [dependencies] cfg-if = "0.1.6" diff --git a/mockall_derive/Cargo.toml b/mockall_derive/Cargo.toml index f07a4cf6..0328d023 100644 --- a/mockall_derive/Cargo.toml +++ b/mockall_derive/Cargo.toml @@ -20,7 +20,9 @@ proc-macro = true [features] # Extra features for the nightly compiler only -nightly = ["proc-macro2/nightly"] +# Must have a different name than the corresponding feature in mockall in order +# to catch hygiene violations. +nightly_derive = ["proc-macro2/nightly"] # For building documentation only; no functional change to the library. extra-docs = [] diff --git a/mockall_derive/src/expectation.rs b/mockall_derive/src/expectation.rs index 93368495..ddbcb82c 100644 --- a/mockall_derive/src/expectation.rs +++ b/mockall_derive/src/expectation.rs @@ -1051,6 +1051,13 @@ impl<'a> StaticExpectation<'a> { ) }; + #[cfg(not(feature = "nightly_derive"))] + let must_use = quote!(#[must_use = + "Must set return value when not using the \"nightly\" feature" + ]); + #[cfg(feature = "nightly_derive")] + let must_use = quote!(); + let context_ts = quote!( /// Manages the context for expectations of static methods. /// @@ -1083,9 +1090,7 @@ impl<'a> StaticExpectation<'a> { } /// Create a new expectation for this method. - #[cfg_attr(not(feature = "nightly"), must_use = - "Must set return value when not using the \"nightly\" feature") - ] + #must_use #v fn expect #meth_ig ( &self,) -> ExpectationGuard #e_tg #meth_wc { @@ -1588,6 +1593,14 @@ impl<'a> RefExpectation<'a> { let (ig, tg, wc) = self.common.egenerics.split_for_impl(); let lg = &self.common.elifetimes; let output = &self.common.output; + + #[cfg(not(feature = "nightly_derive"))] + let default_err_msg = + "Returning default values requires the \"nightly\" feature"; + #[cfg(feature = "nightly_derive")] + let default_err_msg = + "Can only return default values for types that impl std::Default"; + quote!( enum Rfunc #ig #wc { Default(Option<#output>), @@ -1604,13 +1617,8 @@ impl<'a> RefExpectation<'a> { Rfunc::Default(Some(ref __mockall_o)) => { Ok(__mockall_o) }, - #[cfg(feature = "nightly")] - Rfunc::Default(None) => { - Err("Can only return default values for types that impl std::Default") - }, - #[cfg(not(feature = "nightly"))] Rfunc::Default(None) => { - Err("Returning default values requires the \"nightly\" feature") + Err(#default_err_msg) }, Rfunc::Const(ref __mockall_o) => { Ok(__mockall_o) @@ -1809,6 +1817,14 @@ impl<'a> RefMutExpectation<'a> { let (ig, tg, wc) = self.common.egenerics.split_for_impl(); let lg = &self.common.elifetimes; let output = &self.common.output; + + #[cfg(not(feature = "nightly_derive"))] + let default_err_msg = + "Returning default values requires the \"nightly\" feature"; + #[cfg(feature = "nightly_derive")] + let default_err_msg = + "Can only return default values for types that impl std::Default"; + quote!( enum Rfunc #ig #wc { Default(Option<#output>), @@ -1834,13 +1850,8 @@ impl<'a> RefMutExpectation<'a> { Rfunc::Default(Some(ref mut __mockall_o)) => { Ok(__mockall_o) }, - #[cfg(feature = "nightly")] - Rfunc::Default(None) => { - Err("Can only return default values for types that impl std::Default") - }, - #[cfg(not(feature = "nightly"))] Rfunc::Default(None) => { - Err("Returning default values requires the \"nightly\" feature") + Err(#default_err_msg) }, Rfunc::Mut(ref mut __mockall_f, ref mut __mockall_o) => { diff --git a/mockall_derive/src/lib.rs b/mockall_derive/src/lib.rs index 10c86226..aeb8ae6a 100644 --- a/mockall_derive/src/lib.rs +++ b/mockall_derive/src/lib.rs @@ -5,7 +5,7 @@ //! its reexports via the [`mockall`](https://docs.rs/mockall/latest/mockall) //! crate. -#![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic))] +#![cfg_attr(feature = "nightly_derive", feature(proc_macro_diagnostic))] extern crate proc_macro; use cfg_if::cfg_if; @@ -62,7 +62,7 @@ cfg_if! { // proc-macro2's Span::unstable method requires the nightly feature, and it // doesn't work in test mode. // https://github.com/alexcrichton/proc-macro2/issues/159 - if #[cfg(all(feature = "nightly", not(test)))] { + if #[cfg(all(feature = "nightly_derive", not(test)))] { fn compile_error(span: Span, msg: &'static str) { span.unstable() .error(msg) diff --git a/mockall_derive/src/mock.rs b/mockall_derive/src/mock.rs index 50409c81..4ae57a52 100644 --- a/mockall_derive/src/mock.rs +++ b/mockall_derive/src/mock.rs @@ -314,10 +314,16 @@ fn gen_mock_method(mock_struct_name: &syn::Ident, #[cfg(any(test, not(feature = "extra-docs")))] let docstr: Option = None; let expect_ident = format_ident!("expect_{}", ident); + + #[cfg(not(feature = "nightly_derive"))] + let must_use = quote!(#[must_use = + "Must set return value when not using the \"nightly\" feature" + ]); + #[cfg(feature = "nightly_derive")] + let must_use = quote!(); + quote!( - #[cfg_attr(not(feature = "nightly"), must_use = - "Must set return value when not using the \"nightly\" feature") - ] + #must_use #attrs #docstr #expect_vis fn #expect_ident #ig(&mut self) -> &mut #mod_ident::#expectation #wc