mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 13:33:31 +00:00
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 :)
This commit is contained in:
commit
33c1f57a1a
20 changed files with 278 additions and 71 deletions
|
@ -272,6 +272,7 @@ impl ReleaseChannel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[non_exhaustive]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct CrateData {
|
pub struct CrateData {
|
||||||
pub root_file_id: FileId,
|
pub root_file_id: FileId,
|
||||||
|
|
|
@ -748,8 +748,9 @@ impl<'a> AssocItemCollector<'a> {
|
||||||
&AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
|
&AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
|
||||||
ctxt,
|
ctxt,
|
||||||
expand_to,
|
expand_to,
|
||||||
self.expander.krate(),
|
self.expander.module,
|
||||||
resolver,
|
resolver,
|
||||||
|
|module| module.def_map(self.db).path_for_module(self.db, module),
|
||||||
) {
|
) {
|
||||||
Ok(Some(call_id)) => {
|
Ok(Some(call_id)) => {
|
||||||
let res =
|
let res =
|
||||||
|
|
|
@ -69,9 +69,12 @@ impl Expander {
|
||||||
|
|
||||||
let result = self.within_limit(db, |this| {
|
let result = self.within_limit(db, |this| {
|
||||||
let macro_call = this.in_file(¯o_call);
|
let macro_call = this.in_file(¯o_call);
|
||||||
match macro_call.as_call_id_with_errors(db.upcast(), this.module.krate(), |path| {
|
match macro_call.as_call_id(
|
||||||
resolver(path).map(|it| db.macro_def(it))
|
db.upcast(),
|
||||||
}) {
|
this.module,
|
||||||
|
|path| resolver(path).map(|it| db.macro_def(it)),
|
||||||
|
|module| this.module.def_map(db).path_for_module(db, module),
|
||||||
|
) {
|
||||||
Ok(call_id) => call_id,
|
Ok(call_id) => call_id,
|
||||||
Err(resolve_err) => {
|
Err(resolve_err) => {
|
||||||
unresolved_macro_err = Some(resolve_err);
|
unresolved_macro_err = Some(resolve_err);
|
||||||
|
|
|
@ -77,7 +77,7 @@ use base_db::{
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
|
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
|
||||||
db::ExpandDatabase,
|
db::ExpandDatabase,
|
||||||
eager::expand_eager_macro_input,
|
eager::{expand_eager_macro_input, expand_module_path_as_eager},
|
||||||
impl_intern_lookup,
|
impl_intern_lookup,
|
||||||
name::Name,
|
name::Name,
|
||||||
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
|
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
|
||||||
|
@ -1400,26 +1400,19 @@ pub trait AsMacroCall {
|
||||||
fn as_call_id(
|
fn as_call_id(
|
||||||
&self,
|
&self,
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
krate: CrateId,
|
module: ModuleId,
|
||||||
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
|
||||||
) -> Option<MacroCallId> {
|
|
||||||
self.as_call_id_with_errors(db, krate, resolver).ok()?.value
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_call_id_with_errors(
|
|
||||||
&self,
|
|
||||||
db: &dyn ExpandDatabase,
|
|
||||||
krate: CrateId,
|
|
||||||
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
||||||
|
mod_path: impl FnOnce(ModuleId) -> String,
|
||||||
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
|
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsMacroCall for InFile<&ast::MacroCall> {
|
impl AsMacroCall for InFile<&ast::MacroCall> {
|
||||||
fn as_call_id_with_errors(
|
fn as_call_id(
|
||||||
&self,
|
&self,
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
krate: CrateId,
|
module: ModuleId,
|
||||||
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
||||||
|
mod_path: impl FnOnce(ModuleId) -> String,
|
||||||
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
|
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
|
||||||
let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
|
let expands_to = hir_expand::ExpandTo::from_call_site(self.value);
|
||||||
let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
|
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> {
|
||||||
&path,
|
&path,
|
||||||
call_site.ctx,
|
call_site.ctx,
|
||||||
expands_to,
|
expands_to,
|
||||||
krate,
|
module,
|
||||||
resolver,
|
resolver,
|
||||||
resolver,
|
resolver,
|
||||||
|
mod_path,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1475,8 +1469,9 @@ fn macro_call_as_call_id(
|
||||||
call: &AstIdWithPath<ast::MacroCall>,
|
call: &AstIdWithPath<ast::MacroCall>,
|
||||||
call_site: SyntaxContextId,
|
call_site: SyntaxContextId,
|
||||||
expand_to: ExpandTo,
|
expand_to: ExpandTo,
|
||||||
krate: CrateId,
|
module: ModuleId,
|
||||||
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
resolver: impl Fn(&path::ModPath) -> Option<MacroDefId> + Copy,
|
||||||
|
mod_path: impl FnOnce(ModuleId) -> String,
|
||||||
) -> Result<Option<MacroCallId>, UnresolvedMacro> {
|
) -> Result<Option<MacroCallId>, UnresolvedMacro> {
|
||||||
macro_call_as_call_id_with_eager(
|
macro_call_as_call_id_with_eager(
|
||||||
db,
|
db,
|
||||||
|
@ -1484,9 +1479,10 @@ fn macro_call_as_call_id(
|
||||||
&call.path,
|
&call.path,
|
||||||
call_site,
|
call_site,
|
||||||
expand_to,
|
expand_to,
|
||||||
krate,
|
module,
|
||||||
resolver,
|
resolver,
|
||||||
resolver,
|
resolver,
|
||||||
|
mod_path,
|
||||||
)
|
)
|
||||||
.map(|res| res.value)
|
.map(|res| res.value)
|
||||||
}
|
}
|
||||||
|
@ -1497,16 +1493,26 @@ fn macro_call_as_call_id_with_eager(
|
||||||
path: &path::ModPath,
|
path: &path::ModPath,
|
||||||
call_site: SyntaxContextId,
|
call_site: SyntaxContextId,
|
||||||
expand_to: ExpandTo,
|
expand_to: ExpandTo,
|
||||||
krate: CrateId,
|
module: ModuleId,
|
||||||
resolver: impl FnOnce(&path::ModPath) -> Option<MacroDefId>,
|
resolver: impl FnOnce(&path::ModPath) -> Option<MacroDefId>,
|
||||||
eager_resolver: impl Fn(&path::ModPath) -> Option<MacroDefId>,
|
eager_resolver: impl Fn(&path::ModPath) -> Option<MacroDefId>,
|
||||||
|
mod_path: impl FnOnce(ModuleId) -> String,
|
||||||
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
|
) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
|
||||||
let def = resolver(path).ok_or_else(|| UnresolvedMacro { path: path.clone() })?;
|
let def = resolver(path).ok_or_else(|| UnresolvedMacro { path: path.clone() })?;
|
||||||
|
|
||||||
let res = match def.kind {
|
let res = match def.kind {
|
||||||
|
MacroDefKind::BuiltInEager(_, EagerExpander::ModulePath) => expand_module_path_as_eager(
|
||||||
|
db,
|
||||||
|
module.krate,
|
||||||
|
mod_path(module),
|
||||||
|
&ast_id.to_node(db),
|
||||||
|
ast_id,
|
||||||
|
def,
|
||||||
|
call_site,
|
||||||
|
),
|
||||||
MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
|
MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
|
||||||
db,
|
db,
|
||||||
krate,
|
module.krate,
|
||||||
&ast_id.to_node(db),
|
&ast_id.to_node(db),
|
||||||
ast_id,
|
ast_id,
|
||||||
def,
|
def,
|
||||||
|
@ -1516,7 +1522,7 @@ fn macro_call_as_call_id_with_eager(
|
||||||
_ if def.is_fn_like() => ExpandResult {
|
_ if def.is_fn_like() => ExpandResult {
|
||||||
value: Some(def.make_call(
|
value: Some(def.make_call(
|
||||||
db,
|
db,
|
||||||
krate,
|
module.krate,
|
||||||
MacroCallKind::FnLike { ast_id, expand_to, eager: None },
|
MacroCallKind::FnLike { ast_id, expand_to, eager: None },
|
||||||
call_site,
|
call_site,
|
||||||
)),
|
)),
|
||||||
|
|
|
@ -95,11 +95,16 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
|
||||||
for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) {
|
for macro_call in source_file.syntax().descendants().filter_map(ast::MacroCall::cast) {
|
||||||
let macro_call = InFile::new(source.file_id, ¯o_call);
|
let macro_call = InFile::new(source.file_id, ¯o_call);
|
||||||
let res = macro_call
|
let res = macro_call
|
||||||
.as_call_id_with_errors(&db, krate, |path| {
|
.as_call_id(
|
||||||
resolver
|
&db,
|
||||||
.resolve_path_as_macro(&db, path, Some(MacroSubNs::Bang))
|
resolver.module(),
|
||||||
.map(|(it, _)| db.macro_def(it))
|
|path| {
|
||||||
})
|
resolver
|
||||||
|
.resolve_path_as_macro(&db, path, Some(MacroSubNs::Bang))
|
||||||
|
.map(|(it, _)| db.macro_def(it))
|
||||||
|
},
|
||||||
|
|module| def_map.path_for_module(&db, module),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let macro_call_id = res.value.unwrap();
|
let macro_call_id = res.value.unwrap();
|
||||||
let macro_file = MacroFileId { macro_call_id };
|
let macro_file = MacroFileId { macro_call_id };
|
||||||
|
|
|
@ -63,7 +63,7 @@ use base_db::CrateId;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId,
|
name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId,
|
||||||
};
|
};
|
||||||
use intern::Symbol;
|
use intern::{sym, Symbol};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use la_arena::Arena;
|
use la_arena::Arena;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
@ -139,6 +139,7 @@ pub struct DefMap {
|
||||||
/// Data that belongs to a crate which is shared between a crate's def map and all its block def maps.
|
/// Data that belongs to a crate which is shared between a crate's def map and all its block def maps.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
struct DefMapCrateData {
|
struct DefMapCrateData {
|
||||||
|
crate_name: Option<Symbol>,
|
||||||
/// The extern prelude which contains all root modules of external crates that are in scope.
|
/// The extern prelude which contains all root modules of external crates that are in scope.
|
||||||
extern_prelude: FxIndexMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
|
extern_prelude: FxIndexMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
|
||||||
|
|
||||||
|
@ -164,6 +165,7 @@ struct DefMapCrateData {
|
||||||
impl DefMapCrateData {
|
impl DefMapCrateData {
|
||||||
fn new(edition: Edition) -> Self {
|
fn new(edition: Edition) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
crate_name: None,
|
||||||
extern_prelude: FxIndexMap::default(),
|
extern_prelude: FxIndexMap::default(),
|
||||||
exported_derives: FxHashMap::default(),
|
exported_derives: FxHashMap::default(),
|
||||||
fn_proc_macro_mapping: FxHashMap::default(),
|
fn_proc_macro_mapping: FxHashMap::default(),
|
||||||
|
@ -186,6 +188,7 @@ impl DefMapCrateData {
|
||||||
registered_attrs,
|
registered_attrs,
|
||||||
registered_tools,
|
registered_tools,
|
||||||
unstable_features,
|
unstable_features,
|
||||||
|
crate_name: _,
|
||||||
rustc_coherence_is_core: _,
|
rustc_coherence_is_core: _,
|
||||||
no_core: _,
|
no_core: _,
|
||||||
no_std: _,
|
no_std: _,
|
||||||
|
@ -443,6 +446,28 @@ impl DefMap {
|
||||||
self.modules.iter()
|
self.modules.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn path_for_module(&self, db: &dyn DefDatabase, mut module: ModuleId) -> String {
|
||||||
|
debug_assert!(module.krate == self.krate && module.block == self.block.map(|b| b.block));
|
||||||
|
let mut parts = vec![];
|
||||||
|
if let Some(name) = module.name(db) {
|
||||||
|
parts.push(name.symbol().clone());
|
||||||
|
}
|
||||||
|
while let Some(parent) = module.def_map(db).containing_module(module.local_id) {
|
||||||
|
module = parent;
|
||||||
|
if let Some(name) = module.name(db) {
|
||||||
|
parts.push(name.symbol().clone());
|
||||||
|
}
|
||||||
|
if parts.len() > 10 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parts.push(match &self.data.crate_name {
|
||||||
|
Some(name) => name.clone(),
|
||||||
|
None => sym::crate_.clone(),
|
||||||
|
});
|
||||||
|
parts.into_iter().rev().format("::").to_string()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn derive_helpers_in_scope(
|
pub fn derive_helpers_in_scope(
|
||||||
&self,
|
&self,
|
||||||
id: AstId<ast::Adt>,
|
id: AstId<ast::Adt>,
|
||||||
|
|
|
@ -247,18 +247,23 @@ impl DefCollector<'_> {
|
||||||
let _p = tracing::info_span!("seed_with_top_level").entered();
|
let _p = tracing::info_span!("seed_with_top_level").entered();
|
||||||
|
|
||||||
let crate_graph = self.db.crate_graph();
|
let crate_graph = self.db.crate_graph();
|
||||||
|
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
|
||||||
|
crate_data.crate_name = crate_graph[self.def_map.krate]
|
||||||
|
.display_name
|
||||||
|
.as_ref()
|
||||||
|
.map(|it| it.crate_name().symbol().clone());
|
||||||
|
|
||||||
let file_id = crate_graph[self.def_map.krate].root_file_id();
|
let file_id = crate_graph[self.def_map.krate].root_file_id();
|
||||||
let item_tree = self.db.file_item_tree(file_id.into());
|
let item_tree = self.db.file_item_tree(file_id.into());
|
||||||
let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
|
let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
|
||||||
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
|
|
||||||
|
|
||||||
let mut process = true;
|
let mut crate_cged_out = false;
|
||||||
|
|
||||||
// Process other crate-level attributes.
|
// Process other crate-level attributes.
|
||||||
for attr in &*attrs {
|
for attr in &*attrs {
|
||||||
if let Some(cfg) = attr.cfg() {
|
if let Some(cfg) = attr.cfg() {
|
||||||
if self.cfg_options.check(&cfg) == Some(false) {
|
if self.cfg_options.check(&cfg) == Some(false) {
|
||||||
process = false;
|
crate_cged_out = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,6 +277,11 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
() if *attr_name == sym::crate_name.clone() => {
|
||||||
|
if let Some(name) = attr.string_value().cloned() {
|
||||||
|
crate_data.crate_name = Some(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
() if *attr_name == sym::crate_type.clone() => {
|
() if *attr_name == sym::crate_type.clone() => {
|
||||||
if attr.string_value() == Some(&sym::proc_dash_macro) {
|
if attr.string_value() == Some(&sym::proc_dash_macro) {
|
||||||
self.is_proc_macro = true;
|
self.is_proc_macro = true;
|
||||||
|
@ -337,7 +347,7 @@ impl DefCollector<'_> {
|
||||||
|
|
||||||
self.inject_prelude();
|
self.inject_prelude();
|
||||||
|
|
||||||
if !process {
|
if crate_cged_out {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1207,8 +1217,9 @@ impl DefCollector<'_> {
|
||||||
ast_id,
|
ast_id,
|
||||||
*call_site,
|
*call_site,
|
||||||
*expand_to,
|
*expand_to,
|
||||||
self.def_map.krate,
|
self.def_map.module_id(directive.module_id),
|
||||||
resolver_def_id,
|
resolver_def_id,
|
||||||
|
|module| self.def_map.path_for_module(self.db, module),
|
||||||
);
|
);
|
||||||
if let Ok(Some(call_id)) = call_id {
|
if let Ok(Some(call_id)) = call_id {
|
||||||
self.def_map.modules[directive.module_id]
|
self.def_map.modules[directive.module_id]
|
||||||
|
@ -1486,7 +1497,7 @@ impl DefCollector<'_> {
|
||||||
ast_id,
|
ast_id,
|
||||||
*call_site,
|
*call_site,
|
||||||
*expand_to,
|
*expand_to,
|
||||||
self.def_map.krate,
|
self.def_map.module_id(directive.module_id),
|
||||||
|path| {
|
|path| {
|
||||||
let resolved_res = self.def_map.resolve_path_fp_with_macro(
|
let resolved_res = self.def_map.resolve_path_fp_with_macro(
|
||||||
self.db,
|
self.db,
|
||||||
|
@ -1498,6 +1509,7 @@ impl DefCollector<'_> {
|
||||||
);
|
);
|
||||||
resolved_res.resolved_def.take_macros().map(|it| self.db.macro_def(it))
|
resolved_res.resolved_def.take_macros().map(|it| self.db.macro_def(it))
|
||||||
},
|
},
|
||||||
|
|module| self.def_map.path_for_module(self.db, module),
|
||||||
);
|
);
|
||||||
if let Err(UnresolvedMacro { path }) = macro_call_as_call_id {
|
if let Err(UnresolvedMacro { path }) = macro_call_as_call_id {
|
||||||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
|
self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
|
||||||
|
@ -2351,7 +2363,7 @@ impl ModCollector<'_, '_> {
|
||||||
&ast_id.path,
|
&ast_id.path,
|
||||||
ctxt,
|
ctxt,
|
||||||
expand_to,
|
expand_to,
|
||||||
self.def_collector.def_map.krate,
|
self.def_collector.def_map.module_id(self.module_id),
|
||||||
|path| {
|
|path| {
|
||||||
path.as_ident().and_then(|name| {
|
path.as_ident().and_then(|name| {
|
||||||
let def_map = &self.def_collector.def_map;
|
let def_map = &self.def_collector.def_map;
|
||||||
|
@ -2381,6 +2393,7 @@ impl ModCollector<'_, '_> {
|
||||||
);
|
);
|
||||||
resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it))
|
resolved_res.resolved_def.take_macros().map(|it| db.macro_def(it))
|
||||||
},
|
},
|
||||||
|
|module| self.def_collector.def_map.path_for_module(self.def_collector.db, module),
|
||||||
) {
|
) {
|
||||||
// FIXME: if there were errors, this might've been in the eager expansion from an
|
// FIXME: if there were errors, this might've been in the eager expansion from an
|
||||||
// unresolved macro, so we need to push this into late macro resolution. see fixme above
|
// unresolved macro, so we need to push this into late macro resolution. see fixme above
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Builtin macros and attributes
|
//! Builtin macros and attributes
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod quote;
|
pub(crate) mod quote;
|
||||||
|
|
||||||
mod attr_macro;
|
mod attr_macro;
|
||||||
mod derive_macro;
|
mod derive_macro;
|
||||||
|
|
|
@ -116,7 +116,6 @@ register_builtin! {
|
||||||
(column, Column) => line_expand,
|
(column, Column) => line_expand,
|
||||||
(file, File) => file_expand,
|
(file, File) => file_expand,
|
||||||
(line, Line) => line_expand,
|
(line, Line) => line_expand,
|
||||||
(module_path, ModulePath) => module_path_expand,
|
|
||||||
(assert, Assert) => assert_expand,
|
(assert, Assert) => assert_expand,
|
||||||
(stringify, Stringify) => stringify_expand,
|
(stringify, Stringify) => stringify_expand,
|
||||||
(llvm_asm, LlvmAsm) => asm_expand,
|
(llvm_asm, LlvmAsm) => asm_expand,
|
||||||
|
@ -142,7 +141,10 @@ register_builtin! {
|
||||||
(include_bytes, IncludeBytes) => include_bytes_expand,
|
(include_bytes, IncludeBytes) => include_bytes_expand,
|
||||||
(include_str, IncludeStr) => include_str_expand,
|
(include_str, IncludeStr) => include_str_expand,
|
||||||
(env, Env) => env_expand,
|
(env, Env) => env_expand,
|
||||||
(option_env, OptionEnv) => option_env_expand
|
(option_env, OptionEnv) => option_env_expand,
|
||||||
|
// This isn't really eager, we have no inputs, but we abuse the fact how eager macros are
|
||||||
|
// handled in r-a to be able to thread the module path through.
|
||||||
|
(module_path, ModulePath) => module_path_expand
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_pound(span: Span) -> tt::Subtree {
|
fn mk_pound(span: Span) -> tt::Subtree {
|
||||||
|
@ -157,18 +159,6 @@ fn mk_pound(span: Span) -> tt::Subtree {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_path_expand(
|
|
||||||
_db: &dyn ExpandDatabase,
|
|
||||||
_id: MacroCallId,
|
|
||||||
_tt: &tt::Subtree,
|
|
||||||
span: Span,
|
|
||||||
) -> ExpandResult<tt::Subtree> {
|
|
||||||
// Just return a dummy result.
|
|
||||||
ExpandResult::ok(quote! {span =>
|
|
||||||
"module::path"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn line_expand(
|
fn line_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
|
@ -904,6 +894,18 @@ fn option_env_expand(
|
||||||
ExpandResult::ok(expanded)
|
ExpandResult::ok(expanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn module_path_expand(
|
||||||
|
_db: &dyn ExpandDatabase,
|
||||||
|
_id: MacroCallId,
|
||||||
|
tt: &tt::Subtree,
|
||||||
|
span: Span,
|
||||||
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
// Note: The actual implementation of this is in crates\hir-expand\src\eager.rs
|
||||||
|
ExpandResult::ok(quote! {span =>
|
||||||
|
#tt
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn quote_expand(
|
fn quote_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_arg_id: MacroCallId,
|
_arg_id: MacroCallId,
|
||||||
|
|
|
@ -128,7 +128,7 @@ macro_rules! quote_impl__ {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub(super) use quote_impl__ as __quote;
|
pub(crate) use quote_impl__ as __quote;
|
||||||
|
|
||||||
/// FIXME:
|
/// FIXME:
|
||||||
/// It probably should implement in proc-macro
|
/// It probably should implement in proc-macro
|
||||||
|
@ -137,7 +137,7 @@ macro_rules! quote_impl {
|
||||||
$crate::builtin::quote::IntoTt::to_subtree($crate::builtin::quote::__quote!($span $($tt)*), $span)
|
$crate::builtin::quote::IntoTt::to_subtree($crate::builtin::quote::__quote!($span $($tt)*), $span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(super) use quote_impl as quote;
|
pub(crate) use quote_impl as quote;
|
||||||
|
|
||||||
pub(crate) trait IntoTt {
|
pub(crate) trait IntoTt {
|
||||||
fn to_subtree(self, span: Span) -> crate::tt::Subtree;
|
fn to_subtree(self, span: Span) -> crate::tt::Subtree;
|
||||||
|
|
|
@ -32,6 +32,51 @@ use crate::{
|
||||||
MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
|
MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn expand_module_path_as_eager(
|
||||||
|
db: &dyn ExpandDatabase,
|
||||||
|
krate: CrateId,
|
||||||
|
mod_path: String,
|
||||||
|
macro_call: &ast::MacroCall,
|
||||||
|
ast_id: AstId<ast::MacroCall>,
|
||||||
|
def: MacroDefId,
|
||||||
|
call_site: SyntaxContextId,
|
||||||
|
) -> ExpandResult<Option<MacroCallId>> {
|
||||||
|
let expand_to = ExpandTo::from_call_site(macro_call);
|
||||||
|
|
||||||
|
// Note:
|
||||||
|
// When `lazy_expand` is called, its *parent* file must already exist.
|
||||||
|
// Here we store an eager macro id for the argument expanded subtree
|
||||||
|
// for that purpose.
|
||||||
|
let arg_id = MacroCallLoc {
|
||||||
|
def,
|
||||||
|
krate,
|
||||||
|
kind: MacroCallKind::FnLike { ast_id, expand_to: ExpandTo::Expr, eager: None },
|
||||||
|
ctxt: call_site,
|
||||||
|
}
|
||||||
|
.intern(db);
|
||||||
|
#[allow(deprecated)] // builtin eager macros are never derives
|
||||||
|
let (_, _, span) = db.macro_arg(arg_id);
|
||||||
|
let subtree = crate::builtin::quote::quote! {span => #mod_path};
|
||||||
|
|
||||||
|
let loc = MacroCallLoc {
|
||||||
|
def,
|
||||||
|
krate,
|
||||||
|
kind: MacroCallKind::FnLike {
|
||||||
|
ast_id,
|
||||||
|
expand_to,
|
||||||
|
eager: Some(Arc::new(EagerCallInfo {
|
||||||
|
arg: Arc::new(subtree),
|
||||||
|
arg_id,
|
||||||
|
error: None,
|
||||||
|
span,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
ctxt: call_site,
|
||||||
|
};
|
||||||
|
|
||||||
|
ExpandResult { value: Some(loc.intern(db)), err: None }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expand_eager_macro_input(
|
pub fn expand_eager_macro_input(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
|
|
|
@ -365,7 +365,6 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
_,
|
_,
|
||||||
BuiltinFnLikeExpander::Column
|
BuiltinFnLikeExpander::Column
|
||||||
| BuiltinFnLikeExpander::File
|
| BuiltinFnLikeExpander::File
|
||||||
| BuiltinFnLikeExpander::ModulePath
|
|
||||||
| BuiltinFnLikeExpander::Asm
|
| BuiltinFnLikeExpander::Asm
|
||||||
| BuiltinFnLikeExpander::LlvmAsm
|
| BuiltinFnLikeExpander::LlvmAsm
|
||||||
| BuiltinFnLikeExpander::GlobalAsm
|
| BuiltinFnLikeExpander::GlobalAsm
|
||||||
|
@ -483,10 +482,26 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
let SourceAnalyzer { file_id, resolver, .. } =
|
let SourceAnalyzer { file_id, resolver, .. } =
|
||||||
self.analyze_no_infer(actual_macro_call.syntax())?;
|
self.analyze_no_infer(actual_macro_call.syntax())?;
|
||||||
let macro_call = InFile::new(file_id, actual_macro_call);
|
let macro_call = InFile::new(file_id, actual_macro_call);
|
||||||
let krate = resolver.krate();
|
let macro_call_id = macro_call
|
||||||
let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
|
.as_call_id(
|
||||||
resolver.resolve_path_as_macro_def(self.db.upcast(), path, Some(MacroSubNs::Bang))
|
self.db.upcast(),
|
||||||
})?;
|
resolver.module(),
|
||||||
|
|path| {
|
||||||
|
resolver.resolve_path_as_macro_def(
|
||||||
|
self.db.upcast(),
|
||||||
|
path,
|
||||||
|
Some(MacroSubNs::Bang),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|module| {
|
||||||
|
resolver
|
||||||
|
.module()
|
||||||
|
.def_map(self.db.upcast())
|
||||||
|
.path_for_module(self.db.upcast(), module)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.ok()?
|
||||||
|
.value?;
|
||||||
hir_expand::db::expand_speculative(
|
hir_expand::db::expand_speculative(
|
||||||
self.db.upcast(),
|
self.db.upcast(),
|
||||||
macro_call_id,
|
macro_call_id,
|
||||||
|
|
|
@ -839,12 +839,25 @@ impl SourceAnalyzer {
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
macro_call: InFile<&ast::MacroCall>,
|
macro_call: InFile<&ast::MacroCall>,
|
||||||
) -> Option<MacroFileId> {
|
) -> Option<MacroFileId> {
|
||||||
let krate = self.resolver.krate();
|
|
||||||
// FIXME: This causes us to parse, generally this is the wrong approach for resolving a
|
// FIXME: This causes us to parse, generally this is the wrong approach for resolving a
|
||||||
// macro call to a macro call id!
|
// macro call to a macro call id!
|
||||||
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
|
let macro_call_id = macro_call
|
||||||
self.resolver.resolve_path_as_macro_def(db.upcast(), path, Some(MacroSubNs::Bang))
|
.as_call_id(
|
||||||
})?;
|
db.upcast(),
|
||||||
|
self.resolver.module(),
|
||||||
|
|path| {
|
||||||
|
self.resolver.resolve_path_as_macro_def(
|
||||||
|
db.upcast(),
|
||||||
|
path,
|
||||||
|
Some(MacroSubNs::Bang),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|module| {
|
||||||
|
self.resolver.module().def_map(db.upcast()).path_for_module(db.upcast(), module)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.ok()?
|
||||||
|
.value?;
|
||||||
// why the 64?
|
// why the 64?
|
||||||
Some(macro_call_id.as_macro_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
|
Some(macro_call_id.as_macro_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,11 @@ pub(crate) fn goto_type_definition(
|
||||||
let file: ast::SourceFile = sema.parse_guess_edition(file_id);
|
let file: ast::SourceFile = sema.parse_guess_edition(file_id);
|
||||||
let token: SyntaxToken =
|
let token: SyntaxToken =
|
||||||
pick_best_token(file.syntax().token_at_offset(offset), |kind| match kind {
|
pick_best_token(file.syntax().token_at_offset(offset), |kind| match kind {
|
||||||
IDENT | INT_NUMBER | T![self] => 2,
|
IDENT | INT_NUMBER | T![self] => 3,
|
||||||
kind if kind.is_trivia() => 0,
|
// operators
|
||||||
_ => 1,
|
T!['('] | T!['['] | T!['{'] | T![')'] | T![']'] | T!['}'] | T![!] | T![?] => 2,
|
||||||
|
kind if !kind.is_trivia() => 1,
|
||||||
|
_ => 0,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut res = Vec::new();
|
let mut res = Vec::new();
|
||||||
|
|
|
@ -8702,3 +8702,68 @@ fn foo() {
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_path_macro() {
|
||||||
|
check(
|
||||||
|
r##"
|
||||||
|
//- minicore: module_path
|
||||||
|
|
||||||
|
const C$0: &'static str = module_path!();
|
||||||
|
"##,
|
||||||
|
expect![[r#"
|
||||||
|
*C*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const C: &'static str = "test"
|
||||||
|
```
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
r##"
|
||||||
|
//- minicore: module_path
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
const C$0: &'static str = module_path!();
|
||||||
|
}
|
||||||
|
"##,
|
||||||
|
expect![[r#"
|
||||||
|
*C*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test::foo
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const C: &'static str = "test::foo"
|
||||||
|
```
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
r##"
|
||||||
|
//- minicore: module_path
|
||||||
|
mod baz {
|
||||||
|
const _: () = {
|
||||||
|
mod bar {
|
||||||
|
const C$0: &'static str = module_path!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"##,
|
||||||
|
expect![[r#"
|
||||||
|
*C*
|
||||||
|
|
||||||
|
```rust
|
||||||
|
test::bar
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
const C: &'static str = "test::baz::bar"
|
||||||
|
```
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
|
||||||
dependencies,
|
dependencies,
|
||||||
origin,
|
origin,
|
||||||
is_proc_macro,
|
is_proc_macro,
|
||||||
|
..
|
||||||
} = &crate_graph[crate_id];
|
} = &crate_graph[crate_id];
|
||||||
format_to!(
|
format_to!(
|
||||||
buf,
|
buf,
|
||||||
|
|
|
@ -177,6 +177,7 @@ define_symbols! {
|
||||||
coroutine_state,
|
coroutine_state,
|
||||||
coroutine,
|
coroutine,
|
||||||
count,
|
count,
|
||||||
|
crate_name,
|
||||||
crate_type,
|
crate_type,
|
||||||
CStr,
|
CStr,
|
||||||
debug_assertions,
|
debug_assertions,
|
||||||
|
|
|
@ -22,7 +22,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LsifManager<'a> {
|
struct LsifManager<'a> {
|
||||||
count: i32,
|
id_counter: i32,
|
||||||
token_map: FxHashMap<TokenId, Id>,
|
token_map: FxHashMap<TokenId, Id>,
|
||||||
range_map: FxHashMap<FileRange, Id>,
|
range_map: FxHashMap<FileRange, Id>,
|
||||||
file_map: FxHashMap<FileId, Id>,
|
file_map: FxHashMap<FileId, Id>,
|
||||||
|
@ -44,7 +44,7 @@ impl From<Id> for lsp_types::NumberOrString {
|
||||||
impl LsifManager<'_> {
|
impl LsifManager<'_> {
|
||||||
fn new<'a>(analysis: &'a Analysis, db: &'a RootDatabase, vfs: &'a Vfs) -> LsifManager<'a> {
|
fn new<'a>(analysis: &'a Analysis, db: &'a RootDatabase, vfs: &'a Vfs) -> LsifManager<'a> {
|
||||||
LsifManager {
|
LsifManager {
|
||||||
count: 0,
|
id_counter: 0,
|
||||||
token_map: FxHashMap::default(),
|
token_map: FxHashMap::default(),
|
||||||
range_map: FxHashMap::default(),
|
range_map: FxHashMap::default(),
|
||||||
file_map: FxHashMap::default(),
|
file_map: FxHashMap::default(),
|
||||||
|
@ -56,9 +56,9 @@ impl LsifManager<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&mut self, data: lsif::Element) -> Id {
|
fn add(&mut self, data: lsif::Element) -> Id {
|
||||||
let id = Id(self.count);
|
let id = Id(self.id_counter);
|
||||||
self.emit(&serde_json::to_string(&lsif::Entry { id: id.into(), data }).unwrap());
|
self.emit(&serde_json::to_string(&lsif::Entry { id: id.into(), data }).unwrap());
|
||||||
self.count += 1;
|
self.id_counter += 1;
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,6 @@ impl flags::Scip {
|
||||||
let error_sink;
|
let error_sink;
|
||||||
(config, error_sink, _) = config.apply_change(change);
|
(config, error_sink, _) = config.apply_change(change);
|
||||||
|
|
||||||
// FIXME @alibektas : What happens to errors without logging?
|
|
||||||
error!(?error_sink, "Config Error(s)");
|
error!(?error_sink, "Config Error(s)");
|
||||||
}
|
}
|
||||||
let cargo_config = config.cargo();
|
let cargo_config = config.cargo();
|
||||||
|
@ -115,7 +114,6 @@ impl flags::Scip {
|
||||||
|
|
||||||
tokens.into_iter().for_each(|(text_range, id)| {
|
tokens.into_iter().for_each(|(text_range, id)| {
|
||||||
let token = si.tokens.get(id).unwrap();
|
let token = si.tokens.get(id).unwrap();
|
||||||
|
|
||||||
let range = text_range_to_scip_range(&line_index, text_range);
|
let range = text_range_to_scip_range(&line_index, text_range);
|
||||||
let symbol = tokens_to_symbol
|
let symbol = tokens_to_symbol
|
||||||
.entry(id)
|
.entry(id)
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
//! iterator: option
|
//! iterator: option
|
||||||
//! iterators: iterator, fn
|
//! iterators: iterator, fn
|
||||||
//! manually_drop: drop
|
//! manually_drop: drop
|
||||||
|
//! module_path:
|
||||||
//! non_null:
|
//! non_null:
|
||||||
//! non_zero:
|
//! non_zero:
|
||||||
//! option: panic
|
//! option: panic
|
||||||
|
@ -1434,6 +1435,16 @@ mod panicking {
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros {
|
mod macros {
|
||||||
|
// region:module_path
|
||||||
|
#[macro_export]
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! module_path {
|
||||||
|
($($arg:tt)*) => {
|
||||||
|
/* compiler built-in */
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// endregion:module_path
|
||||||
|
|
||||||
// region:panic
|
// region:panic
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_builtin_macro(core_panic)]
|
#[rustc_builtin_macro(core_panic)]
|
||||||
|
|
Loading…
Reference in a new issue