aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_expand/src
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-05-19 19:19:08 +0100
committerJonas Schievink <[email protected]>2021-05-19 19:19:08 +0100
commitea8555b1552f6c08043f84885e47a196320da376 (patch)
tree6a9644cf1375b42885cdf4680476720ce6fbd0cc /crates/hir_expand/src
parentc7196620abd5e9bab4fbd53388da361f0f6987a1 (diff)
Simplify eager macro representation
Diffstat (limited to 'crates/hir_expand/src')
-rw-r--r--crates/hir_expand/src/builtin_derive.rs25
-rw-r--r--crates/hir_expand/src/builtin_macro.rs81
-rw-r--r--crates/hir_expand/src/db.rs120
-rw-r--r--crates/hir_expand/src/eager.rs32
-rw-r--r--crates/hir_expand/src/hygiene.rs34
-rw-r--r--crates/hir_expand/src/input.rs4
-rw-r--r--crates/hir_expand/src/lib.rs124
7 files changed, 156 insertions, 264 deletions
diff --git a/crates/hir_expand/src/builtin_derive.rs b/crates/hir_expand/src/builtin_derive.rs
index b6a6d602f..fe9497b50 100644
--- a/crates/hir_expand/src/builtin_derive.rs
+++ b/crates/hir_expand/src/builtin_derive.rs
@@ -8,7 +8,7 @@ use syntax::{
8 match_ast, 8 match_ast,
9}; 9};
10 10
11use crate::{db::AstDatabase, name, quote, AstId, CrateId, LazyMacroId, MacroDefId, MacroDefKind}; 11use crate::{db::AstDatabase, name, quote, AstId, CrateId, MacroCallId, MacroDefId, MacroDefKind};
12 12
13macro_rules! register_builtin { 13macro_rules! register_builtin {
14 ( $($trait:ident => $expand:ident),* ) => { 14 ( $($trait:ident => $expand:ident),* ) => {
@@ -21,7 +21,7 @@ macro_rules! register_builtin {
21 pub fn expand( 21 pub fn expand(
22 &self, 22 &self,
23 db: &dyn AstDatabase, 23 db: &dyn AstDatabase,
24 id: LazyMacroId, 24 id: MacroCallId,
25 tt: &tt::Subtree, 25 tt: &tt::Subtree,
26 ) -> Result<tt::Subtree, mbe::ExpandError> { 26 ) -> Result<tt::Subtree, mbe::ExpandError> {
27 let expander = match *self { 27 let expander = match *self {
@@ -164,7 +164,7 @@ fn expand_simple_derive(
164 Ok(expanded) 164 Ok(expanded)
165} 165}
166 166
167fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { 167fn find_builtin_crate(db: &dyn AstDatabase, id: MacroCallId) -> tt::TokenTree {
168 // FIXME: make hygiene works for builtin derive macro 168 // FIXME: make hygiene works for builtin derive macro
169 // such that $crate can be used here. 169 // such that $crate can be used here.
170 let cg = db.crate_graph(); 170 let cg = db.crate_graph();
@@ -184,7 +184,7 @@ fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree {
184 184
185fn copy_expand( 185fn copy_expand(
186 db: &dyn AstDatabase, 186 db: &dyn AstDatabase,
187 id: LazyMacroId, 187 id: MacroCallId,
188 tt: &tt::Subtree, 188 tt: &tt::Subtree,
189) -> Result<tt::Subtree, mbe::ExpandError> { 189) -> Result<tt::Subtree, mbe::ExpandError> {
190 let krate = find_builtin_crate(db, id); 190 let krate = find_builtin_crate(db, id);
@@ -193,7 +193,7 @@ fn copy_expand(
193 193
194fn clone_expand( 194fn clone_expand(
195 db: &dyn AstDatabase, 195 db: &dyn AstDatabase,
196 id: LazyMacroId, 196 id: MacroCallId,
197 tt: &tt::Subtree, 197 tt: &tt::Subtree,
198) -> Result<tt::Subtree, mbe::ExpandError> { 198) -> Result<tt::Subtree, mbe::ExpandError> {
199 let krate = find_builtin_crate(db, id); 199 let krate = find_builtin_crate(db, id);
@@ -202,7 +202,7 @@ fn clone_expand(
202 202
203fn default_expand( 203fn default_expand(
204 db: &dyn AstDatabase, 204 db: &dyn AstDatabase,
205 id: LazyMacroId, 205 id: MacroCallId,
206 tt: &tt::Subtree, 206 tt: &tt::Subtree,
207) -> Result<tt::Subtree, mbe::ExpandError> { 207) -> Result<tt::Subtree, mbe::ExpandError> {
208 let krate = find_builtin_crate(db, id); 208 let krate = find_builtin_crate(db, id);
@@ -211,7 +211,7 @@ fn default_expand(
211 211
212fn debug_expand( 212fn debug_expand(
213 db: &dyn AstDatabase, 213 db: &dyn AstDatabase,
214 id: LazyMacroId, 214 id: MacroCallId,
215 tt: &tt::Subtree, 215 tt: &tt::Subtree,
216) -> Result<tt::Subtree, mbe::ExpandError> { 216) -> Result<tt::Subtree, mbe::ExpandError> {
217 let krate = find_builtin_crate(db, id); 217 let krate = find_builtin_crate(db, id);
@@ -220,7 +220,7 @@ fn debug_expand(
220 220
221fn hash_expand( 221fn hash_expand(
222 db: &dyn AstDatabase, 222 db: &dyn AstDatabase,
223 id: LazyMacroId, 223 id: MacroCallId,
224 tt: &tt::Subtree, 224 tt: &tt::Subtree,
225) -> Result<tt::Subtree, mbe::ExpandError> { 225) -> Result<tt::Subtree, mbe::ExpandError> {
226 let krate = find_builtin_crate(db, id); 226 let krate = find_builtin_crate(db, id);
@@ -229,7 +229,7 @@ fn hash_expand(
229 229
230fn eq_expand( 230fn eq_expand(
231 db: &dyn AstDatabase, 231 db: &dyn AstDatabase,
232 id: LazyMacroId, 232 id: MacroCallId,
233 tt: &tt::Subtree, 233 tt: &tt::Subtree,
234) -> Result<tt::Subtree, mbe::ExpandError> { 234) -> Result<tt::Subtree, mbe::ExpandError> {
235 let krate = find_builtin_crate(db, id); 235 let krate = find_builtin_crate(db, id);
@@ -238,7 +238,7 @@ fn eq_expand(
238 238
239fn partial_eq_expand( 239fn partial_eq_expand(
240 db: &dyn AstDatabase, 240 db: &dyn AstDatabase,
241 id: LazyMacroId, 241 id: MacroCallId,
242 tt: &tt::Subtree, 242 tt: &tt::Subtree,
243) -> Result<tt::Subtree, mbe::ExpandError> { 243) -> Result<tt::Subtree, mbe::ExpandError> {
244 let krate = find_builtin_crate(db, id); 244 let krate = find_builtin_crate(db, id);
@@ -247,7 +247,7 @@ fn partial_eq_expand(
247 247
248fn ord_expand( 248fn ord_expand(
249 db: &dyn AstDatabase, 249 db: &dyn AstDatabase,
250 id: LazyMacroId, 250 id: MacroCallId,
251 tt: &tt::Subtree, 251 tt: &tt::Subtree,
252) -> Result<tt::Subtree, mbe::ExpandError> { 252) -> Result<tt::Subtree, mbe::ExpandError> {
253 let krate = find_builtin_crate(db, id); 253 let krate = find_builtin_crate(db, id);
@@ -256,7 +256,7 @@ fn ord_expand(
256 256
257fn partial_ord_expand( 257fn partial_ord_expand(
258 db: &dyn AstDatabase, 258 db: &dyn AstDatabase,
259 id: LazyMacroId, 259 id: MacroCallId,
260 tt: &tt::Subtree, 260 tt: &tt::Subtree,
261) -> Result<tt::Subtree, mbe::ExpandError> { 261) -> Result<tt::Subtree, mbe::ExpandError> {
262 let krate = find_builtin_crate(db, id); 262 let krate = find_builtin_crate(db, id);
@@ -317,6 +317,7 @@ $0
317 local_inner: false, 317 local_inner: false,
318 }, 318 },
319 krate: CrateId(0), 319 krate: CrateId(0),
320 eager: None,
320 kind: MacroCallKind::Derive { 321 kind: MacroCallKind::Derive {
321 ast_id, 322 ast_id,
322 derive_name: name.to_string(), 323 derive_name: name.to_string(),
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 280c25f11..09ac16700 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -1,7 +1,7 @@
1//! Builtin macro 1//! Builtin macro
2use crate::{ 2use crate::{
3 db::AstDatabase, name, quote, AstId, CrateId, EagerMacroId, LazyMacroId, MacroCallId, 3 db::AstDatabase, name, quote, AstId, CrateId, MacroCallId, MacroCallLoc, MacroDefId,
4 MacroCallLoc, MacroDefId, MacroDefKind, TextSize, 4 MacroDefKind, TextSize,
5}; 5};
6 6
7use base_db::{AnchoredPath, Edition, FileId}; 7use base_db::{AnchoredPath, Edition, FileId};
@@ -27,7 +27,7 @@ macro_rules! register_builtin {
27 pub fn expand( 27 pub fn expand(
28 &self, 28 &self,
29 db: &dyn AstDatabase, 29 db: &dyn AstDatabase,
30 id: LazyMacroId, 30 id: MacroCallId,
31 tt: &tt::Subtree, 31 tt: &tt::Subtree,
32 ) -> ExpandResult<tt::Subtree> { 32 ) -> ExpandResult<tt::Subtree> {
33 let expander = match *self { 33 let expander = match *self {
@@ -41,7 +41,7 @@ macro_rules! register_builtin {
41 pub fn expand( 41 pub fn expand(
42 &self, 42 &self,
43 db: &dyn AstDatabase, 43 db: &dyn AstDatabase,
44 arg_id: EagerMacroId, 44 arg_id: MacroCallId,
45 tt: &tt::Subtree, 45 tt: &tt::Subtree,
46 ) -> ExpandResult<Option<ExpandedEager>> { 46 ) -> ExpandResult<Option<ExpandedEager>> {
47 let expander = match *self { 47 let expander = match *self {
@@ -128,7 +128,7 @@ register_builtin! {
128 128
129fn module_path_expand( 129fn module_path_expand(
130 _db: &dyn AstDatabase, 130 _db: &dyn AstDatabase,
131 _id: LazyMacroId, 131 _id: MacroCallId,
132 _tt: &tt::Subtree, 132 _tt: &tt::Subtree,
133) -> ExpandResult<tt::Subtree> { 133) -> ExpandResult<tt::Subtree> {
134 // Just return a dummy result. 134 // Just return a dummy result.
@@ -137,7 +137,7 @@ fn module_path_expand(
137 137
138fn line_expand( 138fn line_expand(
139 _db: &dyn AstDatabase, 139 _db: &dyn AstDatabase,
140 _id: LazyMacroId, 140 _id: MacroCallId,
141 _tt: &tt::Subtree, 141 _tt: &tt::Subtree,
142) -> ExpandResult<tt::Subtree> { 142) -> ExpandResult<tt::Subtree> {
143 // dummy implementation for type-checking purposes 143 // dummy implementation for type-checking purposes
@@ -151,7 +151,7 @@ fn line_expand(
151 151
152fn stringify_expand( 152fn stringify_expand(
153 db: &dyn AstDatabase, 153 db: &dyn AstDatabase,
154 id: LazyMacroId, 154 id: MacroCallId,
155 _tt: &tt::Subtree, 155 _tt: &tt::Subtree,
156) -> ExpandResult<tt::Subtree> { 156) -> ExpandResult<tt::Subtree> {
157 let loc = db.lookup_intern_macro(id); 157 let loc = db.lookup_intern_macro(id);
@@ -176,7 +176,7 @@ fn stringify_expand(
176 176
177fn column_expand( 177fn column_expand(
178 _db: &dyn AstDatabase, 178 _db: &dyn AstDatabase,
179 _id: LazyMacroId, 179 _id: MacroCallId,
180 _tt: &tt::Subtree, 180 _tt: &tt::Subtree,
181) -> ExpandResult<tt::Subtree> { 181) -> ExpandResult<tt::Subtree> {
182 // dummy implementation for type-checking purposes 182 // dummy implementation for type-checking purposes
@@ -190,7 +190,7 @@ fn column_expand(
190 190
191fn assert_expand( 191fn assert_expand(
192 _db: &dyn AstDatabase, 192 _db: &dyn AstDatabase,
193 _id: LazyMacroId, 193 _id: MacroCallId,
194 tt: &tt::Subtree, 194 tt: &tt::Subtree,
195) -> ExpandResult<tt::Subtree> { 195) -> ExpandResult<tt::Subtree> {
196 // A hacky implementation for goto def and hover 196 // A hacky implementation for goto def and hover
@@ -214,7 +214,7 @@ fn assert_expand(
214 214
215fn file_expand( 215fn file_expand(
216 _db: &dyn AstDatabase, 216 _db: &dyn AstDatabase,
217 _id: LazyMacroId, 217 _id: MacroCallId,
218 _tt: &tt::Subtree, 218 _tt: &tt::Subtree,
219) -> ExpandResult<tt::Subtree> { 219) -> ExpandResult<tt::Subtree> {
220 // FIXME: RA purposefully lacks knowledge of absolute file names 220 // FIXME: RA purposefully lacks knowledge of absolute file names
@@ -230,7 +230,7 @@ fn file_expand(
230 230
231fn format_args_expand( 231fn format_args_expand(
232 _db: &dyn AstDatabase, 232 _db: &dyn AstDatabase,
233 _id: LazyMacroId, 233 _id: MacroCallId,
234 tt: &tt::Subtree, 234 tt: &tt::Subtree,
235) -> ExpandResult<tt::Subtree> { 235) -> ExpandResult<tt::Subtree> {
236 // We expand `format_args!("", a1, a2)` to 236 // We expand `format_args!("", a1, a2)` to
@@ -265,7 +265,7 @@ fn format_args_expand(
265 265
266fn asm_expand( 266fn asm_expand(
267 _db: &dyn AstDatabase, 267 _db: &dyn AstDatabase,
268 _id: LazyMacroId, 268 _id: MacroCallId,
269 _tt: &tt::Subtree, 269 _tt: &tt::Subtree,
270) -> ExpandResult<tt::Subtree> { 270) -> ExpandResult<tt::Subtree> {
271 // both asm and llvm_asm don't return anything, so we can expand them to nothing, 271 // both asm and llvm_asm don't return anything, so we can expand them to nothing,
@@ -278,7 +278,7 @@ fn asm_expand(
278 278
279fn global_asm_expand( 279fn global_asm_expand(
280 _db: &dyn AstDatabase, 280 _db: &dyn AstDatabase,
281 _id: LazyMacroId, 281 _id: MacroCallId,
282 _tt: &tt::Subtree, 282 _tt: &tt::Subtree,
283) -> ExpandResult<tt::Subtree> { 283) -> ExpandResult<tt::Subtree> {
284 // Expand to nothing (at item-level) 284 // Expand to nothing (at item-level)
@@ -287,7 +287,7 @@ fn global_asm_expand(
287 287
288fn cfg_expand( 288fn cfg_expand(
289 db: &dyn AstDatabase, 289 db: &dyn AstDatabase,
290 id: LazyMacroId, 290 id: MacroCallId,
291 tt: &tt::Subtree, 291 tt: &tt::Subtree,
292) -> ExpandResult<tt::Subtree> { 292) -> ExpandResult<tt::Subtree> {
293 let loc = db.lookup_intern_macro(id); 293 let loc = db.lookup_intern_macro(id);
@@ -299,7 +299,7 @@ fn cfg_expand(
299 299
300fn panic_expand( 300fn panic_expand(
301 db: &dyn AstDatabase, 301 db: &dyn AstDatabase,
302 id: LazyMacroId, 302 id: MacroCallId,
303 tt: &tt::Subtree, 303 tt: &tt::Subtree,
304) -> ExpandResult<tt::Subtree> { 304) -> ExpandResult<tt::Subtree> {
305 let loc: MacroCallLoc = db.lookup_intern_macro(id); 305 let loc: MacroCallLoc = db.lookup_intern_macro(id);
@@ -324,7 +324,7 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> {
324 324
325fn compile_error_expand( 325fn compile_error_expand(
326 _db: &dyn AstDatabase, 326 _db: &dyn AstDatabase,
327 _id: EagerMacroId, 327 _id: MacroCallId,
328 tt: &tt::Subtree, 328 tt: &tt::Subtree,
329) -> ExpandResult<Option<ExpandedEager>> { 329) -> ExpandResult<Option<ExpandedEager>> {
330 let err = match &*tt.token_trees { 330 let err = match &*tt.token_trees {
@@ -345,7 +345,7 @@ fn compile_error_expand(
345 345
346fn concat_expand( 346fn concat_expand(
347 _db: &dyn AstDatabase, 347 _db: &dyn AstDatabase,
348 _arg_id: EagerMacroId, 348 _arg_id: MacroCallId,
349 tt: &tt::Subtree, 349 tt: &tt::Subtree,
350) -> ExpandResult<Option<ExpandedEager>> { 350) -> ExpandResult<Option<ExpandedEager>> {
351 let mut err = None; 351 let mut err = None;
@@ -376,7 +376,7 @@ fn concat_expand(
376 376
377fn concat_idents_expand( 377fn concat_idents_expand(
378 _db: &dyn AstDatabase, 378 _db: &dyn AstDatabase,
379 _arg_id: EagerMacroId, 379 _arg_id: MacroCallId,
380 tt: &tt::Subtree, 380 tt: &tt::Subtree,
381) -> ExpandResult<Option<ExpandedEager>> { 381) -> ExpandResult<Option<ExpandedEager>> {
382 let mut err = None; 382 let mut err = None;
@@ -427,7 +427,7 @@ fn parse_string(tt: &tt::Subtree) -> Result<String, mbe::ExpandError> {
427 427
428fn include_expand( 428fn include_expand(
429 db: &dyn AstDatabase, 429 db: &dyn AstDatabase,
430 arg_id: EagerMacroId, 430 arg_id: MacroCallId,
431 tt: &tt::Subtree, 431 tt: &tt::Subtree,
432) -> ExpandResult<Option<ExpandedEager>> { 432) -> ExpandResult<Option<ExpandedEager>> {
433 let res = (|| { 433 let res = (|| {
@@ -457,7 +457,7 @@ fn include_expand(
457 457
458fn include_bytes_expand( 458fn include_bytes_expand(
459 _db: &dyn AstDatabase, 459 _db: &dyn AstDatabase,
460 _arg_id: EagerMacroId, 460 _arg_id: MacroCallId,
461 tt: &tt::Subtree, 461 tt: &tt::Subtree,
462) -> ExpandResult<Option<ExpandedEager>> { 462) -> ExpandResult<Option<ExpandedEager>> {
463 if let Err(e) = parse_string(tt) { 463 if let Err(e) = parse_string(tt) {
@@ -477,7 +477,7 @@ fn include_bytes_expand(
477 477
478fn include_str_expand( 478fn include_str_expand(
479 db: &dyn AstDatabase, 479 db: &dyn AstDatabase,
480 arg_id: EagerMacroId, 480 arg_id: MacroCallId,
481 tt: &tt::Subtree, 481 tt: &tt::Subtree,
482) -> ExpandResult<Option<ExpandedEager>> { 482) -> ExpandResult<Option<ExpandedEager>> {
483 let path = match parse_string(tt) { 483 let path = match parse_string(tt) {
@@ -502,14 +502,14 @@ fn include_str_expand(
502 ExpandResult::ok(Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr))) 502 ExpandResult::ok(Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)))
503} 503}
504 504
505fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { 505fn get_env_inner(db: &dyn AstDatabase, arg_id: MacroCallId, key: &str) -> Option<String> {
506 let krate = db.lookup_intern_eager_expansion(arg_id).krate; 506 let krate = db.lookup_intern_macro(arg_id).krate;
507 db.crate_graph()[krate].env.get(key) 507 db.crate_graph()[krate].env.get(key)
508} 508}
509 509
510fn env_expand( 510fn env_expand(
511 db: &dyn AstDatabase, 511 db: &dyn AstDatabase,
512 arg_id: EagerMacroId, 512 arg_id: MacroCallId,
513 tt: &tt::Subtree, 513 tt: &tt::Subtree,
514) -> ExpandResult<Option<ExpandedEager>> { 514) -> ExpandResult<Option<ExpandedEager>> {
515 let key = match parse_string(tt) { 515 let key = match parse_string(tt) {
@@ -540,7 +540,7 @@ fn env_expand(
540 540
541fn option_env_expand( 541fn option_env_expand(
542 db: &dyn AstDatabase, 542 db: &dyn AstDatabase,
543 arg_id: EagerMacroId, 543 arg_id: MacroCallId,
544 tt: &tt::Subtree, 544 tt: &tt::Subtree,
545) -> ExpandResult<Option<ExpandedEager>> { 545) -> ExpandResult<Option<ExpandedEager>> {
546 let key = match parse_string(tt) { 546 let key = match parse_string(tt) {
@@ -560,7 +560,7 @@ fn option_env_expand(
560mod tests { 560mod tests {
561 use super::*; 561 use super::*;
562 use crate::{ 562 use crate::{
563 name::AsName, test_db::TestDB, AstNode, EagerCallLoc, MacroCallId, MacroCallKind, 563 name::AsName, test_db::TestDB, AstNode, EagerCallInfo, MacroCallId, MacroCallKind,
564 MacroCallLoc, 564 MacroCallLoc,
565 }; 565 };
566 use base_db::{fixture::WithFixture, SourceDatabase}; 566 use base_db::{fixture::WithFixture, SourceDatabase};
@@ -599,6 +599,7 @@ mod tests {
599 let loc = MacroCallLoc { 599 let loc = MacroCallLoc {
600 def, 600 def,
601 krate, 601 krate,
602 eager: None,
602 kind: MacroCallKind::FnLike { 603 kind: MacroCallKind::FnLike {
603 ast_id: AstId::new(file_id.into(), ast_id_map.ast_id(&macro_call)), 604 ast_id: AstId::new(file_id.into(), ast_id_map.ast_id(&macro_call)),
604 fragment: FragmentKind::Expr, 605 fragment: FragmentKind::Expr,
@@ -620,28 +621,28 @@ mod tests {
620 let parsed_args = mbe::ast_to_token_tree(&args).0; 621 let parsed_args = mbe::ast_to_token_tree(&args).0;
621 let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(&macro_call)); 622 let call_id = AstId::new(file_id.into(), ast_id_map.ast_id(&macro_call));
622 623
623 let arg_id = db.intern_eager_expansion({ 624 let arg_id = db.intern_macro(MacroCallLoc {
624 EagerCallLoc { 625 def,
625 def, 626 krate,
626 fragment: FragmentKind::Expr, 627 eager: Some(EagerCallInfo {
627 subtree: Arc::new(parsed_args.clone()), 628 expansion: Arc::new(parsed_args.clone()),
628 krate,
629 call: call_id,
630 included_file: None, 629 included_file: None,
631 } 630 }),
631 kind: MacroCallKind::FnLike { ast_id: call_id, fragment: FragmentKind::Expr },
632 }); 632 });
633 633
634 let expanded = expander.expand(&db, arg_id, &parsed_args).value.unwrap(); 634 let expanded = expander.expand(&db, arg_id, &parsed_args).value.unwrap();
635 let eager = EagerCallLoc { 635 let loc = MacroCallLoc {
636 def, 636 def,
637 fragment: expanded.fragment,
638 subtree: Arc::new(expanded.subtree),
639 krate, 637 krate,
640 call: call_id, 638 eager: Some(EagerCallInfo {
641 included_file: expanded.included_file, 639 expansion: Arc::new(expanded.subtree),
640 included_file: expanded.included_file,
641 }),
642 kind: MacroCallKind::FnLike { ast_id: call_id, fragment: expanded.fragment },
642 }; 643 };
643 644
644 let id: MacroCallId = db.intern_eager_expansion(eager).into(); 645 let id: MacroCallId = db.intern_macro(loc).into();
645 id.as_file() 646 id.as_file()
646 } 647 }
647 }; 648 };
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs
index c43d382ad..7a82400a8 100644
--- a/crates/hir_expand/src/db.rs
+++ b/crates/hir_expand/src/db.rs
@@ -13,8 +13,8 @@ use syntax::{
13 13
14use crate::{ 14use crate::{
15 ast_id_map::AstIdMap, hygiene::HygieneFrame, input::process_macro_input, BuiltinDeriveExpander, 15 ast_id_map::AstIdMap, hygiene::HygieneFrame, input::process_macro_input, BuiltinDeriveExpander,
16 BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, HirFileId, HirFileIdRepr, LazyMacroId, 16 BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, MacroCallId, MacroCallLoc, MacroDefId,
17 MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander, 17 MacroDefKind, MacroFile, ProcMacroExpander,
18}; 18};
19 19
20/// Total limit on the number of tokens produced by any macro invocation. 20/// Total limit on the number of tokens produced by any macro invocation.
@@ -41,7 +41,7 @@ impl TokenExpander {
41 fn expand( 41 fn expand(
42 &self, 42 &self,
43 db: &dyn AstDatabase, 43 db: &dyn AstDatabase,
44 id: LazyMacroId, 44 id: MacroCallId,
45 tt: &tt::Subtree, 45 tt: &tt::Subtree,
46 ) -> mbe::ExpandResult<tt::Subtree> { 46 ) -> mbe::ExpandResult<tt::Subtree> {
47 match self { 47 match self {
@@ -101,11 +101,7 @@ pub trait AstDatabase: SourceDatabase {
101 /// We encode macro definitions into ids of macro calls, this what allows us 101 /// We encode macro definitions into ids of macro calls, this what allows us
102 /// to be incremental. 102 /// to be incremental.
103 #[salsa::interned] 103 #[salsa::interned]
104 fn intern_macro(&self, macro_call: MacroCallLoc) -> LazyMacroId; 104 fn intern_macro(&self, macro_call: MacroCallLoc) -> MacroCallId;
105 /// Certain built-in macros are eager (`format!(concat!("file: ", file!(), "{}"")), 92`).
106 /// For them, we actually want to encode the whole token tree as an argument.
107 #[salsa::interned]
108 fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId;
109 105
110 /// Lowers syntactic macro call to a token tree representation. 106 /// Lowers syntactic macro call to a token tree representation.
111 #[salsa::transparent] 107 #[salsa::transparent]
@@ -146,17 +142,12 @@ pub fn expand_hypothetical(
146 token_to_map.text_range().checked_sub(hypothetical_args.syntax().text_range().start())?; 142 token_to_map.text_range().checked_sub(hypothetical_args.syntax().text_range().start())?;
147 let token_id = tmap_1.token_by_range(range)?; 143 let token_id = tmap_1.token_by_range(range)?;
148 144
149 let lazy_id = match actual_macro_call {
150 MacroCallId::LazyMacro(id) => id,
151 MacroCallId::EagerMacro(_) => return None,
152 };
153
154 let macro_def = { 145 let macro_def = {
155 let loc = db.lookup_intern_macro(lazy_id); 146 let loc: MacroCallLoc = db.lookup_intern_macro(actual_macro_call);
156 db.macro_def(loc.def)? 147 db.macro_def(loc.def)?
157 }; 148 };
158 149
159 let hypothetical_expansion = macro_def.expand(db, lazy_id, &tt); 150 let hypothetical_expansion = macro_def.expand(db, actual_macro_call, &tt);
160 151
161 let fragment_kind = macro_fragment_kind(db, actual_macro_call); 152 let fragment_kind = macro_fragment_kind(db, actual_macro_call);
162 153
@@ -194,30 +185,22 @@ fn parse_macro_expansion(
194 // Note: 185 // Note:
195 // The final goal we would like to make all parse_macro success, 186 // The final goal we would like to make all parse_macro success,
196 // such that the following log will not call anyway. 187 // such that the following log will not call anyway.
197 match macro_file.macro_call_id { 188 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
198 MacroCallId::LazyMacro(id) => { 189 let node = loc.kind.node(db);
199 let loc: MacroCallLoc = db.lookup_intern_macro(id); 190
200 let node = loc.kind.node(db); 191 // collect parent information for warning log
201 192 let parents =
202 // collect parent information for warning log 193 std::iter::successors(loc.kind.file_id().call_node(db), |it| it.file_id.call_node(db))
203 let parents = std::iter::successors(loc.kind.file_id().call_node(db), |it| {
204 it.file_id.call_node(db)
205 })
206 .map(|n| format!("{:#}", n.value)) 194 .map(|n| format!("{:#}", n.value))
207 .collect::<Vec<_>>() 195 .collect::<Vec<_>>()
208 .join("\n"); 196 .join("\n");
209 197
210 log::warn!( 198 log::warn!(
211 "fail on macro_parse: (reason: {:?} macro_call: {:#}) parents: {}", 199 "fail on macro_parse: (reason: {:?} macro_call: {:#}) parents: {}",
212 err, 200 err,
213 node.value, 201 node.value,
214 parents 202 parents
215 ); 203 );
216 }
217 _ => {
218 log::warn!("fail on macro_parse: (reason: {:?})", err);
219 }
220 }
221 } 204 }
222 let tt = match result.value { 205 let tt = match result.value {
223 Some(tt) => tt, 206 Some(tt) => tt,
@@ -269,25 +252,16 @@ fn macro_arg(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(tt::Subtree,
269 let arg = db.macro_arg_text(id)?; 252 let arg = db.macro_arg_text(id)?;
270 let (mut tt, tmap) = mbe::syntax_node_to_token_tree(&SyntaxNode::new_root(arg)); 253 let (mut tt, tmap) = mbe::syntax_node_to_token_tree(&SyntaxNode::new_root(arg));
271 254
272 if let MacroCallId::LazyMacro(id) = id { 255 let loc: MacroCallLoc = db.lookup_intern_macro(id);
273 let loc: MacroCallLoc = db.lookup_intern_macro(id); 256 if loc.def.is_proc_macro() {
274 if loc.def.is_proc_macro() { 257 // proc macros expect their inputs without parentheses, MBEs expect it with them included
275 // proc macros expect their inputs without parentheses, MBEs expect it with them included 258 tt.delimiter = None;
276 tt.delimiter = None;
277 }
278 } 259 }
279 260
280 Some(Arc::new((tt, tmap))) 261 Some(Arc::new((tt, tmap)))
281} 262}
282 263
283fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> { 264fn macro_arg_text(db: &dyn AstDatabase, id: MacroCallId) -> Option<GreenNode> {
284 let id = match id {
285 MacroCallId::LazyMacro(id) => id,
286 MacroCallId::EagerMacro(_id) => {
287 // FIXME: support macro_arg for eager macro
288 return None;
289 }
290 };
291 let loc = db.lookup_intern_macro(id); 265 let loc = db.lookup_intern_macro(id);
292 let arg = loc.kind.arg(db)?; 266 let arg = loc.kind.arg(db)?;
293 let arg = process_macro_input(db, arg, id); 267 let arg = process_macro_input(db, arg, id);
@@ -347,24 +321,21 @@ fn macro_expand_with_arg(
347 arg: Option<Arc<(tt::Subtree, mbe::TokenMap)>>, 321 arg: Option<Arc<(tt::Subtree, mbe::TokenMap)>>,
348) -> ExpandResult<Option<Arc<tt::Subtree>>> { 322) -> ExpandResult<Option<Arc<tt::Subtree>>> {
349 let _p = profile::span("macro_expand"); 323 let _p = profile::span("macro_expand");
350 let lazy_id = match id { 324 let loc: MacroCallLoc = db.lookup_intern_macro(id);
351 MacroCallId::LazyMacro(id) => id, 325 if let Some(eager) = &loc.eager {
352 MacroCallId::EagerMacro(id) => { 326 if arg.is_some() {
353 if arg.is_some() { 327 return ExpandResult::str_err(
354 return ExpandResult::str_err( 328 "hypothetical macro expansion not implemented for eager macro".to_owned(),
355 "hypothetical macro expansion not implemented for eager macro".to_owned(), 329 );
356 ); 330 } else {
357 } else { 331 return ExpandResult {
358 return ExpandResult { 332 value: Some(eager.expansion.clone()),
359 value: Some(db.lookup_intern_eager_expansion(id).subtree), 333 // FIXME: There could be errors here!
360 // FIXME: There could be errors here! 334 err: None,
361 err: None, 335 };
362 };
363 }
364 } 336 }
365 }; 337 }
366 338
367 let loc = db.lookup_intern_macro(lazy_id);
368 let macro_arg = match arg.or_else(|| db.macro_arg(id)) { 339 let macro_arg = match arg.or_else(|| db.macro_arg(id)) {
369 Some(it) => it, 340 Some(it) => it,
370 None => return ExpandResult::str_err("Fail to args in to tt::TokenTree".into()), 341 None => return ExpandResult::str_err("Fail to args in to tt::TokenTree".into()),
@@ -374,7 +345,7 @@ fn macro_expand_with_arg(
374 Some(it) => it, 345 Some(it) => it,
375 None => return ExpandResult::str_err("Fail to find macro definition".into()), 346 None => return ExpandResult::str_err("Fail to find macro definition".into()),
376 }; 347 };
377 let ExpandResult { value: tt, err } = macro_rules.expand(db, lazy_id, &macro_arg.0); 348 let ExpandResult { value: tt, err } = macro_rules.expand(db, id, &macro_arg.0);
378 // Set a hard limit for the expanded tt 349 // Set a hard limit for the expanded tt
379 let count = tt.count(); 350 let count = tt.count();
380 if count > TOKEN_LIMIT { 351 if count > TOKEN_LIMIT {
@@ -391,12 +362,7 @@ fn expand_proc_macro(
391 db: &dyn AstDatabase, 362 db: &dyn AstDatabase,
392 id: MacroCallId, 363 id: MacroCallId,
393) -> Result<tt::Subtree, mbe::ExpandError> { 364) -> Result<tt::Subtree, mbe::ExpandError> {
394 let lazy_id = match id { 365 let loc: MacroCallLoc = db.lookup_intern_macro(id);
395 MacroCallId::LazyMacro(id) => id,
396 MacroCallId::EagerMacro(_) => unreachable!(),
397 };
398
399 let loc = db.lookup_intern_macro(lazy_id);
400 let macro_arg = match db.macro_arg(id) { 366 let macro_arg = match db.macro_arg(id) {
401 Some(it) => it, 367 Some(it) => it,
402 None => { 368 None => {
@@ -436,14 +402,6 @@ fn hygiene_frame(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<HygieneFrame>
436} 402}
437 403
438fn macro_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind { 404fn macro_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
439 match id { 405 let loc: MacroCallLoc = db.lookup_intern_macro(id);
440 MacroCallId::LazyMacro(id) => { 406 loc.kind.fragment_kind()
441 let loc: MacroCallLoc = db.lookup_intern_macro(id);
442 loc.kind.fragment_kind()
443 }
444 MacroCallId::EagerMacro(id) => {
445 let loc: EagerCallLoc = db.lookup_intern_eager_expansion(id);
446 loc.fragment
447 }
448 }
449} 407}
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs
index 85491fe8b..5e30ab930 100644
--- a/crates/hir_expand/src/eager.rs
+++ b/crates/hir_expand/src/eager.rs
@@ -22,7 +22,7 @@
22use crate::{ 22use crate::{
23 ast::{self, AstNode}, 23 ast::{self, AstNode},
24 db::AstDatabase, 24 db::AstDatabase,
25 EagerCallLoc, EagerMacroId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 25 EagerCallInfo, InFile, MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
26}; 26};
27 27
28use base_db::CrateId; 28use base_db::CrateId;
@@ -105,7 +105,7 @@ pub fn expand_eager_macro(
105 def: MacroDefId, 105 def: MacroDefId,
106 resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>, 106 resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>,
107 mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError), 107 mut diagnostic_sink: &mut dyn FnMut(mbe::ExpandError),
108) -> Result<EagerMacroId, ErrorEmitted> { 108) -> Result<MacroCallId, ErrorEmitted> {
109 let parsed_args = diagnostic_sink.option_with( 109 let parsed_args = diagnostic_sink.option_with(
110 || Some(mbe::ast_to_token_tree(&macro_call.value.token_tree()?).0), 110 || Some(mbe::ast_to_token_tree(&macro_call.value.token_tree()?).0),
111 || err("malformed macro invocation"), 111 || err("malformed macro invocation"),
@@ -118,15 +118,14 @@ pub fn expand_eager_macro(
118 // When `lazy_expand` is called, its *parent* file must be already exists. 118 // When `lazy_expand` is called, its *parent* file must be already exists.
119 // Here we store an eager macro id for the argument expanded subtree here 119 // Here we store an eager macro id for the argument expanded subtree here
120 // for that purpose. 120 // for that purpose.
121 let arg_id = db.intern_eager_expansion({ 121 let arg_id = db.intern_macro(MacroCallLoc {
122 EagerCallLoc { 122 def,
123 def, 123 krate,
124 fragment: FragmentKind::Expr, 124 eager: Some(EagerCallInfo {
125 subtree: Arc::new(parsed_args.clone()), 125 expansion: Arc::new(parsed_args.clone()),
126 krate,
127 call: call_id,
128 included_file: None, 126 included_file: None,
129 } 127 }),
128 kind: MacroCallKind::FnLike { ast_id: call_id, fragment: FragmentKind::Expr },
130 }); 129 });
131 let arg_file_id: MacroCallId = arg_id.into(); 130 let arg_file_id: MacroCallId = arg_id.into();
132 131
@@ -146,16 +145,17 @@ pub fn expand_eager_macro(
146 let res = eager.expand(db, arg_id, &subtree); 145 let res = eager.expand(db, arg_id, &subtree);
147 146
148 let expanded = diagnostic_sink.expand_result_option(res)?; 147 let expanded = diagnostic_sink.expand_result_option(res)?;
149 let eager = EagerCallLoc { 148 let loc = MacroCallLoc {
150 def, 149 def,
151 fragment: expanded.fragment,
152 subtree: Arc::new(expanded.subtree),
153 krate, 150 krate,
154 call: call_id, 151 eager: Some(EagerCallInfo {
155 included_file: expanded.included_file, 152 expansion: Arc::new(expanded.subtree),
153 included_file: expanded.included_file,
154 }),
155 kind: MacroCallKind::FnLike { ast_id: call_id, fragment: expanded.fragment },
156 }; 156 };
157 157
158 Ok(db.intern_eager_expansion(eager)) 158 Ok(db.intern_macro(loc))
159 } else { 159 } else {
160 panic!("called `expand_eager_macro` on non-eager macro def {:?}", def); 160 panic!("called `expand_eager_macro` on non-eager macro def {:?}", def);
161 } 161 }
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs
index aca69e35a..38e09fdd4 100644
--- a/crates/hir_expand/src/hygiene.rs
+++ b/crates/hir_expand/src/hygiene.rs
@@ -14,7 +14,7 @@ use syntax::{ast, AstNode, SyntaxNode, TextRange, TextSize};
14use crate::{ 14use crate::{
15 db::{self, AstDatabase}, 15 db::{self, AstDatabase},
16 name::{AsName, Name}, 16 name::{AsName, Name},
17 HirFileId, HirFileIdRepr, InFile, MacroCallId, MacroCallLoc, MacroDefKind, MacroFile, 17 HirFileId, HirFileIdRepr, InFile, MacroCallLoc, MacroDefKind, MacroFile,
18}; 18};
19 19
20#[derive(Clone, Debug)] 20#[derive(Clone, Debug)]
@@ -140,10 +140,7 @@ impl HygieneInfo {
140 let (token_id, origin) = self.macro_def.map_id_up(token_id); 140 let (token_id, origin) = self.macro_def.map_id_up(token_id);
141 let (token_map, tt) = match origin { 141 let (token_map, tt) = match origin {
142 mbe::Origin::Call => { 142 mbe::Origin::Call => {
143 let call_id = match self.file.macro_call_id { 143 let call_id = self.file.macro_call_id;
144 MacroCallId::LazyMacro(lazy) => lazy,
145 MacroCallId::EagerMacro(_) => unreachable!(),
146 };
147 let loc: MacroCallLoc = db.lookup_intern_macro(call_id); 144 let loc: MacroCallLoc = db.lookup_intern_macro(call_id);
148 let arg_start = loc.kind.arg(db)?.text_range().start(); 145 let arg_start = loc.kind.arg(db)?.text_range().start();
149 (&self.macro_arg.1, InFile::new(loc.kind.file_id(), arg_start)) 146 (&self.macro_arg.1, InFile::new(loc.kind.file_id(), arg_start))
@@ -186,23 +183,20 @@ impl HygieneFrame {
186 pub(crate) fn new(db: &dyn AstDatabase, file_id: HirFileId) -> HygieneFrame { 183 pub(crate) fn new(db: &dyn AstDatabase, file_id: HirFileId) -> HygieneFrame {
187 let (info, krate, local_inner) = match file_id.0 { 184 let (info, krate, local_inner) = match file_id.0 {
188 HirFileIdRepr::FileId(_) => (None, None, false), 185 HirFileIdRepr::FileId(_) => (None, None, false),
189 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { 186 HirFileIdRepr::MacroFile(macro_file) => {
190 MacroCallId::EagerMacro(_id) => (None, None, false), 187 let loc = db.lookup_intern_macro(macro_file.macro_call_id);
191 MacroCallId::LazyMacro(id) => { 188 let info =
192 let loc = db.lookup_intern_macro(id); 189 make_hygiene_info(db, macro_file, &loc).map(|info| (loc.kind.file_id(), info));
193 let info = make_hygiene_info(db, macro_file, &loc) 190 match loc.def.kind {
194 .map(|info| (loc.kind.file_id(), info)); 191 MacroDefKind::Declarative(_) => {
195 match loc.def.kind { 192 (info, Some(loc.def.krate), loc.def.local_inner)
196 MacroDefKind::Declarative(_) => {
197 (info, Some(loc.def.krate), loc.def.local_inner)
198 }
199 MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false),
200 MacroDefKind::BuiltInDerive(..) => (info, None, false),
201 MacroDefKind::BuiltInEager(..) => (info, None, false),
202 MacroDefKind::ProcMacro(..) => (info, None, false),
203 } 193 }
194 MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false),
195 MacroDefKind::BuiltInDerive(..) => (info, None, false),
196 MacroDefKind::BuiltInEager(..) => (info, None, false),
197 MacroDefKind::ProcMacro(..) => (info, None, false),
204 } 198 }
205 }, 199 }
206 }; 200 };
207 201
208 let (calling_file, info) = match info { 202 let (calling_file, info) = match info {
diff --git a/crates/hir_expand/src/input.rs b/crates/hir_expand/src/input.rs
index 112216859..fe4790e7b 100644
--- a/crates/hir_expand/src/input.rs
+++ b/crates/hir_expand/src/input.rs
@@ -8,13 +8,13 @@ use syntax::{
8use crate::{ 8use crate::{
9 db::AstDatabase, 9 db::AstDatabase,
10 name::{name, AsName}, 10 name::{name, AsName},
11 LazyMacroId, MacroCallKind, MacroCallLoc, 11 MacroCallId, MacroCallKind, MacroCallLoc,
12}; 12};
13 13
14pub(crate) fn process_macro_input( 14pub(crate) fn process_macro_input(
15 db: &dyn AstDatabase, 15 db: &dyn AstDatabase,
16 node: SyntaxNode, 16 node: SyntaxNode,
17 id: LazyMacroId, 17 id: MacroCallId,
18) -> SyntaxNode { 18) -> SyntaxNode {
19 let loc: MacroCallLoc = db.lookup_intern_macro(id); 19 let loc: MacroCallLoc = db.lookup_intern_macro(id);
20 20
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index 88cb16ca4..edd5f9db2 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -80,19 +80,10 @@ impl HirFileId {
80 match self.0 { 80 match self.0 {
81 HirFileIdRepr::FileId(file_id) => file_id, 81 HirFileIdRepr::FileId(file_id) => file_id,
82 HirFileIdRepr::MacroFile(macro_file) => { 82 HirFileIdRepr::MacroFile(macro_file) => {
83 let file_id = match macro_file.macro_call_id { 83 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
84 MacroCallId::LazyMacro(id) => { 84 let file_id = match &loc.eager {
85 let loc = db.lookup_intern_macro(id); 85 Some(EagerCallInfo { included_file: Some(file), .. }) => (*file).into(),
86 loc.kind.file_id() 86 _ => loc.kind.file_id(),
87 }
88 MacroCallId::EagerMacro(id) => {
89 let loc = db.lookup_intern_eager_expansion(id);
90 if let Some(included_file) = loc.included_file {
91 return included_file;
92 } else {
93 loc.call.file_id
94 }
95 }
96 }; 87 };
97 file_id.original_file(db) 88 file_id.original_file(db)
98 } 89 }
@@ -103,17 +94,10 @@ impl HirFileId {
103 let mut level = 0; 94 let mut level = 0;
104 let mut curr = self; 95 let mut curr = self;
105 while let HirFileIdRepr::MacroFile(macro_file) = curr.0 { 96 while let HirFileIdRepr::MacroFile(macro_file) = curr.0 {
97 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
98
106 level += 1; 99 level += 1;
107 curr = match macro_file.macro_call_id { 100 curr = loc.kind.file_id();
108 MacroCallId::LazyMacro(id) => {
109 let loc = db.lookup_intern_macro(id);
110 loc.kind.file_id()
111 }
112 MacroCallId::EagerMacro(id) => {
113 let loc = db.lookup_intern_eager_expansion(id);
114 loc.call.file_id
115 }
116 };
117 } 101 }
118 level 102 level
119 } 103 }
@@ -122,16 +106,10 @@ impl HirFileId {
122 pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> { 106 pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> {
123 match self.0 { 107 match self.0 {
124 HirFileIdRepr::FileId(_) => None, 108 HirFileIdRepr::FileId(_) => None,
125 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { 109 HirFileIdRepr::MacroFile(macro_file) => {
126 MacroCallId::LazyMacro(lazy_id) => { 110 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
127 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); 111 Some(loc.kind.node(db))
128 Some(loc.kind.node(db)) 112 }
129 }
130 MacroCallId::EagerMacro(id) => {
131 let loc: EagerCallLoc = db.lookup_intern_eager_expansion(id);
132 Some(loc.call.with_value(loc.call.to_node(db).syntax().clone()))
133 }
134 },
135 } 113 }
136 } 114 }
137 115
@@ -140,14 +118,7 @@ impl HirFileId {
140 match self.0 { 118 match self.0 {
141 HirFileIdRepr::FileId(_) => None, 119 HirFileIdRepr::FileId(_) => None,
142 HirFileIdRepr::MacroFile(macro_file) => { 120 HirFileIdRepr::MacroFile(macro_file) => {
143 let lazy_id = match macro_file.macro_call_id { 121 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
144 MacroCallId::LazyMacro(id) => id,
145 MacroCallId::EagerMacro(_id) => {
146 // FIXME: handle expansion_info for eager macro
147 return None;
148 }
149 };
150 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
151 122
152 let arg_tt = loc.kind.arg(db)?; 123 let arg_tt = loc.kind.arg(db)?;
153 124
@@ -180,13 +151,7 @@ impl HirFileId {
180 match self.0 { 151 match self.0 {
181 HirFileIdRepr::FileId(_) => None, 152 HirFileIdRepr::FileId(_) => None,
182 HirFileIdRepr::MacroFile(macro_file) => { 153 HirFileIdRepr::MacroFile(macro_file) => {
183 let lazy_id = match macro_file.macro_call_id { 154 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
184 MacroCallId::LazyMacro(id) => id,
185 MacroCallId::EagerMacro(_id) => {
186 return None;
187 }
188 };
189 let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id);
190 let item = match loc.def.kind { 155 let item = match loc.def.kind {
191 MacroDefKind::BuiltInDerive(..) => loc.kind.node(db), 156 MacroDefKind::BuiltInDerive(..) => loc.kind.node(db),
192 _ => return None, 157 _ => return None,
@@ -199,16 +164,12 @@ impl HirFileId {
199 /// Return whether this file is an include macro 164 /// Return whether this file is an include macro
200 pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool { 165 pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool {
201 match self.0 { 166 match self.0 {
202 HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { 167 HirFileIdRepr::MacroFile(macro_file) => {
203 MacroCallId::EagerMacro(id) => { 168 let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id);
204 let loc = db.lookup_intern_eager_expansion(id); 169 matches!(loc.eager, Some(EagerCallInfo { included_file: Some(_), .. }))
205 return loc.included_file.is_some(); 170 }
206 } 171 _ => false,
207 _ => {}
208 },
209 _ => {}
210 } 172 }
211 false
212 } 173 }
213} 174}
214 175
@@ -220,29 +181,8 @@ pub struct MacroFile {
220/// `MacroCallId` identifies a particular macro invocation, like 181/// `MacroCallId` identifies a particular macro invocation, like
221/// `println!("Hello, {}", world)`. 182/// `println!("Hello, {}", world)`.
222#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 183#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
223pub enum MacroCallId { 184pub struct MacroCallId(salsa::InternId);
224 LazyMacro(LazyMacroId), 185impl_intern_key!(MacroCallId);
225 EagerMacro(EagerMacroId),
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
229pub struct LazyMacroId(salsa::InternId);
230impl_intern_key!(LazyMacroId);
231
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233pub struct EagerMacroId(salsa::InternId);
234impl_intern_key!(EagerMacroId);
235
236impl From<LazyMacroId> for MacroCallId {
237 fn from(it: LazyMacroId) -> Self {
238 MacroCallId::LazyMacro(it)
239 }
240}
241impl From<EagerMacroId> for MacroCallId {
242 fn from(it: EagerMacroId) -> Self {
243 MacroCallId::EagerMacro(it)
244 }
245}
246 186
247#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 187#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
248pub struct MacroDefId { 188pub struct MacroDefId {
@@ -258,8 +198,8 @@ impl MacroDefId {
258 db: &dyn db::AstDatabase, 198 db: &dyn db::AstDatabase,
259 krate: CrateId, 199 krate: CrateId,
260 kind: MacroCallKind, 200 kind: MacroCallKind,
261 ) -> LazyMacroId { 201 ) -> MacroCallId {
262 db.intern_macro(MacroCallLoc { def: self, krate, kind }) 202 db.intern_macro(MacroCallLoc { def: self, krate, eager: None, kind })
263 } 203 }
264 204
265 pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> { 205 pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> {
@@ -289,9 +229,17 @@ pub enum MacroDefKind {
289} 229}
290 230
291#[derive(Debug, Clone, PartialEq, Eq, Hash)] 231#[derive(Debug, Clone, PartialEq, Eq, Hash)]
232struct EagerCallInfo {
233 /// NOTE: This can be *either* the expansion result, *or* the argument to the eager macro!
234 expansion: Arc<tt::Subtree>,
235 included_file: Option<FileId>,
236}
237
238#[derive(Debug, Clone, PartialEq, Eq, Hash)]
292pub struct MacroCallLoc { 239pub struct MacroCallLoc {
293 pub(crate) def: MacroDefId, 240 pub(crate) def: MacroDefId,
294 pub(crate) krate: CrateId, 241 pub(crate) krate: CrateId,
242 eager: Option<EagerCallInfo>,
295 pub kind: MacroCallKind, 243 pub kind: MacroCallKind,
296} 244}
297 245
@@ -313,6 +261,7 @@ pub enum MacroCallKind {
313} 261}
314 262
315impl MacroCallKind { 263impl MacroCallKind {
264 /// Returns the file containing the macro invocation.
316 fn file_id(&self) -> HirFileId { 265 fn file_id(&self) -> HirFileId {
317 match self { 266 match self {
318 MacroCallKind::FnLike { ast_id, .. } => ast_id.file_id, 267 MacroCallKind::FnLike { ast_id, .. } => ast_id.file_id,
@@ -354,17 +303,6 @@ impl MacroCallId {
354 } 303 }
355} 304}
356 305
357#[derive(Debug, Clone, PartialEq, Eq, Hash)]
358pub struct EagerCallLoc {
359 pub(crate) def: MacroDefId,
360 pub(crate) fragment: FragmentKind,
361 pub(crate) subtree: Arc<tt::Subtree>,
362 pub(crate) krate: CrateId,
363 pub(crate) call: AstId<ast::MacroCall>,
364 // The included file ID of the include macro.
365 pub(crate) included_file: Option<FileId>,
366}
367
368/// ExpansionInfo mainly describes how to map text range between src and expanded macro 306/// ExpansionInfo mainly describes how to map text range between src and expanded macro
369#[derive(Debug, Clone, PartialEq, Eq)] 307#[derive(Debug, Clone, PartialEq, Eq)]
370pub struct ExpansionInfo { 308pub struct ExpansionInfo {