Skip to content

Commit 3bb9efb

Browse files
committed
use the included file as the source of expanded include macro
Signed-off-by: Yilin Chen <[email protected]>
1 parent a0ed87f commit 3bb9efb

File tree

5 files changed

+107
-28
lines changed

5 files changed

+107
-28
lines changed

crates/hir_def/src/nameres/mod_resolution.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ impl ModDir {
6262
name: &Name,
6363
attr_path: Option<&SmolStr>,
6464
) -> Result<(FileId, bool, ModDir), String> {
65+
let is_include_macro = file_id.is_include_macro(db.upcast());
6566
let file_id = file_id.original_file(db.upcast());
6667

6768
let mut candidate_files = Vec::new();
@@ -70,8 +71,13 @@ impl ModDir {
7071
candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
7172
}
7273
None => {
73-
candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
74-
candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
74+
if is_include_macro {
75+
candidate_files.push(format!("{}.rs", name));
76+
candidate_files.push(format!("{}/mod.rs", name));
77+
} else {
78+
candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
79+
candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
80+
}
7581
}
7682
};
7783

crates/hir_expand/src/builtin_macro.rs

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ macro_rules! register_builtin {
4343
db: &dyn AstDatabase,
4444
arg_id: EagerMacroId,
4545
tt: &tt::Subtree,
46-
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
46+
) -> ExpandResult<Option<ExpandedEager>> {
4747
let expander = match *self {
4848
$( EagerExpander::$e_kind => $e_expand, )*
4949
};
@@ -61,6 +61,20 @@ macro_rules! register_builtin {
6161
};
6262
}
6363

