ernie-research/MEnvData-SWE huggingface dataset:
Repository: google/argh (Rust)

Issue:
Unrecognized argument on raw identifier
## Demo

```rs
use argh::FromArgs;

/// An example CLI application
#[derive(FromArgs)]
struct Example {
    /// the type (as a usize) to be used
    #[argh(option)]
    r#type: usize,
}

fn main() {
    let _up: Example = argh::from_env();
}
```
then folllowing `cargo run -- --type 1` the output is:
```
warning: field is never read: `type`
 --> src/main.rs:8:5
  |
8 |     r#type: usize,
  |     ^^^^^^^^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

warning: `arghtest` (bin "arghtest") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.33s
     Running `target/debug/arghtest --type 1`
Unrecognized argument: --type
```


Discussion:

Patch:
diff --git a/argh_derive/src/lib.rs b/argh_derive/src/lib.rs
index 8b3b7ee..db5cf9a 100644
--- a/argh_derive/src/lib.rs
+++ b/argh_derive/src/lib.rs
@@ -3,6 +3,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+use syn::ext::IdentExt as _;
+
 /// Implementation of the `FromArgs` and `argh(...)` derive attributes.
 ///
 /// For more thorough documentation, see the `argh` crate itself.
@@ -188,7 +190,7 @@ impl<'a> StructField<'a> {
         let long_name = match kind {
             FieldKind::Switch | FieldKind::Option => {
                 let long_name = attrs.long.as_ref().map(syn::LitStr::value).unwrap_or_else(|| {
-                    let kebab_name = to_kebab_case(&name.to_string());
+                    let kebab_name = to_kebab_case(&name.unraw().to_string());
                     check_long_name(errors, name, &kebab_name);
                     kebab_name
                 });


Test patch:
diff --git a/argh/tests/lib.rs b/argh/tests/lib.rs
index dbd3b48..78c6afa 100644
--- a/argh/tests/lib.rs
+++ b/argh/tests/lib.rs
@@ -317,6 +317,20 @@ fn explicit_long_value_for_option() {
     assert_eq!(cmd.x, 5);
 }
 
+#[test]
+fn raw_identifier() {
+    #[derive(FromArgs, Debug)]
+    /// Short description
+    struct Cmd {
+        #[argh(switch)]
+        /// whether to move the file
+        r#move: bool,
+    }
+
+    let cmd = Cmd::from_args(&["cmdname"], &["--move"]).unwrap();
+    assert!(cmd.r#move);
+}
+
 /// Test that descriptions can start with an initialism despite
 /// usually being required to start with a lowercase letter.
 #[derive(FromArgs)]
Repository: TedDriggs/darling (Rust)

Issue:
Field-level default should take path without quotation marks
The [`DefaultExpression`](https://github.com/TedDriggs/darling/blob/master/core/src/options/mod.rs#L35) type was never updated to accept a path in the right-hand side. This means that `#[darling(default = path_to_fn)]` doesn't work, while `#[darling(default = "path_to_fn")]` does. We should allow the quotation-free form.


Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 359f98b1..27b36f71 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## Unreleased
+
+- Accept bare paths in `#[darling(default = ...)]` [#258](https://github.com/TedDriggs/darling/pull/258)
+
 ## v0.20.3 (July 12, 2023)
 
 - Add `FromMeta` impl for `u128` and `i128` [#243](https://github.com/TedDriggs/darling/pull/243)
diff --git a/core/src/options/mod.rs b/core/src/options/mod.rs
index 066aa1c1..164d21f6 100644
--- a/core/src/options/mod.rs
+++ b/core/src/options/mod.rs
@@ -55,6 +55,10 @@ impl FromMeta for DefaultExpression {
         }
     }
 
+    fn from_expr(expr: &syn::Expr) -> Result<Self> {
+        syn::Path::from_expr(expr).map(DefaultExpression::Explicit)
+    }
+
     fn from_value(value: &syn::Lit) -> Result<Self> {
         syn::Path::from_value(value).map(DefaultExpression::Explicit)
     }


Test patch:
diff --git a/tests/defaults.rs b/tests/defaults.rs
index 05ab1ed1..b74c7451 100644
--- a/tests/defaults.rs
+++ b/tests/defaults.rs
@@ -12,7 +12,7 @@ mod foo {
 #[derive(FromDeriveInput)]
 #[darling(attributes(speak))]
 pub struct SpeakerOpts {
-    #[darling(default = "foo::bar::init")]
+    #[darling(default = foo::bar::init)]
     first_word: String,
 }
Repository: kivikakk/comrak (Rust)

Issue:
Comrak round-trip introduces extraneous space in code fence info string
**Description**

When comrak is used to parse, and then re-render, a Markdown file (i.e. a round-trip), any code fences in the input are modified such that, on the re-render, each of their info strings will contain an extra leading space space.

Example input:

````markdown
```lua some_more_info
print("hello world")
```
````

Expected output:

````markdown
```lua some_more_info
print("hello world")
```
````

Actual output:

````markdown
``` lua some_more_info
print("hello world")
```
````

**Steps to reproduce**

Clone this [test repo](https://github.com/LeonBaram/comrak-code-fence-info-string-issue#) and run `cargo test`.

Please let me know if further information is required, or if I missed something in the docs. Cheers!


Discussion:
True! There's no particular reason for Comrak to do this, other than that the [reference `cmark` implementation](https://github.com/commonmark/cmark/blob/fe8691301ebccd38995f1c4e3acdeacb5688aa6f/src/commonmark.c#L289) does this. It's nicer not to, though, isn't it? Fix will be forthcoming in the next Comrak release.
Thanks for the report!
Thank you! :D
This was released in Comrak [v0.48.0](https://github.com/kivikakk/comrak/releases/tag/v0.48.0)!



Patch:
diff --git a/src/cm.rs b/src/cm.rs
index f41a1667..25532370 100644
--- a/src/cm.rs
+++ b/src/cm.rs
@@ -694,7 +694,6 @@ impl<'a, 'o, 'c, 'w> CommonMarkFormatter<'a, 'o, 'c, 'w> {
                 write!(self, "{}", fence_byte as char)?;
             }
             if !info.is_empty() {
-                write!(self, " ")?;
                 self.write_str(&ncb.info)?;
             }
             self.cr();


Test patch:
diff --git a/src/tests/commonmark.rs b/src/tests/commonmark.rs
index c2e13623..3018f374 100644
--- a/src/tests/commonmark.rs
+++ b/src/tests/commonmark.rs
@@ -58,7 +58,7 @@ fn commonmark_renders_single_list_item() {
 
 #[test_case("$$x^2$$ and $1 + 2$ and $`y^2`$", "$$x^2$$ and $1 + 2$ and $`y^2`$\n")]
 #[test_case("$$\nx^2\n$$", "$$\nx^2\n$$\n")]
-#[test_case("```math\nx^2\n```", "``` math\nx^2\n```\n")]
+#[test_case("```math\nx^2\n```", "```math\nx^2\n```\n")]
 fn commonmark_math(markdown: &str, cm: &str) {
     let mut options = Options::default();
     options.extension.math_dollars = true;
Repository: dtolnay/thiserror (Rust)

Issue:
Accept top level #[error(...)] attribute on enums to apply to all variants
```rust
use thiserror::Error;

#[derive(Error, Debug)]
#[error("{0}")]
pub enum Error {
    Io(io::Error),
    Json(serde_json::Error),
    Regex(regex::Error),
}
```

^ this should be treated as equivalent to:

```rust
#[derive(Error, Debug)]
pub enum Error {
    #[error("{0}")]
    Io(io::Error),
    #[error("{0}")]
    Json(serde_json::Error),
    #[error("{0}")]
    Regex(regex::Error),
}
```


Discussion:
This works, but what if I want to customize one of the variants?



Patch:
diff --git a/impl/src/ast.rs b/impl/src/ast.rs
index f68820ea..bc4e90a4 100644
--- a/impl/src/ast.rs
+++ b/impl/src/ast.rs
@@ -63,15 +63,23 @@ impl<'a> Struct<'a> {
 
 impl<'a> Enum<'a> {
     fn from_syn(node: &'a DeriveInput, data: &'a DataEnum) -> Result<Self> {
+        let attrs = attr::get(&node.attrs)?;
+        let variants = data
+            .variants
+            .iter()
+            .map(|node| {
+                let mut variant = Variant::from_syn(node)?;
+                if let display @ None = &mut variant.attrs.display {
+                    *display = attrs.display.clone();
+                }
+                Ok(variant)
+            })
+            .collect::<Result<_>>()?;
         Ok(Enum {
-            attrs: attr::get(&node.attrs)?,
+            attrs,
             ident: node.ident.clone(),
             generics: &node.generics,
-            variants: data
-                .variants
-                .iter()
-                .map(Variant::from_syn)
-                .collect::<Result<_>>()?,
+            variants,
         })
     }
 }
diff --git a/impl/src/attr.rs b/impl/src/attr.rs
index e741c64b..93e95dd0 100644
--- a/impl/src/attr.rs
+++ b/impl/src/attr.rs
@@ -12,6 +12,7 @@ pub struct Attrs<'a> {
     pub source: Option<Source<'a>>,
 }
 
+#[derive(Clone)]
 pub struct Display {
     pub fmt: LitStr,
     pub args: TokenStream,


Test patch:
diff --git a/tests/test_display.rs b/tests/test_display.rs
index c7bb8577..50a59e24 100644
--- a/tests/test_display.rs
+++ b/tests/test_display.rs
@@ -31,6 +31,14 @@ enum EnumError {
     Unit,
 }
 
+#[derive(Error, Debug)]
+#[error("{0}")]
+enum Inherit {
+    Unit(UnitError),
+    #[error("other error")]
+    Other(UnitError),
+}
+
 #[derive(Error, Debug)]
 #[error("1 + 1 = {}", 1 + 1)]
 struct Arithmetic;
@@ -57,6 +65,8 @@ fn test_display() {
     assert("braced error: 0", EnumError::Braced { id: 0 });
     assert("tuple error: 0", EnumError::Tuple(0));
     assert("unit error", EnumError::Unit);
+    assert("unit error", Inherit::Unit(UnitError));
+    assert("other error", Inherit::Other(UnitError));
     assert("1 + 1 = 2", Arithmetic);
     assert("!bool = false", NestedShorthand(true));
 }
Repository: dtolnay/async-trait (Rust)

Issue:
Using async-trait with nightly-2024-03-04 triggers `unused-qualifications` lint
Consider the following code:

```rust
use async_trait::async_trait;  // async-trait = "0.1.77"

#[async_trait]
pub trait Foo {
    async fn foo(&self);
}

pub struct Bar;

#[async_trait]
impl Foo for Bar {
    async fn foo(&self) {
        todo!()
    }
}
```

with the following in `Cargo.toml`:

```toml
[lints.rust]
unused_qualifications = "deny"
```

Using the current nightly channel (d18480b84 2024-03-04), running `cargo +nightly check` on the above fails with:

```text
error: unnecessary qualification
 --> src/lib.rs:5:5
  |
5 |     async fn foo(&self);
  |     ^^^^^
  |
  = note: requested on the command line with `-D unused-qualifications`
help: remove the unnecessary path segments
  |
5 |     async fn foo(&self);
  |

error: unnecessary qualification
  --> src/lib.rs:12:5
   |
12 |     async fn foo(&self) {
   |     ^^^^^
   |
help: remove the unnecessary path segments
   |
12 |     async fn foo(&self) {
   |

error: could not compile `unused-qual` (lib) due to 2 previous errors
```


Discussion:

Patch:
diff --git a/src/expand.rs b/src/expand.rs
index 2a8b3c2..cbef6f2 100644
--- a/src/expand.rs
+++ b/src/expand.rs
@@ -125,6 +125,7 @@ pub fn expand(input: &mut Item, is_local: bool) {
 fn lint_suppress_with_body() -> Attribute {
     parse_quote! {
         #[allow(
+            unused_qualifications,
             clippy::async_yields_async,
             clippy::diverging_sub_expression,
             clippy::let_unit_value,
@@ -140,6 +141,7 @@ fn lint_suppress_with_body() -> Attribute {
 fn lint_suppress_without_body() -> Attribute {
     parse_quote! {
         #[allow(
+            unused_qualifications,
             clippy::type_complexity,
             clippy::type_repetition_in_bounds
         )]


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index cbd8e03..4b01bad 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -2,7 +2,7 @@
     async_trait_nightly_testing,
     feature(impl_trait_in_assoc_type, min_specialization)
 )]
-#![deny(rust_2021_compatibility)]
+#![deny(rust_2021_compatibility, unused_qualifications)]
 #![allow(
     clippy::incompatible_msrv, // https://github.com/rust-lang/rust-clippy/issues/12257
     clippy::let_underscore_untyped,
@@ -1384,6 +1384,7 @@ pub mod issue169 {
     use async_trait::async_trait;
 
     #[async_trait]
+    #[allow(unused_qualifications)]
     pub trait Trait: ::core::marker::Sync {
         async fn f(&self) {}
     }
Repository: sharksforarms/deku (Rust)

Issue:
Support unit structure `struct S;` in derive-macro `DekuWrite`
We should support unit structure `struct S;` since `struct S {}` and `struct S();` are allowed to derive `DekuWrite`.
```rust
#[derive(DekuWrite)] // error: expected tuple struct or tuple variant, found unit struct `Zero`
#[deku(magic = b"\x00")]
struct Zero;
```
And `DekuRead` is no error here.


Discussion:
https://github.com/sharksforarms/deku/pull/450 should fix this.



Patch:
diff --git a/deku-derive/src/macros/deku_write.rs b/deku-derive/src/macros/deku_write.rs
index 3f3b90fe..871d1623 100644
--- a/deku-derive/src/macros/deku_write.rs
+++ b/deku-derive/src/macros/deku_write.rs
@@ -34,6 +34,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
     let field_updates = emit_field_updates(&fields, Some(quote! { self. }));
 
     let named = fields.style.is_struct();
+    let unit = fields.style.is_unit();
 
     let field_idents = fields.iter().enumerate().filter_map(|(i, f)| {
         if !f.temp {
@@ -43,7 +44,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
         }
     });
 
-    let destructured = gen_struct_destruction(named, &input.ident, field_idents);
+    let destructured = gen_struct_destruction(named, unit, &input.ident, field_idents);
 
     // Implement `DekuContainerWrite` for types that don't need a context
     if input.ctx.is_none() || (input.ctx.is_some() && input.ctx_default.is_some()) {
diff --git a/deku-derive/src/macros/mod.rs b/deku-derive/src/macros/mod.rs
index 8853dc45..847db153 100644
--- a/deku-derive/src/macros/mod.rs
+++ b/deku-derive/src/macros/mod.rs
@@ -95,10 +95,15 @@ fn gen_struct_init<I: ToTokens>(
 /// - Unnamed: `#ident ( ref fields )`
 fn gen_struct_destruction<I: ToTokens, F: ToTokens>(
     named: bool,
+    unit: bool,
     ident: I,
     field_idents: impl Iterator<Item = F>,
 ) -> TokenStream {
-    if named {
+    if unit {
+        quote! {
+            #ident
+        }
+    } else if named {
         quote! {
             #ident {
                 #(ref #field_idents),*


Test patch:
diff --git a/tests/test_struct.rs b/tests/test_struct.rs
index 41e3b3d4..c5bb117b 100644
--- a/tests/test_struct.rs
+++ b/tests/test_struct.rs
@@ -204,3 +204,19 @@ fn test_big_endian() {
     let new_bytes = a.to_bytes().unwrap();
     assert_eq!(&bytes[..2], &*new_bytes);
 }
+
+#[test]
+fn test_units() {
+    #[derive(DekuRead, DekuWrite)]
+    #[deku(magic = b"\xf0")]
+    struct Unit;
+
+    let bytes = [0xf0];
+    let a = Unit::from_bytes((&bytes, 0)).unwrap().1;
+    let new_bytes = a.to_bytes().unwrap();
+    assert_eq!(bytes, &*new_bytes);
+
+    let a = Unit;
+    let new_bytes = a.to_bytes().unwrap();
+    assert_eq!(bytes, &*new_bytes);
+}
Repository: dtolnay/anyhow (Rust)

Issue:
Usage of `bail!(error)` loses the context of `error`
I was in a situation recently where I was doing:

```rust
match some_result {
    Ok(()) => {}
    Err(e) => {
        if !err_is_ok(e) {
            bail!(e);
        }
    }
}
```

in this case `e` was actually of type `anyhow::Error` so a `return Err(e)` would have worked just fine, but I was surprised when this `bail!()` lost the context of the error of `e`, presumably because it called `.to_string()` on the result and lost all the context information.


Discussion:
Sorry about the confusion! This was a bug, I've fixed it in 1.0.22. It should now correctly preserve context for anyhow::Error as the argument as well as Box\<dyn Error\> and Box\<dyn Error + Send + Sync\>.
👍 





Patch:
diff --git a/src/kind.rs b/src/kind.rs
index 9a8a911..be9d9f4 100644
--- a/src/kind.rs
+++ b/src/kind.rs
@@ -45,7 +45,6 @@
 //     (&error).anyhow_kind().new(error)
 
 use crate::Error;
-use std::error::Error as StdError;
 use std::fmt::{Debug, Display};
 
 #[cfg(backtrace)]
@@ -80,13 +79,13 @@ pub trait TraitKind: Sized {
     }
 }
 
-impl<T> TraitKind for T where T: StdError + Send + Sync + 'static {}
+impl<E> TraitKind for E where E: Into<Error> {}
 
 impl Trait {
     pub fn new<E>(self, error: E) -> Error
     where
-        E: StdError + Send + Sync + 'static,
+        E: Into<Error>,
     {
-        Error::from_std(error, backtrace!())
+        error.into()
     }
 }


Test patch:
diff --git a/tests/test_source.rs b/tests/test_source.rs
index 04e9a9a..018267d 100644
--- a/tests/test_source.rs
+++ b/tests/test_source.rs
@@ -53,3 +53,10 @@ fn test_io_source() {
     let error = anyhow!(TestError::Io(io));
     assert_eq!("oh no!", error.source().unwrap().to_string());
 }
+
+#[test]
+fn test_anyhow_from_anyhow() {
+    let error = anyhow!("oh no!").context("context");
+    let error = anyhow!(error);
+    assert_eq!("oh no!", error.source().unwrap().to_string());
+}
Repository: JelteF/derive_more (Rust)

Issue:
[1.0.0-beta.6] Specifying `Display` trait bound after format causes confusing error message.
## Problem

The following code used to work in 1.0.0-beta.3:

```rust
#[derive(Display)]
#[display("{name}@{tag}")]
#[display(bound(Tag: std::fmt::Display))]
struct Specifier<Tag> {
    name: String,
    tag: Tag,
}
```

However, in 1.0.0-beta.6, it emits the following error message:

```text
error: multiple `#[display("...", ...)]` attributes aren't allowed
```

It took me a long time to figure out that the fix was to swap place between the 2 display attributes.

## Suggestions

Either allowing the display attributes to be in any order or improve the error message for this case.


Discussion:

Patch:
diff --git a/impl/src/fmt/mod.rs b/impl/src/fmt/mod.rs
index baeaadbb..0a3244ba 100644
--- a/impl/src/fmt/mod.rs
+++ b/impl/src/fmt/mod.rs
@@ -8,8 +8,6 @@ pub(crate) mod debug;
 pub(crate) mod display;
 mod parsing;
 
-use std::mem;
-
 use proc_macro2::TokenStream;
 use quote::ToTokens;
 use syn::{
@@ -391,7 +389,7 @@ impl attr::ParseMultiple for ContainerAttributes {
             item: new,
         } = new;
 
-        if mem::replace(&mut prev.fmt, new.fmt).is_some() {
+        if new.fmt.and_then(|n| prev.fmt.replace(n)).is_some() {
             return Err(syn::Error::new(
                 new_span,
                 format!("multiple `#[{name}(\"...\", ...)]` attributes aren't allowed"),


Test patch:
diff --git a/tests/display.rs b/tests/display.rs
index 540d35f5..3ede71b8 100644
--- a/tests/display.rs
+++ b/tests/display.rs
@@ -786,8 +786,8 @@ mod generic {
             }
 
             #[derive(Display)]
-            #[display(bound(T1: Trait1 + Trait2, T2: Trait1))]
             #[display("{} {} {} {} {:?}", _0.function1(), _0, _0.function2(), _1.function1(), _1)]
+            #[display(bound(T1: Trait1 + Trait2, T2: Trait1))]
             struct Struct<T1, T2>(T1, T2);
 
             let s = Struct(10, DebugOnly);
@@ -849,8 +849,8 @@ mod generic {
             }
 
             #[derive(Display)]
-            #[display(bound(T: Trait))]
             #[display("{}", _0.function())]
+            #[display(bound(T: Trait))]
             struct Struct<T>(T);
 
             let s = Struct(NoDisplay);
Repository: amber-lang/amber (Rust)

Issue:
[Bug] Special characters get interpolated inside of Text literal
The reproduction code for special symbols: `$`, `` ` ``, `!`

```js
unsafe $SUCCESS="FAILURE"$
echo "This is a $SUCCESS."
// This should print out "This is a $SUCCESS." and not "This is a FAILURE."
echo "Today is `date`"
// Expands to "Today is [current date]"
echo "Gooj job!"
// Expands to history expansion
```


Discussion:

Patch:
diff --git a/src/modules/expression/literal/mod.rs b/src/modules/expression/literal/mod.rs
index fbb7de9c7..974abeec9 100644
--- a/src/modules/expression/literal/mod.rs
+++ b/src/modules/expression/literal/mod.rs
@@ -80,16 +80,19 @@ fn translate_escaped_string(string: String, is_str: bool) -> String {
                     result.push('"');
                 }
             },
-            '`' => {
-                // Escape backticks if in a string
+            symbol @ ('$' | '`') => {
                 if is_str {
                     result.push('\\');
-                    result.push('`');
-                }
-                else {
-                    result.push('`');
                 }
+                result.push(symbol);
             },
+            '!' => {
+                if is_str {
+                    result += "\"'!'\"";
+                } else {
+                    result.push('!')
+                }
+            }
             '\\' => {
                 // Escape symbols
                 match chars.peek() {
diff --git a/src/std/main.ab b/src/std/main.ab
index 7c428f0fb..77e722975 100644
--- a/src/std/main.ab
+++ b/src/std/main.ab
@@ -1,7 +1,7 @@
 pub fun input(prompt: Text): Text {
     unsafe $printf "\${nameof prompt}"$
     unsafe $read$
-    return "$REPLY"
+    return unsafe $echo \$REPLY$
 }
 
 pub fun replace_once(source, pattern, replacement) {


Test patch:
diff --git a/src/tests/validity.rs b/src/tests/validity.rs
index ce44266f3..d61583216 100644
--- a/src/tests/validity.rs
+++ b/src/tests/validity.rs
@@ -41,6 +41,18 @@ fn text_escaped() {
     test_amber!("echo \"Hello \\\"World\\\"\"", "Hello \"World\"");
 }
 
+#[test]
+fn text_isolated_from_bash() {
+    let code = "
+        unsafe $SUCCESS=\"FAILURE\"$
+        echo \"This is a $SUCCESS\"
+
+        echo \"Today is `date`\"
+
+        echo \"Good job!\"
+    ";
+    test_amber!(code, "This is a $SUCCESS\nToday is `date`\nGood job!");
+}
 #[test]
 fn text_unescaped_after() {
     test_amber!("echo \"Hello\\\\\"", "Hello\\");
Repository: slog-rs/slog (Rust)

Issue:
2.2.1 breaking change, references to Logger are no longer accepted by macros
This would previously work but now fails to build:
```rust
fn do_thing(log: &Logger) {
    info!(log, "Thing done!");
}
```
As a workaround this works for now:
```rust
fn do_thing(log: &Logger) {
    info!(*log, "Thing done!");
}
```


Discussion:
I also just ran into this as well!
I believe I broke it in 08385b5 by using a qualified name for `$crate::Drain::is_enabled(&$l, $level)`.
This was necessary because the `Drain` trait isn't in scope and the method isn't inherent.
Fixing it is as simple as making a blanket implementation of `Drain` for all references.
Jenkins broke over the weekend with this `$crate::Drain:::is_enabled` patch.

I haven't advanced any of my dependencies, I'm wondering how it got in it?
Sorry for the problems. This should be fixed now.
While #165 fixed the issue for `&Logger` (thanks!) it still seems to be case for `&mut Logger` - which would also be a breaking change, right?
@Techcable  ? :)
Thanks for the quick fix :+1:
This also breaks passing structs as logger in the macros, which implement `Deref<::slog::Logger>`, which was also working previously. :/
@Drakulix Please provide more info. I plan to look into it today evening PST, and the more info I have, the higher the chance I'll fix it. :)
I think I identified the problem https://github.com/slog-rs/slog/commit/08385b53fe45ea2773a9a59f11b000a5f2dec7f1#diff-b4aea3e418ccdb71239b96952d9cddb6R772 . 

v2.2.3 was pushed where I reverted this part of the PR.



Patch:
diff --git a/src/lib.rs b/src/lib.rs
index d9fbf300a..5c610f749 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1448,6 +1448,22 @@ pub trait Drain {
         self.map(Fuse)
     }
 }
+impl<'a, D: Drain + 'a> Drain for &'a D {
+    type Ok = D::Ok;
+    type Err = D::Err;
+    #[inline]
+    fn log(
+        &self,
+        record: &Record,
+        values: &OwnedKVList,
+    ) -> result::Result<Self::Ok, Self::Err> {
+        (**self).log(record, values)
+    }
+    #[inline]
+    fn is_enabled(&self, level: Level) -> bool {
+        (**self).is_enabled(level)
+    }
+}
 
 #[cfg(feature = "std")]
 /// `Send + Sync + UnwindSafe` bound


Test patch:
diff --git a/src/tests.rs b/src/tests.rs
index c8f87e6cb..8c4f25608 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -237,3 +237,14 @@ fn logger_to_erased() {
 
     takes_arced_drain(log.into_erased());
 }
+
+#[test]
+fn logger_by_ref() {
+    use ::*;
+    let drain = Discard.filter_level(Level::Warning).map(Fuse);
+    let log = Logger::root_typed(drain, o!("version" => env!("CARGO_PKG_VERSION")));
+    let f = "f";
+    let d = (1, 2);
+    info!(&log, "message"; "f" => %f, "d" => ?d);
+}
+
Repository: dtolnay/thiserror (Rust)

Issue:
Figure out what to do about void enums
We should have some way to have derive(Error) emit a Display impl for a void enum; I don't think it works currently. Specifically, for enums the macro looks for at least one variant that has a `#[error("...")]` attribute to decide whether to generate Display, and void enums don't have any variants.

```rust
#[derive(Debug, Error)]
pub enum Error {}
```

Maybe the following should generate a Display impl, but it seems a bit silly because the message is meaningless as the Display impl is unreachable.

```rust
#[derive(Debug, Error)]
#[error("...")]
pub enum Error {}
```


Discussion:
The display impl in itself is a bit weird, but I think the benefit might come from it being a placeholder.  
Much for the same reason the Error has no variants, it could be that it's just not been populated yet.  

I know I've created an empty Error enum before, because I want the compiler to tell me which `From<_>` impls I need.



Patch:
diff --git a/impl/src/expand.rs b/impl/src/expand.rs
index 197239a7..6c04bd7c 100644
--- a/impl/src/expand.rs
+++ b/impl/src/expand.rs
@@ -110,6 +110,11 @@ fn impl_enum(input: Enum) -> TokenStream {
     };
 
     let display_impl = if input.has_display() {
+        let void_deref = if input.variants.is_empty() {
+            Some(quote!(*))
+        } else {
+            None
+        };
         let arms = input.variants.iter().map(|variant| {
             let display = variant.attrs.display.as_ref().expect(valid::CHECKED);
             let ident = &variant.ident;
@@ -122,7 +127,7 @@ fn impl_enum(input: Enum) -> TokenStream {
             impl #impl_generics std::fmt::Display for #ty #ty_generics #where_clause {
                 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
                     #[allow(unused_variables)]
-                    match self {
+                    match #void_deref self {
                         #(#arms,)*
                     }
                 }
diff --git a/impl/src/prop.rs b/impl/src/prop.rs
index 47bf65f7..b2473f5b 100644
--- a/impl/src/prop.rs
+++ b/impl/src/prop.rs
@@ -25,9 +25,11 @@ impl Enum<'_> {
     }
 
     pub(crate) fn has_display(&self) -> bool {
-        self.variants
-            .iter()
-            .any(|variant| variant.attrs.display.is_some())
+        self.attrs.display.is_some()
+            || self
+                .variants
+                .iter()
+                .any(|variant| variant.attrs.display.is_some())
     }
 }
 


Test patch:
diff --git a/tests/test_display.rs b/tests/test_display.rs
index 50a59e24..841029ca 100644
--- a/tests/test_display.rs
+++ b/tests/test_display.rs
@@ -47,6 +47,10 @@ struct Arithmetic;
 #[error("!bool = {}", not(.0))]
 struct NestedShorthand(bool);
 
+#[derive(Error, Debug)]
+#[error("...")]
+enum Void {}
+
 fn not(bool: &bool) -> bool {
     !*bool
 }
Repository: dtolnay/async-trait (Rust)

Issue:
Associated constants in trait functions
This is a weird one & may not be an issue with `async-trait`, so please close if needed.  When trying to use associated constants in macros (such as `debug!` or `println!`) it appears to trip up the compiler.

This standard trait compiles:

```rust
pub trait Example {
    const ASSOCIATED: &'static str;

    fn associated(&self) {
        println!("Associated:{}", Self::ASSOCIATED);
    }
}
```

This decorated trait does not compile:

```rust
#[async_trait]
pub trait Example {
    const ASSOCIATED: &'static str;

    async fn associated(&self) {
        println!("Associated:{}", Self::ASSOCIATED);
    }
}
```

I get the following error message:
```
error[E0401]: can't use generic parameters from outer function
  --> src/example.rs:16:35
   |
16 |         println!("Associated:{}", Self::ASSOCIATED);
   |                                   ^^^^^^^^^^^^^^^^
   |                                   |
   |                                   use of generic parameter from outer function
   |                                   can't use `Self` here
```

However, the trait impl works fine if you `let` bind it:

```rust
#[async_trait]
pub trait Example {
    const ASSOCIATED: &'static str;

    async fn associated(&self) {
        let associated = Self::ASSOCIATED;
        println!("Associated:{}", associated);
    }
}
```

The workaround appears to be OK for my use case.


Discussion:
Thanks for the nice minimal repro. I published 0.1.25 with a fix.



Patch:
diff --git a/src/receiver.rs b/src/receiver.rs
index 8125a3d..bb7a134 100644
--- a/src/receiver.rs
+++ b/src/receiver.rs
@@ -205,6 +205,7 @@ fn fold_token_stream(tokens: &mut TokenStream) -> bool {
         match tt {
             TokenTree::Ident(mut ident) => {
                 modified |= prepend_underscore_to_self(&mut ident);
+                modified |= replace_self_from_outer_function(&mut ident);
                 out.push(TokenTree::Ident(ident));
             }
             TokenTree::Group(group) => {
@@ -230,3 +231,11 @@ fn prepend_underscore_to_self(ident: &mut Ident) -> bool {
     }
     modified
 }
+
+fn replace_self_from_outer_function(ident: &mut Ident) -> bool {
+    let modified = ident == "Self";
+    if modified {
+        *ident = Ident::new("AsyncTrait", ident.span());
+    }
+    modified
+}


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index db065a9..d4fca0e 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -502,3 +502,17 @@ pub mod issue57 {
         executor::block_on_simple(fut);
     }
 }
+
+// https://github.com/dtolnay/async-trait/issues/73
+pub mod issue73 {
+    use async_trait::async_trait;
+
+    #[async_trait]
+    pub trait Example {
+        const ASSOCIATED: &'static str;
+
+        async fn associated(&self) {
+            println!("Associated:{}", Self::ASSOCIATED);
+        }
+    }
+}
Repository: altsem/gitu (Rust)

Issue:
remote.pushDefault is not consulted before prompting for a pushRemote
This was previously reported in #321, although I can't quite figure out why it was closed.

My [remote.pushDefault](https://git-scm.com/docs/git-config#Documentation/git-config.txt-branchltnamegtremote) config option in my repo is set to `origin`:

```shell
git config remote.pushDefault
origin
```

But when I do `Pp`, I am still prompted to enter a `pushRemote` for every new branch.

Briefly looking at `get_push_remote` and `head_push_remote_cfg`, I couldn't see how it might fall back to `remote.pushDefault` if `branch.{branch}.pushRemote` was not defined.

(I'll admit I don't think I fully understand the multitude of ways git can find a push remote, so maybe there's some other config value I should have looked for first?)


Discussion:
This is related as well: https://github.com/altsem/gitu/issues/322



Patch:
diff --git a/src/git/remote.rs b/src/git/remote.rs
index a4fb400d22..827870dc15 100644
--- a/src/git/remote.rs
+++ b/src/git/remote.rs
@@ -72,6 +72,22 @@ pub(crate) fn get_push_remote(repo: &Repository) -> Res<Option<String>> {
     let push_remote_cfg = head_push_remote_cfg(repo)?;
     let config = repo.config().map_err(Error::ReadGitConfig)?;
     let result = match config.get_entry(&push_remote_cfg) {
+        Ok(entry) => Ok(Some(
+            String::from_utf8(entry.value_bytes().to_vec())
+                .map_err(Utf8Error::String)
+                .map_err(Error::ReadGitConfigUtf8)?,
+        )),
+        Err(e) if e.class() == git2::ErrorClass::Config => get_default_push_remote(repo),
+        Err(e) => Err(Error::ReadGitConfig(e)),
+    };
+
+    result
+}
+
+pub(crate) fn get_default_push_remote(repo: &Repository) -> Res<Option<String>> {
+    let push_default_cfg = "remote.pushDefault";
+    let config = repo.config().map_err(Error::ReadGitConfig)?;
+    let result = match config.get_entry(push_default_cfg) {
         Ok(entry) => Ok(Some(
             String::from_utf8(entry.value_bytes().to_vec())
                 .map_err(Utf8Error::String)


Test patch:
diff --git a/src/tests/remote.rs b/src/tests/remote.rs
index 9de8e7a3c1..3dadf66adb 100644
--- a/src/tests/remote.rs
+++ b/src/tests/remote.rs
@@ -71,3 +71,20 @@ fn get_upstream_components_of_feature_branch() {
     assert_eq!(remote, ".");
     assert_eq!(branch, "main");
 }
+
+#[test]
+fn get_push_remote_with_default() {
+    let ctx = RepoTestContext::setup_clone();
+    let repo = ctx.local_repo;
+
+    let push_remote = get_push_remote(&repo).unwrap();
+    assert_eq!(push_remote, None);
+
+    run(
+        ctx.dir.path(),
+        &["git", "config", "remote.pushDefault", "origin"],
+    );
+
+    let push_remote = get_push_remote(&repo).unwrap();
+    assert_eq!(push_remote.unwrap(), "origin");
+}
Repository: dtolnay/async-trait (Rust)

Issue:
`mut self` is expended as `_self`
```rust
#[async_trait]
pub trait T {
    async fn f(self);
}

struct S {}

#[async_trait]
impl T for S {
    async fn f(mut self) {
        (&mut self).do_something();
    }
}
```

would give error

```
                                  ---- help: consider changing this to be mutable: `mut _self`
    (&mut self)
       ^^^^^^^^^^^ cannot borrow as mutable
```


Discussion:
Thanks! Fixed in 0.1.10.



Patch:
diff --git a/src/expand.rs b/src/expand.rs
index 7448152..f93dd04 100644
--- a/src/expand.rs
+++ b/src/expand.rs
@@ -307,8 +307,12 @@ fn transform_block(
             }
         }
         Some(arg @ FnArg::Receiver(_)) => {
-            let self_token = match arg {
-                FnArg::Receiver(Receiver { self_token, .. }) => self_token,
+            let (self_token, mutability) = match arg {
+                FnArg::Receiver(Receiver {
+                    self_token,
+                    mutability,
+                    ..
+                }) => (self_token, mutability),
                 _ => unreachable!(),
             };
             let under_self = Ident::new("_self", self_token.span);
@@ -316,12 +320,12 @@ fn transform_block(
                 Context::Trait { .. } => {
                     self_bound = Some(parse_quote!(core::marker::Send));
                     *arg = parse_quote! {
-                        #under_self: AsyncTrait
+                        #mutability #under_self: AsyncTrait
                     };
                 }
                 Context::Impl { receiver, .. } => {
                     *arg = parse_quote! {
-                        #under_self: #receiver
+                        #mutability #under_self: #receiver
                     };
                 }
             }


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index 8a030c0..9933244 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -225,3 +225,31 @@ mod issue17 {
         }
     }
 }
+
+// https://github.com/dtolnay/async-trait/issues/23
+mod issue23 {
+    use async_trait::async_trait;
+
+    #[async_trait]
+    pub trait T {
+        async fn f(self);
+
+        async fn g(mut self)
+        where
+            Self: Sized,
+        {
+            do_something(&mut self);
+        }
+    }
+
+    struct S {}
+
+    #[async_trait]
+    impl T for S {
+        async fn f(mut self) {
+            do_something(&mut self);
+        }
+    }
+
+    fn do_something<T>(_: &mut T) {}
+}
Repository: dtolnay/async-trait (Rust)

Issue:
Does not compile if self is Arc<Self>
Please add support for using a self type of Arc<Self>.

```
#![feature(async_await)]
use std::sync::Arc;
use async_trait::async_trait;

#[async_trait]
trait Trait {
    async fn example(self : Arc<Self>);
}

struct A;

#[async_trait]
impl Trait for A where  {
    async fn example(self : Arc<Self>) {
    }
}

fn main() {
    let a = Arc::new(A);
    async move {
        a.example().await
    };
}

```

```
error: unexpected `self` parameter in function
  --> src\main.rs:12:1
   |
12 | #[async_trait]
   | ^^^^^^^^^^^^^^ not valid as function parameter
   |
   = note: `self` is only valid as the first parameter of an associated function
```


Discussion:
Thanks! Fixed in 0.1.4.



Patch:
diff --git a/src/expand.rs b/src/expand.rs
index e564f0b..d77a565 100644
--- a/src/expand.rs
+++ b/src/expand.rs
@@ -294,6 +294,14 @@ fn transform_block(context: Context, sig: &mut MethodSig, block: &mut Block, has
                 };
             }
         },
+        Some(FnArg::Captured(ArgCaptured {
+            pat: Pat::Ident(arg),
+            ..
+        })) => {
+            if arg.ident == "self" {
+                arg.ident = Ident::new("_self", arg.ident.span());
+            }
+        }
         _ => {}
     }
 


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index 3a8a1ae..2ee5ea3 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -158,3 +158,21 @@ mod issue9 {
         async fn f(_x: Self) {}
     }
 }
+
+// https://github.com/dtolnay/async-trait/issues/11
+mod issue11 {
+    use async_trait::async_trait;
+    use std::sync::Arc;
+
+    #[async_trait]
+    trait Issue11 {
+        async fn example(self: Arc<Self>);
+    }
+
+    struct Struct;
+
+    #[async_trait]
+    impl Issue11 for Struct {
+        async fn example(self: Arc<Self>) {}
+    }
+}
Repository: dotenv-linter/dotenv-linter (Rust)

Issue:
Fix a bug with exit with code 1
`dotenv-linter` always exits with code 1 even if there are no warnings.
Need to fix that bug and write some integration tests to cover that case.

Link: https://github.com/mgrachev/dotenv-linter/blob/master/src/main.rs#L18


Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cef370bcd..b10c5084b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### 🔧 Changed
 - New CLI API: Ability to check multiple directories [#99](https://github.com/mgrachev/dotenv-linter/pull/99)
+- Add exit with the code 0 when there are no warnings [#105](https://github.com/mgrachev/dotenv-linter/pull/105) ([@simPod](https://github.com/simPod))
 
 ## [v1.1.2] - 2020-03-13
 ### 🔧 Changed
diff --git a/src/main.rs b/src/main.rs
index fac55480b..07ecee0e4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,9 +6,11 @@ use std::process;
 fn main() {
     match dotenv_linter::run() {
         Ok(warnings) => {
-            if !warnings.is_empty() {
-                warnings.iter().for_each(|w| println!("{}", w));
+            if warnings.is_empty() {
+                process::exit(0);
             }
+
+            warnings.iter().for_each(|w| println!("{}", w));
         }
         Err(error) => {
             eprintln!("dotenv-linter: {}", error);


Test patch:
diff --git a/tests/cli_test.rs b/tests/cli_test.rs
index af61495af..d51dcfeea 100644
--- a/tests/cli_test.rs
+++ b/tests/cli_test.rs
@@ -254,3 +254,17 @@ fn checks_one_specific_file_twice() {
     drop(file1);
     current_dir.close().unwrap();
 }
+
+#[test]
+fn exits_with_0_on_no_errors() {
+    let current_dir = tempdir().unwrap();
+    let file_path = current_dir.path().join(".env");
+    let mut file = File::create(&file_path).unwrap();
+    writeln!(file, "FOO=bar").unwrap();
+
+    let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap();
+    cmd.current_dir(&current_dir).assert().success();
+
+    drop(file);
+    current_dir.close().unwrap();
+}
Repository: dtolnay/async-trait (Rust)

Issue:
Unsize coercion fails if end of method is unreachable
The following async trait fails to compile. Notice that the same method body is fine in an ordinary async fn outside of an async trait.

This worked prior to #143.

```rust
use async_trait::async_trait;

struct Thing;
trait Ret {}
impl Ret for Thing {}

async fn ok() -> &'static dyn Ret {
    return &Thing;
}

#[async_trait]
trait Trait {
    async fn fail() -> &'static dyn Ret {
        return &Thing;
    }
}
```

```console
error[E0308]: mismatched types
  --> src/main.rs:13:41
   |
13 |       async fn fail() -> &'static dyn Ret {
   |  _________________________________________^
14 | |         return &Thing;
15 | |     }
   | |_____^ expected struct `Thing`, found trait object `dyn Ret`
   |
   = note:   expected type `&Thing`
           found reference `&'static (dyn Ret + 'static)`
note: return type inferred to be `&Thing` here
  --> src/main.rs:14:16
   |
14 |         return &Thing;
   |                ^^^^^^

error[E0271]: type mismatch resolving `<impl Future as Future>::Output == &'static (dyn Ret + 'static)`
  --> src/main.rs:13:41
   |
13 |       async fn fail() -> &'static dyn Ret {
   |  _________________________________________^
14 | |         return &Thing;
15 | |     }
   | |_____^ expected trait object `dyn Ret`, found struct `Thing`
   |
   = note: expected reference `&'static (dyn Ret + 'static)`
              found reference `&Thing`
   = note: required for the cast to the object type `dyn Future<Output = &'static (dyn Ret + 'static)> + Send`
```


Discussion:

Patch:
diff --git a/src/expand.rs b/src/expand.rs
index b0ebb4c..06c4ba3 100644
--- a/src/expand.rs
+++ b/src/expand.rs
@@ -350,6 +350,9 @@ fn transform_block(sig: &mut Signature, block: &mut Block) {
             let _: () = { #(#decls)* #(#stmts)* };
         },
         ReturnType::Type(_, ret) => quote_spanned! {block.brace_token.span=>
+            if let ::core::option::Option::Some(__ret) = ::core::option::Option::None::<#ret> {
+                return __ret;
+            }
             let __ret: #ret = { #(#decls)* #(#stmts)* };
             #[allow(unreachable_code)]
             __ret


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index a97af36..06c0918 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1258,3 +1258,23 @@ pub mod issue147 {
         }
     }
 }
+
+// https://github.com/dtolnay/async-trait/issues/149
+pub mod issue149 {
+    use async_trait::async_trait;
+
+    pub struct Thing;
+    pub trait Ret {}
+    impl Ret for Thing {}
+
+    pub async fn ok() -> &'static dyn Ret {
+        return &Thing;
+    }
+
+    #[async_trait]
+    pub trait Trait {
+        async fn fail() -> &'static dyn Ret {
+            return &Thing;
+        }
+    }
+}
Repository: TedDriggs/darling (Rust)

Issue:
`Override<Callable>` rejects a closure
```rust
use darling::FromAttributes;
use darling::util::{Callable, Override};

#[derive(FromAttributes)]
#[darling(attributes(test))]
struct Test1 {
    func: Callable,
}

#[derive(FromAttributes)]
#[darling(attributes(test))]
struct Test2 {
    func: Override<Callable>,
}

#[test]
fn test() {
    let attrs = [syn::parse_quote!(#[test(func = || 1 + 1)])];
    assert!(Test1::from_attributes(&attrs).is_ok());
    assert!(Test2::from_attributes(&attrs).is_err()); // Error { kind: UnexpectedType("closure"), locations: ["func"], span: Some(Span) }
}
```


Discussion:
`impl<T: FromMeta> FromMeta for Override<T>` doesn't override `from_expr` method:

https://github.com/TedDriggs/darling/blob/65d73d1b38d47804cfaa584e3527c7d2f5e761d5/core/src/util/over_ride.rs#L139-L163

When we provide an `syn::Expr::Closure` to it, it goes through the default implementation, resulting the unexpected closure error:

https://github.com/TedDriggs/darling/blob/65d73d1b38d47804cfaa584e3527c7d2f5e761d5/core/src/from_meta.rs#L124-L138

I've published this in 0.21.3



Patch:
diff --git a/core/src/util/over_ride.rs b/core/src/util/over_ride.rs
index 1f8113f..337d5f6 100644
--- a/core/src/util/over_ride.rs
+++ b/core/src/util/over_ride.rs
@@ -149,6 +149,10 @@ impl<T: FromMeta> FromMeta for Override<T> {
         Ok(Explicit(FromMeta::from_value(lit)?))
     }
 
+    fn from_expr(expr: &syn::Expr) -> Result<Self> {
+        Ok(Explicit(FromMeta::from_expr(expr)?))
+    }
+
     fn from_char(value: char) -> Result<Self> {
         Ok(Explicit(FromMeta::from_char(value)?))
     }


Test patch:
diff --git a/tests/override_callable.rs b/tests/override_callable.rs
new file mode 100644
index 0000000..8a3eca9
--- /dev/null
+++ b/tests/override_callable.rs
@@ -0,0 +1,50 @@
+//! This is a regression test for issue [#371](https://github.com/TedDriggs/darling/issues/371).
+
+use darling::util::{Callable, Override};
+use darling::FromDeriveInput;
+
+#[derive(FromDeriveInput)]
+#[darling(attributes(test))]
+struct Test1 {
+    #[allow(dead_code)]
+    func: Callable,
+}
+
+#[derive(FromDeriveInput)]
+#[darling(attributes(test))]
+struct Test2 {
+    func: Override<Callable>,
+}
+
+#[test]
+fn test_explicit_closure() {
+    let input = syn::parse_quote! {
+        #[test(func = || 1 + 1)]
+        struct Foo;
+    };
+    assert!(Test1::from_derive_input(&input).is_ok());
+    assert!(Test2::from_derive_input(&input).is_ok());
+}
+
+#[test]
+fn test_explicit_path() {
+    let input = syn::parse_quote! {
+        #[test(func = foo::bar)]
+        struct Foo;
+    };
+    assert!(Test1::from_derive_input(&input).is_ok());
+    assert!(Test2::from_derive_input(&input).is_ok());
+}
+
+#[test]
+fn test_inherit() {
+    let input = syn::parse_quote! {
+        #[test(func)]
+        struct Foo;
+    };
+    assert!(Test1::from_derive_input(&input).is_err());
+    assert!(matches!(
+        Test2::from_derive_input(&input).unwrap().func,
+        Override::Inherit
+    ));
+}
Repository: dotenv-linter/dotenv-linter (Rust)

Issue:
Proposal: Add text indicating "no difference" when running compare option.
Example files:

**.env**
`FOO=BAR
BAR=FOO`

**.env.example**
`FOO=BAR
BAR=FOO`

Running `dotenv-linter compare .env .env.example`

```
Comparing .env

Comparing .env.example
```

I propose that when the comparison reveals both files to be the same, a message indicates it so. Something like

```
No difference found.
```

This could be helpful to prevent any confusion about the program's result of finding no comparison vs terminating for some reason.


Discussion:
This issue is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 5 days.
Can this be reviewed? I have a PR ready here: https://github.com/dotenv-linter/dotenv-linter/pull/648



Patch:
diff --git a/dotenv-linter/src/common/output/compare.rs b/dotenv-linter/src/common/output/compare.rs
index 0a6218cef..03717d726 100644
--- a/dotenv-linter/src/common/output/compare.rs
+++ b/dotenv-linter/src/common/output/compare.rs
@@ -29,4 +29,11 @@ impl CompareOutput {
             println!("Nothing to compare");
         }
     }
+
+    /// Prints "No difference found" when the two compared files have no difference
+    pub fn print_no_difference_found(&self) {
+        if !self.is_quiet_mode {
+            println!("No difference found");
+        }
+    }
 }
diff --git a/dotenv-linter/src/lib.rs b/dotenv-linter/src/lib.rs
index 0ff17091e..ef8f39ecc 100644
--- a/dotenv-linter/src/lib.rs
+++ b/dotenv-linter/src/lib.rs
@@ -143,6 +143,12 @@ pub fn compare(opts: &CompareOptions, current_dir: &PathBuf) -> Result<usize> {
         }
     }
 
+    // Create success message if no warnings found.
+    if warnings.is_empty() {
+        output.print_no_difference_found();
+        return Ok(0);
+    }
+
     output.print_warnings(&warnings);
     Ok(warnings.len())
 }


Test patch:
diff --git a/dotenv-linter/tests/compare/compare.rs b/dotenv-linter/tests/compare/compare.rs
index e16dcae16..acb62d732 100644
--- a/dotenv-linter/tests/compare/compare.rs
+++ b/dotenv-linter/tests/compare/compare.rs
@@ -5,7 +5,7 @@ fn files_with_same_environment_variables() {
     let test_dir = TestDir::new();
     let testfile_one = test_dir.create_testfile(".env1", "FOO=abc\nBAR=def");
     let testfile_two = test_dir.create_testfile(".env2", "FOO=abc\nBAR=def");
-    let expected_output = "Comparing .env1\nComparing .env2\n";
+    let expected_output = "Comparing .env1\nComparing .env2\nNo difference found\n";
 
     test_dir.test_command_success_with_args(
         &["compare", testfile_one.as_str(), testfile_two.as_str()],