about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_expand/src/proc_macro.rs34
-rw-r--r--crates/proc_macro_api/src/lib.rs2
2 files changed, 23 insertions, 13 deletions
diff --git a/crates/hir_expand/src/proc_macro.rs b/crates/hir_expand/src/proc_macro.rs
index e8e1d99e808..d68794eb980 100644
--- a/crates/hir_expand/src/proc_macro.rs
+++ b/crates/hir_expand/src/proc_macro.rs
@@ -1,9 +1,10 @@
 //! Proc Macro Expander stub
 
-use crate::db::AstDatabase;
-use base_db::{CrateId, ProcMacroExpansionError, ProcMacroId};
+use base_db::{CrateId, ProcMacroExpansionError, ProcMacroId, ProcMacroKind};
 use mbe::ExpandResult;
 
+use crate::db::AstDatabase;
+
 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
 pub struct ProcMacroExpander {
     krate: CrateId,
@@ -36,20 +37,29 @@ impl ProcMacroExpander {
                 let krate_graph = db.crate_graph();
                 let proc_macro = match krate_graph[self.krate].proc_macro.get(id.0 as usize) {
                     Some(proc_macro) => proc_macro,
-                    None => return ExpandResult::str_err("No derive macro found.".to_string()),
+                    None => return ExpandResult::str_err("No proc-macro found.".to_string()),
                 };
 
                 // Proc macros have access to the environment variables of the invoking crate.
                 let env = &krate_graph[calling_crate].env;
-
-                proc_macro
-                    .expander
-                    .expand(tt, attr_arg, env)
-                    .map_err(|err| match err {
-                        ProcMacroExpansionError::Panic(text) => mbe::ExpandError::Other(text),
-                        ProcMacroExpansionError::System(text) => mbe::ExpandError::Other(text),
-                    })
-                    .into()
+                match proc_macro.expander.expand(tt, attr_arg, env) {
+                    Ok(t) => ExpandResult::ok(t),
+                    Err(err) => match err {
+                        // Don't discard the item in case something unexpected happened while expanding attributes
+                        ProcMacroExpansionError::System(text)
+                            if proc_macro.kind == ProcMacroKind::Attr =>
+                        {
+                            ExpandResult {
+                                value: tt.clone(),
+                                err: Some(mbe::ExpandError::Other(text)),
+                            }
+                        }
+                        ProcMacroExpansionError::System(text)
+                        | ProcMacroExpansionError::Panic(text) => {
+                            ExpandResult::only_err(mbe::ExpandError::Other(text))
+                        }
+                    },
+                }
             }
             None => ExpandResult::only_err(mbe::ExpandError::UnresolvedProcMacro),
         }
diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs
index b03a029f8ad..9e50c1f83f7 100644
--- a/crates/proc_macro_api/src/lib.rs
+++ b/crates/proc_macro_api/src/lib.rs
@@ -167,7 +167,7 @@ impl ProcMacro {
         let request = msg::Request::ExpandMacro(task);
         let response = self.process.lock().unwrap_or_else(|e| e.into_inner()).send_task(request)?;
         match response {
-            msg::Response::ExpandMacro(it) => Ok(it.map(|it| it.to_subtree())),
+            msg::Response::ExpandMacro(it) => Ok(it.map(FlatTree::to_subtree)),
             msg::Response::ListMacros { .. } => {
                 Err(ServerError { message: "unexpected response".to_string(), io: None })
             }