Repository: shepmaster/snafu (rust)

Issue:
Error variants named `None` conflict with `Option::None`
If by chance someone chooses to name one of the variants `None`, the code expanded by `derive(Snafu)` will not compile.

```rust
use snafu::Snafu;

#[derive(Debug, Snafu)]
enum Error {
    #[snafu(display("Nothing is wrong"))]
    None,
}
```

```none
error[E0308]: mismatched types
 --> src/main.rs:3:17
  |
3 | #[derive(Debug, Snafu)]
  |                 ^^^^^ expected enum `std::option::Option`, found struct `None`
  |
  = note: expected type `std::option::Option<&dyn std::error::Error>`
             found type `None`

error[E0308]: mismatched types
 --> src/main.rs:3:17
  |
3 | #[derive(Debug, Snafu)]
  |                 ^^^^^ expected enum `std::option::Option`, found struct `None`
  |
  = note: expected type `std::option::Option<&(dyn std::error::Error + 'static)>`
             found type `None`

error[E0308]: mismatched types
 --> src/main.rs:3:17
  |
3 | #[derive(Debug, Snafu)]
  |                 ^^^^^ expected enum `std::option::Option`, found struct `None`
  |
  = note: expected type `std::option::Option<&snafu::backtrace_shim::Backtrace>`
             found type `None`

error: aborting due to 3 previous errors
```

Pull request:
Fully-qualify `Some` and `None` in generated code
Fixes #51

Patch:
diff --git a/snafu-derive/src/lib.rs b/snafu-derive/src/lib.rs
index aa2a59b..b6b0f93 100644
--- a/snafu-derive/src/lib.rs
+++ b/snafu-derive/src/lib.rs
@@ -713,13 +713,13 @@ impl<'a> ErrorImpl<'a> {
                         } = *source_field;
                         quote! {
                             #enum_name::#variant_name { ref #field_name, .. } => {
-                                Some(std::borrow::Borrow::borrow(#field_name))
+                                std::option::Option::Some(std::borrow::Borrow::borrow(#field_name))
                             }
                         }
                     }
                     None => {
                         quote! {
-                            #enum_name::#variant_name { .. } => { None }
+                            #enum_name::#variant_name { .. } => { std::option::Option::None }
                         }
                     }
                 }
@@ -809,11 +809,11 @@ impl<'a> ErrorCompatImpl<'a> {
                     ..
                 } = *backtrace_field;
                 quote! {
-                    #enum_name::#variant_name { ref #field_name, .. } => { Some(#field_name) }
+                    #enum_name::#variant_name { ref #field_name, .. } => { std::option::Option::Some(#field_name) }
                 }
             } else {
                 quote! {
-                    #enum_name::#variant_name { .. } => { None }
+                    #enum_name::#variant_name { .. } => { std::option::Option::None }
                 }
             }
         }).collect()


Test patch:
diff --git a/tests/name-conflicts.rs b/tests/name-conflicts.rs
new file mode 100644
index 0000000..e9fc33d
--- /dev/null
+++ b/tests/name-conflicts.rs
@@ -0,0 +1,23 @@
+extern crate snafu;
+
+use snafu::Snafu;
+
+#[derive(Debug, Snafu)]
+enum VariantNamedNone {
+    None,
+}
+
+#[derive(Debug, Snafu)]
+enum VariantNamedSome<T> {
+    Some { value: T },
+}
+
+#[derive(Debug, Snafu)]
+enum VariantNamedOk<T> {
+    Ok { value: T },
+}
+
+#[derive(Debug, Snafu)]
+enum VariantNamedErr<T> {
+    Err { value: T },
+}