]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_expand/src/db.rs
internal: Expand the derive attribute into a pseudo expansion
[rust.git] / crates / hir_expand / src / db.rs
index 75766a54a74f7920e16746860ed39bf750bb8507..d6d33b4cd724f144e336c27e9fb91e67863a4cdc 100644 (file)
@@ -5,7 +5,7 @@
 use base_db::{salsa, SourceDatabase};
 use either::Either;
 use limit::Limit;
-use mbe::{syntax_node_to_token_tree, ExpandError, ExpandResult};
+use mbe::syntax_node_to_token_tree;
 use rustc_hash::FxHashSet;
 use syntax::{
     algo::diff,
@@ -15,8 +15,9 @@
 
 use crate::{
     ast_id_map::AstIdMap, fixup, hygiene::HygieneFrame, BuiltinAttrExpander, BuiltinDeriveExpander,
-    BuiltinFnLikeExpander, ExpandTo, HirFileId, HirFileIdRepr, MacroCallId, MacroCallKind,
-    MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander,
+    BuiltinFnLikeExpander, ExpandError, ExpandResult, ExpandTo, HirFileId, HirFileIdRepr,
+    MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile,
+    ProcMacroExpander,
 };
 
 /// Total limit on the number of tokens produced by any macro invocation.
@@ -47,10 +48,10 @@ fn expand(
         db: &dyn AstDatabase,
         id: MacroCallId,
         tt: &tt::Subtree,
-    ) -> mbe::ExpandResult<tt::Subtree> {
+    ) -> ExpandResult<tt::Subtree> {
         match self {
-            TokenExpander::DeclarativeMacro { mac, .. } => mac.expand(tt),
-            TokenExpander::Builtin(it) => it.expand(db, id, tt),
+            TokenExpander::DeclarativeMacro { mac, .. } => mac.expand(tt).map_err(Into::into),
+            TokenExpander::Builtin(it) => it.expand(db, id, tt).map_err(Into::into),
             TokenExpander::BuiltinAttr(it) => it.expand(db, id, tt),
             TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt),
             TokenExpander::ProcMacro(_) => {
@@ -336,10 +337,12 @@ fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet<Sy
                 ast::Item::cast(node.clone())?
                     .attrs()
                     .take(derive_attr_index as usize + 1)
+                    // FIXME
                     .filter(|attr| attr.simple_name().as_deref() == Some("derive"))
                     .map(|it| it.syntax().clone())
                     .collect()
             }
+            MacroCallKind::Attr { is_derive: true, .. } => return None,
             MacroCallKind::Attr { invoc_attr_index, .. } => {
                 cov_mark::hit!(attribute_macro_attr_censoring);
                 ast::Item::cast(node.clone())?
@@ -431,7 +434,11 @@ fn macro_expand(db: &dyn AstDatabase, id: MacroCallId) -> ExpandResult<Option<Ar
 
     let macro_arg = match db.macro_arg(id) {
         Some(it) => it,
-        None => return ExpandResult::str_err("Failed to lower macro args to token tree".into()),
+        None => {
+            return ExpandResult::only_err(ExpandError::Other(
+                "Failed to lower macro args to token tree".into(),
+            ))
+        }
     };
 
     let expander = match db.macro_def(loc.def) {
@@ -439,16 +446,23 @@ fn macro_expand(db: &dyn AstDatabase, id: MacroCallId) -> ExpandResult<Option<Ar
         // FIXME: This is weird -- we effectively report macro *definition*
         // errors lazily, when we try to expand the macro. Instead, they should
         // be reported at the definition site (when we construct a def map).
-        Err(err) => return ExpandResult::str_err(format!("invalid macro definition: {}", err)),
+        Err(err) => {
+            return ExpandResult::only_err(ExpandError::Other(
+                format!("invalid macro definition: {}", err).into(),
+            ))
+        }
     };
     let ExpandResult { value: mut tt, err } = expander.expand(db, id, &macro_arg.0);
     // Set a hard limit for the expanded tt
     let count = tt.count();
     if TOKEN_LIMIT.check(count).is_err() {
-        return ExpandResult::str_err(format!(
-            "macro invocation exceeds token limit: produced {} tokens, limit is {}",
-            count,
-            TOKEN_LIMIT.inner(),
+        return ExpandResult::only_err(ExpandError::Other(
+            format!(
+                "macro invocation exceeds token limit: produced {} tokens, limit is {}",
+                count,
+                TOKEN_LIMIT.inner(),
+            )
+            .into(),
         ));
     }
 
@@ -465,7 +479,9 @@ fn expand_proc_macro(db: &dyn AstDatabase, id: MacroCallId) -> ExpandResult<tt::
     let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
     let macro_arg = match db.macro_arg(id) {
         Some(it) => it,
-        None => return ExpandResult::str_err("No arguments for proc-macro".to_string()),
+        None => {
+            return ExpandResult::only_err(ExpandError::Other("No arguments for proc-macro".into()))
+        }
     };
 
     let expander = match loc.def.kind {