From 59dd7ccbf2a78809f95061952146af9ed7244b31 Mon Sep 17 00:00:00 2001
From: David Tolnay <dtolnay@gmail.com>
Date: Sat, 18 Mar 2023 13:29:19 -0700
Subject: [PATCH] Add methods on Meta for error reporting an incorrect kind of
 attribute

---
 src/attr.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/src/attr.rs b/src/attr.rs
index cc5ebc7758..34d5515a56 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -505,6 +505,54 @@ impl Meta {
             Meta::NameValue(meta) => &meta.path,
         }
     }
+
+    /// Error if this is a `Meta::List` or `Meta::NameValue`.
+    #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+    pub fn require_path_only(&self) -> Result<&Path> {
+        let error_span = match self {
+            Meta::Path(path) => return Ok(path),
+            Meta::List(meta) => meta.delimiter.span().open(),
+            Meta::NameValue(meta) => meta.eq_token.span,
+        };
+        Err(Error::new(error_span, "unexpected token in attribute"))
+    }
+
+    /// Error if this is a `Meta::Path` or `Meta::NameValue`.
+    #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+    pub fn require_list(&self) -> Result<&MetaList> {
+        match self {
+            Meta::List(meta) => Ok(meta),
+            Meta::Path(path) => Err(crate::error::new2(
+                path.segments.first().unwrap().ident.span(),
+                path.segments.last().unwrap().ident.span(),
+                format!(
+                    "expected attribute arguments in parentheses: `{}(...)`",
+                    parsing::DisplayPath(path),
+                ),
+            )),
+            Meta::NameValue(meta) => Err(Error::new(meta.eq_token.span, "expected `(`")),
+        }
+    }
+
+    /// Error if this is a `Meta::Path` or `Meta::List`.
+    #[cfg(feature = "parsing")]
+    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
+    pub fn require_name_value(&self) -> Result<&MetaNameValue> {
+        match self {
+            Meta::NameValue(meta) => Ok(meta),
+            Meta::Path(path) => Err(crate::error::new2(
+                path.segments.first().unwrap().ident.span(),
+                path.segments.last().unwrap().ident.span(),
+                format!(
+                    "expected a value for this attribute: `{} = ...`",
+                    parsing::DisplayPath(path),
+                ),
+            )),
+            Meta::List(meta) => Err(Error::new(meta.delimiter.span().open(), "expected `=`")),
+        }
+    }
 }
 
 impl MetaList {