about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/compiletest/src/common.rs10
-rw-r--r--src/tools/compiletest/src/tests.rs27
2 files changed, 34 insertions, 3 deletions
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 36f876bcdc6..4e2510ed9ab 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -39,18 +39,22 @@ macro_rules! string_enum {
         }
 
         impl FromStr for $name {
-            type Err = ();
+            type Err = String;
 
-            fn from_str(s: &str) -> Result<Self, ()> {
+            fn from_str(s: &str) -> Result<Self, Self::Err> {
                 match s {
                     $($repr => Ok(Self::$variant),)*
-                    _ => Err(()),
+                    _ => Err(format!(concat!("unknown `", stringify!($name), "` variant: `{}`"), s)),
                 }
             }
         }
     }
 }
 
+// Make the macro visible outside of this module, for tests.
+#[cfg(test)]
+pub(crate) use string_enum;
+
 string_enum! {
     #[derive(Clone, Copy, PartialEq, Debug)]
     pub enum Mode {
diff --git a/src/tools/compiletest/src/tests.rs b/src/tools/compiletest/src/tests.rs
index fec746904de..43c6dc0a67e 100644
--- a/src/tools/compiletest/src/tests.rs
+++ b/src/tools/compiletest/src/tests.rs
@@ -66,3 +66,30 @@ fn is_test_test() {
     assert!(!is_test(&OsString::from("#a_dog_gif")));
     assert!(!is_test(&OsString::from("~a_temp_file")));
 }
+
+#[test]
+fn string_enums() {
+    // These imports are needed for the macro-generated code
+    use std::fmt;
+    use std::str::FromStr;
+
+    crate::common::string_enum! {
+        #[derive(Clone, Copy, Debug, PartialEq)]
+        enum Animal {
+            Cat => "meow",
+            Dog => "woof",
+        }
+    }
+
+    // General assertions, mostly to silence the dead code warnings
+    assert_eq!(Animal::VARIANTS.len(), 2);
+    assert_eq!(Animal::STR_VARIANTS.len(), 2);
+
+    // Correct string conversions
+    assert_eq!(Animal::Cat, "meow".parse().unwrap());
+    assert_eq!(Animal::Dog, "woof".parse().unwrap());
+
+    // Invalid conversions
+    let animal = "nya".parse::<Animal>();
+    assert_eq!("unknown `Animal` variant: `nya`", animal.unwrap_err());
+}