64+
#[derive(Debug)]
65+
pub struct ExpandedEager {
66+
pub(crate) subtree: tt::Subtree,
67+
pub(crate) fragment: FragmentKind,
68+
/// The included file ID of the include macro.
69+
pub(crate) included_file: Option<FileId>,
70+
}
71+
72+
impl ExpandedEager {
73+
fn new(subtree: tt::Subtree, fragment: FragmentKind) -> Self {
74+
ExpandedEager { subtree, fragment, included_file: None }
75+
}
76+
}
77+
6478
pub fn find_builtin_macro(
6579
ident: &name::Name,
6680
krate: CrateId,
@@ -280,7 +294,7 @@ fn compile_error_expand(
280294
_db: &dyn AstDatabase,
281295
_id: EagerMacroId,
282296
tt: &tt::Subtree,
283-
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
297+
) -> ExpandResult<Option<ExpandedEager>> {
284298
let err = match &*tt.token_trees {
285299
[tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => {
286300
let text = it.text.as_str();
@@ -294,14 +308,14 @@ fn compile_error_expand(
294308
_ => mbe::ExpandError::BindingError("`compile_error!` argument must be a string".into()),
295309
};
296310

297-
ExpandResult { value: Some((quote! {}, FragmentKind::Items)), err: Some(err) }
311+
ExpandResult { value: Some(ExpandedEager::new(quote! {}, FragmentKind::Items)), err: Some(err) }
298312
}
299313

300314
fn concat_expand(
301315
_db: &dyn AstDatabase,
302316
_arg_id: EagerMacroId,
303317
tt: &tt::Subtree,
304-
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
318+
) -> ExpandResult<Option<ExpandedEager>> {
305319
let mut err = None;
306320
let mut text = String::new();
307321
for (i, t) in tt.token_trees.iter().enumerate() {
@@ -325,7 +339,7 @@ fn concat_expand(
325339
}
326340
}
327341
}
328-
ExpandResult { value: Some((quote!(#text), FragmentKind::Expr)), err }
342+
ExpandResult { value: Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)), err }
329343
}
330344

331345
fn relative_file(
@@ -361,21 +375,27 @@ fn include_expand(
361375
db: &dyn AstDatabase,
362376
arg_id: EagerMacroId,
363377
tt: &tt::Subtree,
364-
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
378+
) -> ExpandResult<Option<ExpandedEager>> {
365379
let res = (|| {
366380
let path = parse_string(tt)?;
367381
let file_id = relative_file(db, arg_id.into(), &path, false)?;
368382

369-
Ok(parse_to_token_tree(&db.file_text(file_id))
383+
let subtree = parse_to_token_tree(&db.file_text(file_id))
370384
.ok_or_else(|| mbe::ExpandError::ConversionError)?
371-
.0)
385+
.0;
386+
Ok((subtree, file_id))
372387
})();
373388

374389
match res {
375-
Ok(res) => {
390+
Ok((subtree, file_id)) => {
376391
// FIXME:
377392
// Handle include as expression
378-
ExpandResult::ok(Some((res, FragmentKind::Items)))
393+
394+
ExpandResult::ok(Some(ExpandedEager {
395+
subtree,
396+
fragment: FragmentKind::Items,
397+
included_file: Some(file_id),
398+
}))
379399
}
380400
Err(e) => ExpandResult::only_err(e),
381401
}
@@ -385,7 +405,7 @@ fn include_bytes_expand(
385405
_db: &dyn AstDatabase,
386406
_arg_id: EagerMacroId,
387407
tt: &tt::Subtree,
388-
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
408+
) -> ExpandResult<Option<ExpandedEager>> {
389409
if let Err(e) = parse_string(tt) {
390410
return ExpandResult::only_err(e);
391411
}
@@ -398,14 +418,14 @@ fn include_bytes_expand(
398418
id: tt::TokenId::unspecified(),
399419
}))],
400420
};
401-
ExpandResult::ok(Some((res, FragmentKind::Expr)))
421+
ExpandResult::ok(Some(ExpandedEager::new(res, FragmentKind::Expr)))
402422
}
403423

404424
fn include_str_expand(
405425
db: &dyn AstDatabase,
406426
arg_id: EagerMacroId,
407427
tt: &tt::Subtree,
408-
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
428+
) -> ExpandResult<Option<ExpandedEager>> {
409429
let path = match parse_string(tt) {
410430
Ok(it) => it,
411431
Err(e) => return ExpandResult::only_err(e),
@@ -418,14 +438,14 @@ fn include_str_expand(
418438
let file_id = match relative_file(db, arg_id.into(), &path, true) {
419439
Ok(file_id) => file_id,
420440
Err(_) => {
421-
return ExpandResult::ok(Some((quote!(""), FragmentKind::Expr)));
441+
return ExpandResult::ok(Some(ExpandedEager::new(quote!(""), FragmentKind::Expr)));
422442
}
423443
};
424444

425445
let text = db.file_text(file_id);
426446
let text = &*text;
427447

428-
ExpandResult::ok(Some((quote!(#text), FragmentKind::Expr)))
448+
ExpandResult::ok(Some(ExpandedEager::new(quote!(#text), FragmentKind::Expr)))
429449
}
430450

431451
fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
@@ -437,7 +457,7 @@ fn env_expand(
437457
db: &dyn AstDatabase,
438458
arg_id: EagerMacroId,
439459
tt: &tt::Subtree,
440-
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
460+
) -> ExpandResult<Option<ExpandedEager>> {
441461
let key = match parse_string(tt) {
442462
Ok(it) => it,
443463
Err(e) => return ExpandResult::only_err(e),
@@ -461,14 +481,14 @@ fn env_expand(
461481
});
462482
let expanded = quote! { #s };
463483

464-
ExpandResult { value: Some((expanded, FragmentKind::Expr)), err }
484+
ExpandResult { value: Some(ExpandedEager::new(expanded, FragmentKind::Expr)), err }
465485
}
466486

467487
fn option_env_expand(
468488
db: &dyn AstDatabase,
469489
arg_id: EagerMacroId,
470490
tt: &tt::Subtree,
471-
) -> ExpandResult<Option<(tt::Subtree, FragmentKind)>> {
491+
) -> ExpandResult<Option<ExpandedEager>> {
472492
let key = match parse_string(tt) {
473493
Ok(it) => it,
474494
Err(e) => return ExpandResult::only_err(e),
@@ -479,7 +499,7 @@ fn option_env_expand(
479499
Some(s) => quote! { std::option::Some(#s) },
480500
};
481501

482-
ExpandResult::ok(Some((expanded, FragmentKind::Expr)))
502+
ExpandResult::ok(Some(ExpandedEager::new(expanded, FragmentKind::Expr)))
483503
}
484504

485505
#[cfg(test)]
@@ -553,16 +573,18 @@ mod tests {
553573
subtree: Arc::new(parsed_args.clone()),
554574
krate,
555575
call: call_id,
576+
included_file: None,
556577
}
557578
});
558579

559-
let (subtree, fragment) = expander.expand(&db, arg_id, &parsed_args).value.unwrap();
580+
let expanded = expander.expand(&db, arg_id, &parsed_args).value.unwrap();
560581
let eager = EagerCallLoc {
561582
def,
562-
fragment,
563-
subtree: Arc::new(subtree),
583+
fragment: expanded.fragment,
584+
subtree: Arc::new(expanded.subtree),
564585
krate,
565586
call: call_id,
587+
included_file: expanded.included_file,
566588
};
567589

568590
let id: MacroCallId = db.intern_eager_expansion(eager).into();

crates/hir_expand/src/eager.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pub fn expand_eager_macro(
124124
subtree: Arc::new(parsed_args.clone()),
125125
krate,
126126
call: call_id,
127+
included_file: None,
127128
}
128129
});
129130
let arg_file_id: MacroCallId = arg_id.into();
@@ -143,9 +144,15 @@ pub fn expand_eager_macro(
143144
if let MacroDefKind::BuiltInEager(eager, _) = def.kind {
144145
let res = eager.expand(db, arg_id, &subtree);
145146

146-
let (subtree, fragment) = diagnostic_sink.expand_result_option(res)?;
147-
let eager =
148-
EagerCallLoc { def, fragment, subtree: Arc::new(subtree), krate, call: call_id };
147+
let expanded = diagnostic_sink.expand_result_option(res)?;
148+
let eager = EagerCallLoc {
149+
def,
150+
fragment: expanded.fragment,
151+
subtree: Arc::new(expanded.subtree),
152+
krate,
153+
call: call_id,
154+
included_file: expanded.included_file,
155+
};
149156

150157
Ok(db.intern_eager_expansion(eager))
151158
} else {

crates/hir_expand/src/lib.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ impl HirFileId {
8484
}
8585
MacroCallId::EagerMacro(id) => {
8686
let loc = db.lookup_intern_eager_expansion(id);
87-
loc.call.file_id
87+
if let Some(included_file) = loc.included_file {
88+
return included_file;
89+
} else {
90+
loc.call.file_id
91+
}
8892
}
8993
};
9094
file_id.original_file(db)
@@ -188,6 +192,21 @@ impl HirFileId {
188192
}
189193
}
190194
}
195+
196+
/// Return whether this file is an include macro
197+
pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool {
198+
match self.0 {
199+
HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id {
200+
MacroCallId::EagerMacro(id) => {
201+
let loc = db.lookup_intern_eager_expansion(id);
202+
return loc.included_file.is_some();
203+
}
204+
_ => {}
205+
},
206+
_ => {}
207+
}
208+
false
209+
}
191210
}
192211

193212
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -315,6 +334,8 @@ pub struct EagerCallLoc {
315334
pub(crate) subtree: Arc<tt::Subtree>,
316335
pub(crate) krate: CrateId,
317336
pub(crate) call: AstId<ast::MacroCall>,
337+
// The included file ID of the include macro.
338+
pub(crate) included_file: Option<FileId>,
318339
}
319340

320341
/// ExpansionInfo mainly describes how to map text range between src and expanded macro

crates/hir_ty/src/tests/macros.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,29 @@ fn bar() -> u32 {0}
606606
);
607607
}
608608

609+
#[test]
610+
fn infer_builtin_macros_include_child_mod() {
611+
check_types(
612+
r#"
613+
//- /main.rs
614+
#[rustc_builtin_macro]
615+
macro_rules! include {() => {}}
616+
617+
include!("f/foo.rs");
618+
619+
fn main() {
620+
bar::bar();
621+
} //^ u32
622+
623+
//- /f/foo.rs
624+
pub mod bar;
625+
626+
//- /f/bar.rs
627+
pub fn bar() -> u32 {0}
628+
"#,
629+
);
630+
}
631+
609632
#[test]
610633
fn infer_builtin_macros_include_str() {
611634
check_types(

0 commit comments

Comments
 (0)