aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_expand/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_expand/src')
-rw-r--r--crates/hir_expand/src/builtin_derive.rs10
-rw-r--r--crates/hir_expand/src/builtin_macro.rs19
-rw-r--r--crates/hir_expand/src/db.rs2
-rw-r--r--crates/hir_expand/src/eager.rs24
-rw-r--r--crates/hir_expand/src/lib.rs21
-rw-r--r--crates/hir_expand/src/name.rs1
6 files changed, 50 insertions, 27 deletions
diff --git a/crates/hir_expand/src/builtin_derive.rs b/crates/hir_expand/src/builtin_derive.rs
index 6ece4b289..537c03028 100644
--- a/crates/hir_expand/src/builtin_derive.rs
+++ b/crates/hir_expand/src/builtin_derive.rs
@@ -269,7 +269,7 @@ mod tests {
269 use expect_test::{expect, Expect}; 269 use expect_test::{expect, Expect};
270 use name::AsName; 270 use name::AsName;
271 271
272 use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc}; 272 use crate::{test_db::TestDB, AstId, AttrId, MacroCallId, MacroCallKind, MacroCallLoc};
273 273
274 use super::*; 274 use super::*;
275 275
@@ -308,7 +308,7 @@ $0
308 308
309 let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap(); 309 let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap();
310 310
311 let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0])); 311 let ast_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0]));
312 312
313 let loc = MacroCallLoc { 313 let loc = MacroCallLoc {
314 def: MacroDefId { 314 def: MacroDefId {
@@ -317,7 +317,11 @@ $0
317 local_inner: false, 317 local_inner: false,
318 }, 318 },
319 krate: CrateId(0), 319 krate: CrateId(0),
320 kind: MacroCallKind::Derive(attr_id, name.to_string()), 320 kind: MacroCallKind::Derive {
321 ast_id,
322 derive_name: name.to_string(),
323 derive_attr: AttrId(0),
324 },
321 }; 325 };
322 326
323 let id: MacroCallId = db.intern_macro(loc).into(); 327 let id: MacroCallId = db.intern_macro(loc).into();
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 75ec4196b..179de61f9 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -110,6 +110,7 @@ register_builtin! {
110 (format_args_nl, FormatArgsNl) => format_args_expand, 110 (format_args_nl, FormatArgsNl) => format_args_expand,
111 (llvm_asm, LlvmAsm) => asm_expand, 111 (llvm_asm, LlvmAsm) => asm_expand,
112 (asm, Asm) => asm_expand, 112 (asm, Asm) => asm_expand,
113 (global_asm, GlobalAsm) => global_asm_expand,
113 (cfg, Cfg) => cfg_expand, 114 (cfg, Cfg) => cfg_expand,
114 (core_panic, CorePanic) => panic_expand, 115 (core_panic, CorePanic) => panic_expand,
115 (std_panic, StdPanic) => panic_expand, 116 (std_panic, StdPanic) => panic_expand,
@@ -274,6 +275,15 @@ fn asm_expand(
274 ExpandResult::ok(expanded) 275 ExpandResult::ok(expanded)
275} 276}
276 277
278fn global_asm_expand(
279 _db: &dyn AstDatabase,
280 _id: LazyMacroId,
281 _tt: &tt::Subtree,
282) -> ExpandResult<tt::Subtree> {
283 // Expand to nothing (at item-level)
284 ExpandResult::ok(quote! {})
285}
286
277fn cfg_expand( 287fn cfg_expand(
278 db: &dyn AstDatabase, 288 db: &dyn AstDatabase,
279 id: LazyMacroId, 289 id: LazyMacroId,
@@ -490,7 +500,7 @@ fn env_expand(
490 // unnecessary diagnostics for eg. `CARGO_PKG_NAME`. 500 // unnecessary diagnostics for eg. `CARGO_PKG_NAME`.
491 if key == "OUT_DIR" { 501 if key == "OUT_DIR" {
492 err = Some(mbe::ExpandError::Other( 502 err = Some(mbe::ExpandError::Other(
493 r#"`OUT_DIR` not set, enable "load out dirs from check" to fix"#.into(), 503 r#"`OUT_DIR` not set, enable "run build scripts" to fix"#.into(),
494 )); 504 ));
495 } 505 }
496 506
@@ -566,10 +576,9 @@ mod tests {
566 let loc = MacroCallLoc { 576 let loc = MacroCallLoc {
567 def, 577 def,
568 krate, 578 krate,
569 kind: MacroCallKind::FnLike(AstId::new( 579 kind: MacroCallKind::FnLike {
570 file_id.into(), 580 ast_id: AstId::new(file_id.into(), ast_id_map.ast_id(&macro_call)),
571 ast_id_map.ast_id(&macro_call), 581 },
572 )),
573 }; 582 };
574 583
575 let id: MacroCallId = db.intern_macro(loc).into(); 584 let id: MacroCallId = db.intern_macro(loc).into();
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index 10fe60821..1e4b0cc19 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -439,6 +439,8 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
439 match parent.kind() { 439 match parent.kind() {
440 MACRO_ITEMS | SOURCE_FILE => FragmentKind::Items, 440 MACRO_ITEMS | SOURCE_FILE => FragmentKind::Items,
441 MACRO_STMTS => FragmentKind::Statements, 441 MACRO_STMTS => FragmentKind::Statements,
442 MACRO_PAT => FragmentKind::Pattern,
443 MACRO_TYPE => FragmentKind::Type,
442 ITEM_LIST => FragmentKind::Items, 444 ITEM_LIST => FragmentKind::Items,
443 LET_STMT => { 445 LET_STMT => {
444 // FIXME: Handle LHS Pattern 446 // FIXME: Handle LHS Pattern
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index 9705526fa..f12132f84 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -29,8 +29,9 @@ use base_db::CrateId;
29use mbe::ExpandResult; 29use mbe::ExpandResult;
30use parser::FragmentKind; 30use parser::FragmentKind;
31use std::sync::Arc; 31use std::sync::Arc;
32use syntax::{algo::SyntaxRewriter, SyntaxNode}; 32use syntax::{ted, SyntaxNode};
33 33
34#[derive(Debug)]
34pub struct ErrorEmitted { 35pub struct ErrorEmitted {
35 _private: (), 36 _private: (),
36} 37}
@@ -174,8 +175,9 @@ fn lazy_expand(
174) -> ExpandResult<Option<InFile<SyntaxNode>>> { 175) -> ExpandResult<Option<InFile<SyntaxNode>>> {
175 let ast_id = db.ast_id_map(macro_call.file_id).ast_id(&macro_call.value); 176 let ast_id = db.ast_id_map(macro_call.file_id).ast_id(&macro_call.value);
176 177
177 let id: MacroCallId = 178 let id: MacroCallId = def
178 def.as_lazy_macro(db, krate, MacroCallKind::FnLike(macro_call.with_value(ast_id))).into(); 179 .as_lazy_macro(db, krate, MacroCallKind::FnLike { ast_id: macro_call.with_value(ast_id) })
180 .into();
179 181
180 let err = db.macro_expand_error(id); 182 let err = db.macro_expand_error(id);
181 let value = db.parse_or_expand(id.as_file()).map(|node| InFile::new(id.as_file(), node)); 183 let value = db.parse_or_expand(id.as_file()).map(|node| InFile::new(id.as_file(), node));
@@ -190,10 +192,10 @@ fn eager_macro_recur(
190 macro_resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>, 192 macro_resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>,
191 mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError), 193 mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
192) -> Result<SyntaxNode, ErrorEmitted> { 194) -> Result<SyntaxNode, ErrorEmitted> {
193 let original = curr.value.clone(); 195 let original = curr.value.clone().clone_for_update();
194 196
195 let children = curr.value.descendants().filter_map(ast::MacroCall::cast); 197 let children = original.descendants().filter_map(ast::MacroCall::cast);
196 let mut rewriter = SyntaxRewriter::default(); 198 let mut replacements = Vec::new();
197 199
198 // Collect replacement 200 // Collect replacement
199 for child in children { 201 for child in children {
@@ -212,6 +214,7 @@ fn eager_macro_recur(
212 .into(); 214 .into();
213 db.parse_or_expand(id.as_file()) 215 db.parse_or_expand(id.as_file())
214 .expect("successful macro expansion should be parseable") 216 .expect("successful macro expansion should be parseable")
217 .clone_for_update()
215 } 218 }
216 MacroDefKind::Declarative(_) 219 MacroDefKind::Declarative(_)
217 | MacroDefKind::BuiltIn(..) 220 | MacroDefKind::BuiltIn(..)
@@ -225,15 +228,14 @@ fn eager_macro_recur(
225 } 228 }
226 }; 229 };
227 230
228 // check if the whole original sytnax is replaced 231 // check if the whole original syntax is replaced
229 // Note that SyntaxRewriter cannot replace the root node itself
230 if child.syntax() == &original { 232 if child.syntax() == &original {
231 return Ok(insert); 233 return Ok(insert);
232 } 234 }
233 235
234 rewriter.replace(child.syntax(), &insert); 236 replacements.push((child, insert));
235 } 237 }
236 238
237 let res = rewriter.rewrite(&original); 239 replacements.into_iter().rev().for_each(|(old, new)| ted::replace(old.syntax(), new));
238 Ok(res) 240 Ok(original)
239} 241}
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index 3e332ee47..a0e6aec62 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -290,22 +290,27 @@ pub struct MacroCallLoc {
290 290
291#[derive(Debug, Clone, PartialEq, Eq, Hash)] 291#[derive(Debug, Clone, PartialEq, Eq, Hash)]
292pub enum MacroCallKind { 292pub enum MacroCallKind {
293 FnLike(AstId<ast::MacroCall>), 293 FnLike { ast_id: AstId<ast::MacroCall> },
294 Derive(AstId<ast::Item>, String), 294 Derive { ast_id: AstId<ast::Item>, derive_name: String, derive_attr: AttrId },
295} 295}
296 296
297#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
298pub struct AttrId(pub u32);
299
297impl MacroCallKind { 300impl MacroCallKind {
298 fn file_id(&self) -> HirFileId { 301 fn file_id(&self) -> HirFileId {
299 match self { 302 match self {
300 MacroCallKind::FnLike(ast_id) => ast_id.file_id, 303 MacroCallKind::FnLike { ast_id, .. } => ast_id.file_id,
301 MacroCallKind::Derive(ast_id, _) => ast_id.file_id, 304 MacroCallKind::Derive { ast_id, .. } => ast_id.file_id,
302 } 305 }
303 } 306 }
304 307
305 fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> { 308 fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> {
306 match self { 309 match self {
307 MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()), 310 MacroCallKind::FnLike { ast_id, .. } => {
308 MacroCallKind::Derive(ast_id, _) => { 311 ast_id.with_value(ast_id.to_node(db).syntax().clone())
312 }
313 MacroCallKind::Derive { ast_id, .. } => {
309 ast_id.with_value(ast_id.to_node(db).syntax().clone()) 314 ast_id.with_value(ast_id.to_node(db).syntax().clone())
310 } 315 }
311 } 316 }
@@ -313,10 +318,10 @@ impl MacroCallKind {
313 318
314 fn arg(&self, db: &dyn db::AstDatabase) -> Option<SyntaxNode> { 319 fn arg(&self, db: &dyn db::AstDatabase) -> Option<SyntaxNode> {
315 match self { 320 match self {
316 MacroCallKind::FnLike(ast_id) => { 321 MacroCallKind::FnLike { ast_id, .. } => {
317 Some(ast_id.to_node(db).token_tree()?.syntax().clone()) 322 Some(ast_id.to_node(db).token_tree()?.syntax().clone())
318 } 323 }
319 MacroCallKind::Derive(ast_id, _) => Some(ast_id.to_node(db).syntax().clone()), 324 MacroCallKind::Derive { ast_id, .. } => Some(ast_id.to_node(db).syntax().clone()),
320 } 325 }
321 } 326 }
322} 327}
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index a0f8766b0..bcfd3e524 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -221,6 +221,7 @@ pub mod known {
221 option_env, 221 option_env,
222 llvm_asm, 222 llvm_asm,
223 asm, 223 asm,
224 global_asm,
224 // Builtin derives 225 // Builtin derives
225 Copy, 226 Copy,
226 Clone, 227 Clone,