Skip to content

Commit 33c1f57

Browse files
committed
Auto merge of #17936 - Veykril:module_path, r=Veykril
feat: Implement `module_path` macro Turns out this is a pain to implement because of our hir-def hir-expand split :)
2 parents 2025b43 + afcf3f2 commit 33c1f57

File tree

20 files changed

+278
-71
lines changed

20 files changed

+278
-71
lines changed

crates/base-db/src/input.rs

+1
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ impl ReleaseChannel {
272272
}
273273
}
274274

275+
#[non_exhaustive]
275276
#[derive(Debug, Clone, PartialEq, Eq)]
276277
pub struct CrateData {
277278
pub root_file_id: FileId,

crates/hir-def/src/data.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -748,8 +748,9 @@ impl<'a> AssocItemCollector<'a> {
748748
&AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
749749
ctxt,
750750
expand_to,
751-
self.expander.krate(),
751+
self.expander.module,
752752
resolver,
753+
|module| module.def_map(self.db).path_for_module(self.db, module),
753754
) {
754755
Ok(Some(call_id)) => {
755756
let res =

crates/hir-def/src/expander.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,12 @@ impl Expander {
6969

7070
let result = self.within_limit(db, |this| {
7171
let macro_call = this.in_file(&macro_call);
72-
match macro_call.as_call_id_with_errors(db.upcast(), this.module.krate(), |path| {
73-
resolver(path).map(|it| db.macro_def(it))
74-
}) {
72+
match macro_call.as_call_id(
73+
db.upcast(),
74+
this.module,
75+
|path| resolver(path).map(|it| db.macro_def(it)),
76+
|module| this.module.def_map(db).path_for_module(db, module),
77+
) {
7578
Ok(call_id) => call_id,
7679
Err(resolve_err) => {
7780
unresolved_macro_err = Some(resolve_err);

crates/hir-def/src/lib.rs

+25-19
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use base_db::{
7777
use hir_expand::{
7878
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
7979
db::ExpandDatabase,
80-
eager::expand_eager_macro_input,
80+
eager::{expand_eager_macro_input, expand_module_path_as_eager},
8181
impl_intern_lookup,
8282
name::Name,
8383
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
@@ -1400,26 +1400,19 @@ pub trait AsMacroCall {
14001400
fn as_call_id(
14011401
&self,
14021402
db: &dyn ExpandDatabase,
1403-
krate: CrateId,
1404-
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
1405-
) -> Option<MacroCallId> {
1406-
self.as_call_id_with_errors(db, krate, resolver).ok()?.value
1407-
}
1408-
1409-
fn as_call_id_with_errors(
1410-
&self,
1411-
db: &dyn ExpandDatabase,
1412-
krate: CrateId,
1403+
module: ModuleId,
14131404
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
1405+
mod_path: impl FnOnce(ModuleId) -> String,
14141406
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
14151407
}
14161408

14171409
impl AsMacroCall for InFile<&ast::MacroCall> {
1418-
fn as_call_id_with_errors(
1410+
fn as_call_id(
14191411
&self,
14201412
db: &dyn ExpandDatabase,
1421-
krate: CrateId,
1413+
module: ModuleId,
14221414
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
1415+
mod_path: impl FnOnce(ModuleId) -> String,
14231416
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
14241417
let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
14251418
let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
@@ -1446,9 +1439,10 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
14461439
&path,
14471440
call_site.ctx,
14481441
expands_to,
1449-
krate,
1442+
module,
14501443
resolver,
14511444
resolver,
1445+
mod_path,
14521446
)
14531447
}
14541448
}
@@ -1475,18 +1469,20 @@ fn macro_call_as_call_id(
14751469
call: &AstIdWithPath<ast::MacroCall>,
14761470
call_site: SyntaxContextId,
14771471
expand_to: ExpandTo,
1478-
krate: CrateId,
1472+
module: ModuleId,
14791473
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
1474+
mod_path: impl FnOnce(ModuleId) -> String,
14801475
) -> Result<Option<MacroCallId>, UnresolvedMacro> {
14811476
macro_call_as_call_id_with_eager(
14821477
db,
14831478
call.ast_id,
14841479
&call.path,
14851480
call_site,
14861481
expand_to,
1487-
krate,
1482+
module,
14881483
resolver,
14891484
resolver,
1485+
mod_path,
14901486
)
14911487
.map(|res| res.value)
14921488
}
@@ -1497,16 +1493,26 @@ fn macro_call_as_call_id_with_eager(
14971493
path: &path::ModPath,
14981494
call_site: SyntaxContextId,
14991495
expand_to: ExpandTo,
1500-
krate: CrateId,
1496+
module: ModuleId,
15011497
resolver: impl FnOnce(&path::ModPath) -> Option<MacroDefId>,
15021498
eager_resolver: impl Fn(&path::ModPath) -> Option<MacroDefId>,
1499+
mod_path: impl FnOnce(ModuleId) -> String,
15031500
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
15041501
let def = resolver(path).ok_or_else(|| UnresolvedMacro { path: path.clone() })?;
15051502

15061503
let res = match def.kind {
1504+
MacroDefKind::BuiltInEager(_, EagerExpander::ModulePath) => expand_module_path_as_eager(
1505+
db,
1506+
module.krate,
1507+
mod_path(module),
1508+
&ast_id.to_node(db),
1509+
ast_id,
1510+
def,
1511+
call_site,
1512+
),
15071513
MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
15081514
db,
1509-
krate,
1515+
module.krate,
15101516
&ast_id.to_node(db),
15111517
ast_id,
15121518
def,
@@ -1516,7 +1522,7 @@ fn macro_call_as_call_id_with_eager(
15161522
_ if def.is_fn_like() => ExpandResult {
15171523
value: Some(def.make_call(
15181524
db,
1519-
krate,
1525+
module.krate,
15201526
MacroCallKind::FnLike { ast_id, expand_to, eager: None },
15211527
call_site,
15221528
)),

crates/hir-def/src/macro_expansion_tests/mod.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,16 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
9595
for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) {
9696
let macro_call = InFile::new(source.file_id, &macro_call);
9797
let res = macro_call
98-
.as_call_id_with_errors(&db, krate, |path| {
99-
resolver
100-
.resolve_path_as_macro(&db, path, Some(MacroSubNs::Bang))
101-
.map(|(it, _)| db.macro_def(it))
102-
})
98+
.as_call_id(
99+
&db,
100+
resolver.module(),
101+
|path| {
102+
resolver
103+
.resolve_path_as_macro(&db, path, Some(MacroSubNs::Bang))
104+
.map(|(it, _)| db.macro_def(it))
105+
},
106+
|module| def_map.path_for_module(&db, module),
107+
)
103108
.unwrap();
104109
let macro_call_id = res.value.unwrap();
105110
let macro_file = MacroFileId { macro_call_id };

crates/hir-def/src/nameres.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use base_db::CrateId;
6363
use hir_expand::{
6464
name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId,
6565
};
66-
use intern::Symbol;
66+
use intern::{sym, Symbol};
6767
use itertools::Itertools;
6868
use la_arena::Arena;
6969
use rustc_hash::{FxHashMap, FxHashSet};
@@ -139,6 +139,7 @@ pub struct DefMap {
139139
/// Data that belongs to a crate which is shared between a crate's def map and all its block def maps.
140140
#[derive(Clone, Debug, PartialEq, Eq)]
141141
struct DefMapCrateData {
142+
crate_name: Option<Symbol>,
142143
/// The extern prelude which contains all root modules of external crates that are in scope.
143144
extern_prelude: FxIndexMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
144145

@@ -164,6 +165,7 @@ struct DefMapCrateData {
164165
impl DefMapCrateData {
165166
fn new(edition: Edition) -> Self {
166167
Self {
168+
crate_name: None,
167169
extern_prelude: FxIndexMap::default(),
168170
exported_derives: FxHashMap::default(),
169171
fn_proc_macro_mapping: FxHashMap::default(),
@@ -186,6 +188,7 @@ impl DefMapCrateData {
186188
registered_attrs,
187189
registered_tools,
188190
unstable_features,
191+
crate_name: _,
189192
rustc_coherence_is_core: _,
190193
no_core: _,
191194
no_std: _,
@@ -443,6 +446,28 @@ impl DefMap {
443446
self.modules.iter()
444447
}
445448

449+
pub fn path_for_module(&self, db: &dyn DefDatabase, mut module: ModuleId) -> String {
450+
debug_assert!(module.krate == self.krate && module.block == self.block.map(|b| b.block));
451+
let mut parts = vec![];
452+
if let Some(name) = module.name(db) {
453+
parts.push(name.symbol().clone());
454+
}
455+
while let Some(parent) = module.def_map(db).containing_module(module.local_id) {
456+
module = parent;
457+
if let Some(name) = module.name(db) {
458+
parts.push(name.symbol().clone());
459+
}
460+
if parts.len() > 10 {
461+
break;
462+
}
463+
}
464+
parts.push(match &self.data.crate_name {
465+
Some(name) => name.clone(),
466+
None => sym::crate_.clone(),
467+
});
468+
parts.into_iter().rev().format("::").to_string()
469+
}
470+
446471
pub fn derive_helpers_in_scope(
447472
&self,
448473
id: AstId<ast::Adt>,

crates/hir-def/src/nameres/collector.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -247,18 +247,23 @@ impl DefCollector<'_> {
247247
let _p = tracing::info_span!("seed_with_top_level").entered();
248248

249249
let crate_graph = self.db.crate_graph();
250+
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
251+
crate_data.crate_name = crate_graph[self.def_map.krate]
252+
.display_name
253+
.as_ref()
254+
.map(|it| it.crate_name().symbol().clone());
255+
250256
let file_id = crate_graph[self.def_map.krate].root_file_id();
251257
let item_tree = self.db.file_item_tree(file_id.into());
252258
let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
253-
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
254259

255-
let mut process = true;
260+
let mut crate_cged_out = false;
256261

257262
// Process other crate-level attributes.
258263
for attr in &*attrs {
259264
if let Some(cfg) = attr.cfg() {
260265
if self.cfg_options.check(&cfg) == Some(false) {
261-
process = false;
266+
crate_cged_out = true;
262267
break;
263268
}
264269
}
@@ -272,6 +277,11 @@ impl DefCollector<'_> {
272277
}
273278
}
274279
}
280+
() if *attr_name == sym::crate_name.clone() => {
281+
if let Some(name) = attr.string_value().cloned() {
282+
crate_data.crate_name = Some(name);
283+
}
284+
}
275285
() if *attr_name == sym::crate_type.clone() => {
276286
if attr.string_value() == Some(&sym::proc_dash_macro) {
277287
self.is_proc_macro = true;
@@ -337,7 +347,7 @@ impl DefCollector<'_> {
337347

338348
self.inject_prelude();
339349

340-
if !process {
350+
if crate_cged_out {
341351
return;
342352
}
343353

@@ -1207,8 +1217,9 @@ impl DefCollector<'_> {
12071217
ast_id,
12081218
*call_site,
12091219
*expand_to,
1210-
self.def_map.krate,
1220+
self.def_map.module_id(directive.module_id),
12111221
resolver_def_id,
1222+
|module| self.def_map.path_for_module(self.db, module),
12121223
);
12131224
if let Ok(Some(call_id)) = call_id {
12141225
self.def_map.modules[directive.module_id]
@@ -1486,7 +1497,7 @@ impl DefCollector<'_> {
14861497
ast_id,
14871498
*call_site,
14881499
*expand_to,
1489-
self.def_map.krate,
1500+
self.def_map.module_id(directive.module_id),
14901501
|path| {
14911502
let resolved_res = self.def_map.resolve_path_fp_with_macro(
14921503
self.db,
@@ -1498,6 +1509,7 @@ impl DefCollector<'_> {
14981509
);
14991510
resolved_res.resolved_def.take_macros().map(|it| self.db.macro_def(it))
15001511
},
1512+
|module| self.def_map.path_for_module(self.db, module),
15011513
);
15021514
if let Err(UnresolvedMacro { path }) = macro_call_as_call_id {
15031515
self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
@@ -2351,7 +2363,7 @@ impl ModCollector<'_, '_> {
23512363
&ast_id.path,
23522364
ctxt,
23532365
expand_to,
2354-
self.def_collector.def_map.krate,
2366+
self.def_collector.def_map.module_id(self.module_id),
23552367
|path| {
23562368
path.as_ident().and_then(|name| {
23572369
let def_map = &self.def_collector.def_map;
@@ -2381,6 +2393,7 @@ impl ModCollector<'_, '_> {
23812393
);
23822394
resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it))
23832395
},
2396+
|module| self.def_collector.def_map.path_for_module(self.def_collector.db, module),
23842397
) {
23852398
// FIXME: if there were errors, this might've been in the eager expansion from an
23862399
// unresolved macro, so we need to push this into late macro resolution. see fixme above

crates/hir-expand/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Builtin macros and attributes
22
#[macro_use]
3-
mod quote;
3+
pub(crate) mod quote;
44

55
mod attr_macro;
66
mod derive_macro;

crates/hir-expand/src/builtin/fn_macro.rs

+16-14
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ register_builtin! {
116116
(column, Column) => line_expand,
117117
(file, File) => file_expand,
118118
(line, Line) => line_expand,
119-
(module_path, ModulePath) => module_path_expand,
120119
(assert, Assert) => assert_expand,
121120
(stringify, Stringify) => stringify_expand,
122121
(llvm_asm, LlvmAsm) => asm_expand,
@@ -142,7 +141,10 @@ register_builtin! {
142141
(include_bytes, IncludeBytes) => include_bytes_expand,
143142
(include_str, IncludeStr) => include_str_expand,
144143
(env, Env) => env_expand,
145-
(option_env, OptionEnv) => option_env_expand
144+
(option_env, OptionEnv) => option_env_expand,
145+
// This isn't really eager, we have no inputs, but we abuse the fact how eager macros are
146+
// handled in r-a to be able to thread the module path through.
147+
(module_path, ModulePath) => module_path_expand
146148
}
147149

148150
fn mk_pound(span: Span) -> tt::Subtree {
@@ -157,18 +159,6 @@ fn mk_pound(span: Span) -> tt::Subtree {
157159
)
158160
}
159161

160-
fn module_path_expand(
161-
_db: &dyn ExpandDatabase,
162-
_id: MacroCallId,
163-
_tt: &tt::Subtree,
164-
span: Span,
165-
) -> ExpandResult<tt::Subtree> {
166-
// Just return a dummy result.
167-
ExpandResult::ok(quote! {span =>
168-
"module::path"
169-
})
170-
}
171-
172162
fn line_expand(
173163
_db: &dyn ExpandDatabase,
174164
_id: MacroCallId,
@@ -904,6 +894,18 @@ fn option_env_expand(
904894
ExpandResult::ok(expanded)
905895
}
906896

897+
fn module_path_expand(
898+
_db: &dyn ExpandDatabase,
899+
_id: MacroCallId,
900+
tt: &tt::Subtree,
901+
span: Span,
902+
) -> ExpandResult<tt::Subtree> {
903+
// Note: The actual implementation of this is in crates\hir-expand\src\eager.rs
904+
ExpandResult::ok(quote! {span =>
905+
#tt
906+
})
907+
}
908+
907909
fn quote_expand(
908910
_db: &dyn ExpandDatabase,
909911
_arg_id: MacroCallId,

0 commit comments

Comments
 (0)