Skip to content

Commit 08ce44e

Browse files
committed
Auto merge of #14561 - jonas-schievink:goto-included-file, r=Veykril
feat: Map tokens from `include!` expansion to the included file Fixes #3767
2 parents 1605911 + 901c8a4 commit 08ce44e

File tree

4 files changed

+37
-20
lines changed

4 files changed

+37
-20
lines changed

crates/hir-expand/src/builtin_fn_macro.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use base_db::{AnchoredPath, Edition, FileId};
44
use cfg::CfgExpr;
55
use either::Either;
6-
use mbe::{parse_exprs_with_sep, parse_to_token_tree};
6+
use mbe::{parse_exprs_with_sep, parse_to_token_tree, TokenMap};
77
use syntax::{
88
ast::{self, AstToken},
99
SmolStr,
@@ -67,7 +67,7 @@ macro_rules! register_builtin {
6767
pub struct ExpandedEager {
6868
pub(crate) subtree: tt::Subtree,
6969
/// The included file ID of the include macro.
70-
pub(crate) included_file: Option<FileId>,
70+
pub(crate) included_file: Option<(FileId, TokenMap)>,
7171
}
7272

7373
impl ExpandedEager {
@@ -566,14 +566,14 @@ fn include_expand(
566566
let path = parse_string(tt)?;
567567
let file_id = relative_file(db, arg_id, &path, false)?;
568568

569-
let subtree =
570-
parse_to_token_tree(&db.file_text(file_id)).ok_or(mbe::ExpandError::ConversionError)?.0;
571-
Ok((subtree, file_id))
569+
let (subtree, map) =
570+
parse_to_token_tree(&db.file_text(file_id)).ok_or(mbe::ExpandError::ConversionError)?;
571+
Ok((subtree, map, file_id))
572572
})();
573573

574574
match res {
575-
Ok((subtree, file_id)) => {
576-
ExpandResult::ok(ExpandedEager { subtree, included_file: Some(file_id) })
575+
Ok((subtree, map, file_id)) => {
576+
ExpandResult::ok(ExpandedEager { subtree, included_file: Some((file_id, map)) })
577577
}
578578
Err(e) => ExpandResult::with_err(
579579
ExpandedEager { subtree: tt::Subtree::empty(), included_file: None },

crates/hir-expand/src/db.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ use syntax::{
1313
};
1414

1515
use crate::{
16-
ast_id_map::AstIdMap, builtin_attr_macro::pseudo_derive_attr_expansion, fixup,
17-
hygiene::HygieneFrame, tt, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander,
18-
ExpandError, ExpandResult, ExpandTo, HirFileId, HirFileIdRepr, MacroCallId, MacroCallKind,
19-
MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander,
16+
ast_id_map::AstIdMap, builtin_attr_macro::pseudo_derive_attr_expansion,
17+
builtin_fn_macro::EagerExpander, fixup, hygiene::HygieneFrame, tt, BuiltinAttrExpander,
18+
BuiltinDeriveExpander, BuiltinFnLikeExpander, ExpandError, ExpandResult, ExpandTo, HirFileId,
19+
HirFileIdRepr, MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile,
20+
ProcMacroExpander,
2021
};
2122

2223
/// Total limit on the number of tokens produced by any macro invocation.
@@ -33,6 +34,8 @@ pub enum TokenExpander {
3334
DeclarativeMacro { mac: mbe::DeclarativeMacro, def_site_token_map: mbe::TokenMap },
3435
/// Stuff like `line!` and `file!`.
3536
Builtin(BuiltinFnLikeExpander),
37+
/// Built-in eagerly expanded fn-like macros (`include!`, `concat!`, etc.)
38+
BuiltinEager(EagerExpander),
3639
/// `global_allocator` and such.
3740
BuiltinAttr(BuiltinAttrExpander),
3841
/// `derive(Copy)` and such.
@@ -51,6 +54,9 @@ impl TokenExpander {
5154
match self {
5255
TokenExpander::DeclarativeMacro { mac, .. } => mac.expand(tt).map_err(Into::into),
5356
TokenExpander::Builtin(it) => it.expand(db, id, tt).map_err(Into::into),
57+
TokenExpander::BuiltinEager(it) => {
58+
it.expand(db, id, tt).map_err(Into::into).map(|res| res.subtree)
59+
}
5460
TokenExpander::BuiltinAttr(it) => it.expand(db, id, tt),
5561
TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt),
5662
TokenExpander::ProcMacro(_) => {
@@ -66,6 +72,7 @@ impl TokenExpander {
6672
match self {
6773
TokenExpander::DeclarativeMacro { mac, .. } => mac.map_id_down(id),
6874
TokenExpander::Builtin(..)
75+
| TokenExpander::BuiltinEager(..)
6976
| TokenExpander::BuiltinAttr(..)
7077
| TokenExpander::BuiltinDerive(..)
7178
| TokenExpander::ProcMacro(..) => id,
@@ -76,6 +83,7 @@ impl TokenExpander {
7683
match self {
7784
TokenExpander::DeclarativeMacro { mac, .. } => mac.map_id_up(id),
7885
TokenExpander::Builtin(..)
86+
| TokenExpander::BuiltinEager(..)
7987
| TokenExpander::BuiltinAttr(..)
8088
| TokenExpander::BuiltinDerive(..)
8189
| TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call),
@@ -412,10 +420,8 @@ fn macro_def(
412420
MacroDefKind::BuiltInDerive(expander, _) => {
413421
Ok(Arc::new(TokenExpander::BuiltinDerive(expander)))
414422
}
415-
MacroDefKind::BuiltInEager(..) => {
416-
// FIXME: Return a random error here just to make the types align.
417-
// This obviously should do something real instead.
418-
Err(mbe::ParseError::UnexpectedToken("unexpected eager macro".into()))
423+
MacroDefKind::BuiltInEager(expander, ..) => {
424+
Ok(Arc::new(TokenExpander::BuiltinEager(expander)))
419425
}
420426
MacroDefKind::ProcMacro(expander, ..) => Ok(Arc::new(TokenExpander::ProcMacro(expander))),
421427
}

crates/hir-expand/src/lib.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub mod mod_path;
2020
pub mod attrs;
2121
mod fixup;
2222

23+
use mbe::TokenMap;
2324
pub use mbe::{Origin, ValueResult};
2425

2526
use ::tt::token_id as tt;
@@ -139,7 +140,7 @@ pub enum MacroDefKind {
139140
struct EagerCallInfo {
140141
/// NOTE: This can be *either* the expansion result, *or* the argument to the eager macro!
141142
arg_or_expansion: Arc<tt::Subtree>,
142-
included_file: Option<FileId>,
143+
included_file: Option<(FileId, TokenMap)>,
143144
}
144145

145146
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -206,7 +207,7 @@ impl HirFileId {
206207
HirFileIdRepr::MacroFile(MacroFile { macro_call_id }) => {
207208
let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_call_id);
208209
file_id = match loc.eager {
209-
Some(EagerCallInfo { included_file: Some(file), .. }) => file.into(),
210+
Some(EagerCallInfo { included_file: Some((file, _)), .. }) => file.into(),
210211
_ => loc.kind.file_id(),
211212
};
212213
}
@@ -319,7 +320,7 @@ impl HirFileId {
319320
match self.macro_file() {
320321
Some(macro_file) => {
321322
let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
322-
matches!(loc.eager, Some(EagerCallInfo { included_file: Some(_), .. }))
323+
matches!(loc.eager, Some(EagerCallInfo { included_file: Some(..), .. }))
323324
}
324325
_ => false,
325326
}
@@ -677,6 +678,16 @@ impl ExpansionInfo {
677678
let call_id = self.expanded.file_id.macro_file()?.macro_call_id;
678679
let loc = db.lookup_intern_macro_call(call_id);
679680

681+
if let Some((file, map)) = loc.eager.and_then(|e| e.included_file) {
682+
// Special case: map tokens from `include!` expansions to the included file
683+
let range = map.first_range_by_token(token_id, token.value.kind())?;
684+
let source = db.parse(file);
685+
686+
let token = source.syntax_node().covering_element(range).into_token()?;
687+
688+
return Some((InFile::new(file.into(), token), Origin::Call));
689+
}
690+
680691
// Attributes are a bit special for us, they have two inputs, the input tokentree and the annotated item.
681692
let (token_map, tt) = match &loc.kind {
682693
MacroCallKind::Attr { attr_args, is_derive: true, .. } => {

crates/ide/src/goto_definition.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -833,8 +833,7 @@ fn test() {
833833
#[rustc_builtin_macro]
834834
macro_rules! include {}
835835
836-
include!("foo.rs");
837-
//^^^^^^^^^^^^^^^^^^^
836+
include!("foo.rs");
838837
839838
fn f() {
840839
foo$0();
@@ -846,6 +845,7 @@ mod confuse_index {
846845
847846
//- /foo.rs
848847
fn foo() {}
848+
//^^^
849849
"#,
850850
);
851851
}

0 commit comments

Comments
 (0)