mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-29 06:23:25 +00:00
Auto merge of #17341 - Veykril:inert-attr, r=Veykril
internal: Cleanup some inert attribute stuff
This commit is contained in:
commit
f28f15ac6e
17 changed files with 155 additions and 162 deletions
|
@ -1,10 +1,5 @@
|
||||||
//! A higher level attributes based on TokenTree, with also some shortcuts.
|
//! A higher level attributes based on TokenTree, with also some shortcuts.
|
||||||
|
|
||||||
pub mod builtin;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use std::{borrow::Cow, hash::Hash, ops, slice::Iter as SliceIter};
|
use std::{borrow::Cow, hash::Hash, ops, slice::Iter as SliceIter};
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
|
@ -646,3 +641,55 @@ pub(crate) fn fields_attrs_source_map(
|
||||||
|
|
||||||
Arc::new(res)
|
Arc::new(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
//! This module contains tests for doc-expression parsing.
|
||||||
|
//! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`.
|
||||||
|
|
||||||
|
use triomphe::Arc;
|
||||||
|
|
||||||
|
use base_db::FileId;
|
||||||
|
use hir_expand::span_map::{RealSpanMap, SpanMap};
|
||||||
|
use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode};
|
||||||
|
use syntax::{ast, AstNode, TextRange};
|
||||||
|
|
||||||
|
use crate::attr::{DocAtom, DocExpr};
|
||||||
|
|
||||||
|
fn assert_parse_result(input: &str, expected: DocExpr) {
|
||||||
|
let source_file = ast::SourceFile::parse(input, span::Edition::CURRENT).ok().unwrap();
|
||||||
|
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
|
||||||
|
let map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0))));
|
||||||
|
let tt = syntax_node_to_token_tree(
|
||||||
|
tt.syntax(),
|
||||||
|
map.as_ref(),
|
||||||
|
map.span_for_range(TextRange::empty(0.into())),
|
||||||
|
DocCommentDesugarMode::ProcMacro,
|
||||||
|
);
|
||||||
|
let cfg = DocExpr::parse(&tt);
|
||||||
|
assert_eq!(cfg, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_doc_expr_parser() {
|
||||||
|
assert_parse_result("#![doc(hidden)]", DocAtom::Flag("hidden".into()).into());
|
||||||
|
|
||||||
|
assert_parse_result(
|
||||||
|
r#"#![doc(alias = "foo")]"#,
|
||||||
|
DocAtom::KeyValue { key: "alias".into(), value: "foo".into() }.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_parse_result(r#"#![doc(alias("foo"))]"#, DocExpr::Alias(["foo".into()].into()));
|
||||||
|
assert_parse_result(
|
||||||
|
r#"#![doc(alias("foo", "bar", "baz"))]"#,
|
||||||
|
DocExpr::Alias(["foo".into(), "bar".into(), "baz".into()].into()),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_parse_result(
|
||||||
|
r#"
|
||||||
|
#[doc(alias("Bar", "Qux"))]
|
||||||
|
struct Foo;"#,
|
||||||
|
DocExpr::Alias(["Bar".into(), "Qux".into()].into()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
//! This module contains tests for doc-expression parsing.
|
|
||||||
//! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`.
|
|
||||||
|
|
||||||
use triomphe::Arc;
|
|
||||||
|
|
||||||
use base_db::FileId;
|
|
||||||
use hir_expand::span_map::{RealSpanMap, SpanMap};
|
|
||||||
use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode};
|
|
||||||
use syntax::{ast, AstNode, TextRange};
|
|
||||||
|
|
||||||
use crate::attr::{DocAtom, DocExpr};
|
|
||||||
|
|
||||||
fn assert_parse_result(input: &str, expected: DocExpr) {
|
|
||||||
let source_file = ast::SourceFile::parse(input, span::Edition::CURRENT).ok().unwrap();
|
|
||||||
let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
|
|
||||||
let map = SpanMap::RealSpanMap(Arc::new(RealSpanMap::absolute(FileId::from_raw(0))));
|
|
||||||
let tt = syntax_node_to_token_tree(
|
|
||||||
tt.syntax(),
|
|
||||||
map.as_ref(),
|
|
||||||
map.span_for_range(TextRange::empty(0.into())),
|
|
||||||
DocCommentDesugarMode::ProcMacro,
|
|
||||||
);
|
|
||||||
let cfg = DocExpr::parse(&tt);
|
|
||||||
assert_eq!(cfg, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_doc_expr_parser() {
|
|
||||||
assert_parse_result("#![doc(hidden)]", DocAtom::Flag("hidden".into()).into());
|
|
||||||
|
|
||||||
assert_parse_result(
|
|
||||||
r#"#![doc(alias = "foo")]"#,
|
|
||||||
DocAtom::KeyValue { key: "alias".into(), value: "foo".into() }.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_parse_result(r#"#![doc(alias("foo"))]"#, DocExpr::Alias(["foo".into()].into()));
|
|
||||||
assert_parse_result(
|
|
||||||
r#"#![doc(alias("foo", "bar", "baz"))]"#,
|
|
||||||
DocExpr::Alias(["foo".into(), "bar".into(), "baz".into()].into()),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_parse_result(
|
|
||||||
r#"
|
|
||||||
#[doc(alias("Bar", "Qux"))]
|
|
||||||
struct Foo;"#,
|
|
||||||
DocExpr::Alias(["Bar".into(), "Qux".into()].into()),
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -642,7 +642,7 @@ impl<'a> AssocItemCollector<'a> {
|
||||||
continue 'attrs;
|
continue 'attrs;
|
||||||
}
|
}
|
||||||
let loc = self.db.lookup_intern_macro_call(call_id);
|
let loc = self.db.lookup_intern_macro_call(call_id);
|
||||||
if let MacroDefKind::ProcMacro(exp, ..) = loc.def.kind {
|
if let MacroDefKind::ProcMacro(_, exp, _) = loc.def.kind {
|
||||||
// If there's no expander for the proc macro (e.g. the
|
// If there's no expander for the proc macro (e.g. the
|
||||||
// proc macro is ignored, or building the proc macro
|
// proc macro is ignored, or building the proc macro
|
||||||
// crate failed), skip expansion like we would if it was
|
// crate failed), skip expansion like we would if it was
|
||||||
|
|
|
@ -294,10 +294,10 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
|
||||||
let in_file = InFile::new(file_id, m);
|
let in_file = InFile::new(file_id, m);
|
||||||
match expander {
|
match expander {
|
||||||
MacroExpander::Declarative => MacroDefKind::Declarative(in_file),
|
MacroExpander::Declarative => MacroDefKind::Declarative(in_file),
|
||||||
MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(it, in_file),
|
MacroExpander::BuiltIn(it) => MacroDefKind::BuiltIn(in_file, it),
|
||||||
MacroExpander::BuiltInAttr(it) => MacroDefKind::BuiltInAttr(it, in_file),
|
MacroExpander::BuiltInAttr(it) => MacroDefKind::BuiltInAttr(in_file, it),
|
||||||
MacroExpander::BuiltInDerive(it) => MacroDefKind::BuiltInDerive(it, in_file),
|
MacroExpander::BuiltInDerive(it) => MacroDefKind::BuiltInDerive(in_file, it),
|
||||||
MacroExpander::BuiltInEager(it) => MacroDefKind::BuiltInEager(it, in_file),
|
MacroExpander::BuiltInEager(it) => MacroDefKind::BuiltInEager(in_file, it),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -338,9 +338,9 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
|
||||||
MacroDefId {
|
MacroDefId {
|
||||||
krate: loc.container.krate,
|
krate: loc.container.krate,
|
||||||
kind: MacroDefKind::ProcMacro(
|
kind: MacroDefKind::ProcMacro(
|
||||||
|
InFile::new(loc.id.file_id(), makro.ast_id),
|
||||||
loc.expander,
|
loc.expander,
|
||||||
loc.kind,
|
loc.kind,
|
||||||
InFile::new(loc.id.file_id(), makro.ast_id),
|
|
||||||
),
|
),
|
||||||
local_inner: false,
|
local_inner: false,
|
||||||
allow_internal_unsafe: false,
|
allow_internal_unsafe: false,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
attrs::{Attr, AttrId, AttrInput},
|
attrs::{Attr, AttrId, AttrInput},
|
||||||
|
inert_attr_macro::find_builtin_attr_idx,
|
||||||
MacroCallId, MacroCallKind, MacroDefId,
|
MacroCallId, MacroCallKind, MacroDefId,
|
||||||
};
|
};
|
||||||
use span::SyntaxContextId;
|
use span::SyntaxContextId;
|
||||||
|
@ -10,7 +11,6 @@ use syntax::{ast, SmolStr};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
attr::builtin::find_builtin_attr_idx,
|
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
item_scope::BuiltinShadowMode,
|
item_scope::BuiltinShadowMode,
|
||||||
nameres::path_resolution::ResolveMode,
|
nameres::path_resolution::ResolveMode,
|
||||||
|
@ -89,9 +89,12 @@ impl DefMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
if segments.len() == 1 {
|
if segments.len() == 1 {
|
||||||
let mut registered = self.data.registered_attrs.iter().map(SmolStr::as_str);
|
if find_builtin_attr_idx(&name).is_some() {
|
||||||
let is_inert = find_builtin_attr_idx(&name).is_some() || registered.any(pred);
|
return true;
|
||||||
return is_inert;
|
}
|
||||||
|
if self.data.registered_attrs.iter().map(SmolStr::as_str).any(pred) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
|
|
@ -10,7 +10,7 @@ use cfg::{CfgExpr, CfgOptions};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
attrs::{Attr, AttrId},
|
attrs::{Attr, AttrId},
|
||||||
builtin_attr_macro::{find_builtin_attr, BuiltinAttrExpander},
|
builtin_attr_macro::find_builtin_attr,
|
||||||
builtin_derive_macro::find_builtin_derive,
|
builtin_derive_macro::find_builtin_derive,
|
||||||
builtin_fn_macro::find_builtin_macro,
|
builtin_fn_macro::find_builtin_macro,
|
||||||
name::{name, AsName, Name},
|
name::{name, AsName, Name},
|
||||||
|
@ -270,6 +270,7 @@ struct DefCollector<'a> {
|
||||||
///
|
///
|
||||||
/// This also stores the attributes to skip when we resolve derive helpers and non-macro
|
/// This also stores the attributes to skip when we resolve derive helpers and non-macro
|
||||||
/// non-builtin attributes in general.
|
/// non-builtin attributes in general.
|
||||||
|
// FIXME: There has to be a better way to do this
|
||||||
skip_attrs: FxHashMap<InFile<ModItem>, AttrId>,
|
skip_attrs: FxHashMap<InFile<ModItem>, AttrId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1255,17 +1256,23 @@ impl DefCollector<'_> {
|
||||||
_ => return Resolved::No,
|
_ => return Resolved::No,
|
||||||
};
|
};
|
||||||
|
|
||||||
let call_id =
|
// Skip #[test]/#[bench] expansion, which would merely result in more memory usage
|
||||||
attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def);
|
// due to duplicating functions into macro expansions
|
||||||
if let MacroDefId {
|
if matches!(
|
||||||
kind:
|
def.kind,
|
||||||
MacroDefKind::BuiltInAttr(
|
MacroDefKind::BuiltInAttr(_, expander)
|
||||||
BuiltinAttrExpander::Derive | BuiltinAttrExpander::DeriveConst,
|
if expander.is_test() || expander.is_bench()
|
||||||
_,
|
) {
|
||||||
),
|
return recollect_without(self);
|
||||||
..
|
}
|
||||||
} = def
|
|
||||||
{
|
let call_id = || {
|
||||||
|
attr_macro_as_call_id(self.db, file_ast_id, attr, self.def_map.krate, def)
|
||||||
|
};
|
||||||
|
if matches!(def,
|
||||||
|
MacroDefId { kind: MacroDefKind::BuiltInAttr(_, exp), .. }
|
||||||
|
if exp.is_derive()
|
||||||
|
) {
|
||||||
// Resolved to `#[derive]`, we don't actually expand this attribute like
|
// Resolved to `#[derive]`, we don't actually expand this attribute like
|
||||||
// normal (as that would just be an identity expansion with extra output)
|
// normal (as that would just be an identity expansion with extra output)
|
||||||
// Instead we treat derive attributes special and apply them separately.
|
// Instead we treat derive attributes special and apply them separately.
|
||||||
|
@ -1290,6 +1297,7 @@ impl DefCollector<'_> {
|
||||||
|
|
||||||
match attr.parse_path_comma_token_tree(self.db.upcast()) {
|
match attr.parse_path_comma_token_tree(self.db.upcast()) {
|
||||||
Some(derive_macros) => {
|
Some(derive_macros) => {
|
||||||
|
let call_id = call_id();
|
||||||
let mut len = 0;
|
let mut len = 0;
|
||||||
for (idx, (path, call_site)) in derive_macros.enumerate() {
|
for (idx, (path, call_site)) in derive_macros.enumerate() {
|
||||||
let ast_id = AstIdWithPath::new(file_id, ast_id.value, path);
|
let ast_id = AstIdWithPath::new(file_id, ast_id.value, path);
|
||||||
|
@ -1312,13 +1320,6 @@ impl DefCollector<'_> {
|
||||||
// This is just a trick to be able to resolve the input to derives
|
// This is just a trick to be able to resolve the input to derives
|
||||||
// as proper paths in `Semantics`.
|
// as proper paths in `Semantics`.
|
||||||
// Check the comment in [`builtin_attr_macro`].
|
// Check the comment in [`builtin_attr_macro`].
|
||||||
let call_id = attr_macro_as_call_id(
|
|
||||||
self.db,
|
|
||||||
file_ast_id,
|
|
||||||
attr,
|
|
||||||
self.def_map.krate,
|
|
||||||
def,
|
|
||||||
);
|
|
||||||
self.def_map.modules[directive.module_id]
|
self.def_map.modules[directive.module_id]
|
||||||
.scope
|
.scope
|
||||||
.init_derive_attribute(ast_id, attr.id, call_id, len + 1);
|
.init_derive_attribute(ast_id, attr.id, call_id, len + 1);
|
||||||
|
@ -1336,17 +1337,8 @@ impl DefCollector<'_> {
|
||||||
return recollect_without(self);
|
return recollect_without(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip #[test]/#[bench] expansion, which would merely result in more memory usage
|
let call_id = call_id();
|
||||||
// due to duplicating functions into macro expansions
|
if let MacroDefKind::ProcMacro(_, exp, _) = def.kind {
|
||||||
if matches!(
|
|
||||||
def.kind,
|
|
||||||
MacroDefKind::BuiltInAttr(expander, _)
|
|
||||||
if expander.is_test() || expander.is_bench()
|
|
||||||
) {
|
|
||||||
return recollect_without(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let MacroDefKind::ProcMacro(exp, ..) = def.kind {
|
|
||||||
// If proc attribute macro expansion is disabled, skip expanding it here
|
// If proc attribute macro expansion is disabled, skip expanding it here
|
||||||
if !self.db.expand_proc_attr_macros() {
|
if !self.db.expand_proc_attr_macros() {
|
||||||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
|
self.def_map.diagnostics.push(DefDiagnostic::unresolved_proc_macro(
|
||||||
|
|
|
@ -52,8 +52,6 @@ impl BuiltinAttrExpander {
|
||||||
|
|
||||||
register_builtin! {
|
register_builtin! {
|
||||||
(bench, Bench) => dummy_attr_expand,
|
(bench, Bench) => dummy_attr_expand,
|
||||||
(cfg, Cfg) => dummy_attr_expand,
|
|
||||||
(cfg_attr, CfgAttr) => dummy_attr_expand,
|
|
||||||
(cfg_accessible, CfgAccessible) => dummy_attr_expand,
|
(cfg_accessible, CfgAccessible) => dummy_attr_expand,
|
||||||
(cfg_eval, CfgEval) => dummy_attr_expand,
|
(cfg_eval, CfgEval) => dummy_attr_expand,
|
||||||
(derive, Derive) => derive_expand,
|
(derive, Derive) => derive_expand,
|
||||||
|
|
|
@ -189,8 +189,8 @@ pub(crate) fn process_cfg_attrs(
|
||||||
// FIXME: #[cfg_eval] is not implemented. But it is not stable yet
|
// FIXME: #[cfg_eval] is not implemented. But it is not stable yet
|
||||||
let is_derive = match loc.def.kind {
|
let is_derive = match loc.def.kind {
|
||||||
MacroDefKind::BuiltInDerive(..)
|
MacroDefKind::BuiltInDerive(..)
|
||||||
| MacroDefKind::ProcMacro(_, ProcMacroKind::CustomDerive, _) => true,
|
| MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive) => true,
|
||||||
MacroDefKind::BuiltInAttr(expander, _) => expander.is_derive(),
|
MacroDefKind::BuiltInAttr(_, expander) => expander.is_derive(),
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if !is_derive {
|
if !is_derive {
|
||||||
|
|
|
@ -252,7 +252,7 @@ pub fn expand_speculative(
|
||||||
// Otherwise the expand query will fetch the non speculative attribute args and pass those instead.
|
// Otherwise the expand query will fetch the non speculative attribute args and pass those instead.
|
||||||
let mut speculative_expansion =
|
let mut speculative_expansion =
|
||||||
match loc.def.kind {
|
match loc.def.kind {
|
||||||
MacroDefKind::ProcMacro(expander, _, ast) => {
|
MacroDefKind::ProcMacro(ast, expander, _) => {
|
||||||
let span = db.proc_macro_span(ast);
|
let span = db.proc_macro_span(ast);
|
||||||
tt.delimiter = tt::Delimiter::invisible_spanned(span);
|
tt.delimiter = tt::Delimiter::invisible_spanned(span);
|
||||||
expander.expand(
|
expander.expand(
|
||||||
|
@ -266,22 +266,22 @@ pub fn expand_speculative(
|
||||||
span_with_mixed_site_ctxt(db, span, actual_macro_call),
|
span_with_mixed_site_ctxt(db, span, actual_macro_call),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltInAttr(BuiltinAttrExpander::Derive, _) => {
|
MacroDefKind::BuiltInAttr(_, it) if it.is_derive() => {
|
||||||
pseudo_derive_attr_expansion(&tt, attr_arg.as_ref()?, span)
|
pseudo_derive_attr_expansion(&tt, attr_arg.as_ref()?, span)
|
||||||
}
|
}
|
||||||
MacroDefKind::Declarative(it) => db
|
MacroDefKind::Declarative(it) => db
|
||||||
.decl_macro_expander(loc.krate, it)
|
.decl_macro_expander(loc.krate, it)
|
||||||
.expand_unhygienic(db, tt, loc.def.krate, span, loc.def.edition),
|
.expand_unhygienic(db, tt, loc.def.krate, span, loc.def.edition),
|
||||||
MacroDefKind::BuiltIn(it, _) => {
|
MacroDefKind::BuiltIn(_, it) => {
|
||||||
it.expand(db, actual_macro_call, &tt, span).map_err(Into::into)
|
it.expand(db, actual_macro_call, &tt, span).map_err(Into::into)
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltInDerive(it, ..) => {
|
MacroDefKind::BuiltInDerive(_, it) => {
|
||||||
it.expand(db, actual_macro_call, &tt, span).map_err(Into::into)
|
it.expand(db, actual_macro_call, &tt, span).map_err(Into::into)
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltInEager(it, _) => {
|
MacroDefKind::BuiltInEager(_, it) => {
|
||||||
it.expand(db, actual_macro_call, &tt, span).map_err(Into::into)
|
it.expand(db, actual_macro_call, &tt, span).map_err(Into::into)
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltInAttr(it, _) => it.expand(db, actual_macro_call, &tt, span),
|
MacroDefKind::BuiltInAttr(_, it) => it.expand(db, actual_macro_call, &tt, span),
|
||||||
};
|
};
|
||||||
|
|
||||||
let expand_to = loc.expand_to();
|
let expand_to = loc.expand_to();
|
||||||
|
@ -493,7 +493,7 @@ fn macro_arg(db: &dyn ExpandDatabase, id: MacroCallId) -> MacroArgResult {
|
||||||
.map_or_else(|| node.syntax().text_range(), |it| it.syntax().text_range()),
|
.map_or_else(|| node.syntax().text_range(), |it| it.syntax().text_range()),
|
||||||
);
|
);
|
||||||
// If derive attribute we need to censor the derive input
|
// If derive attribute we need to censor the derive input
|
||||||
if matches!(loc.def.kind, MacroDefKind::BuiltInAttr(expander, ..) if expander.is_derive())
|
if matches!(loc.def.kind, MacroDefKind::BuiltInAttr(_, expander) if expander.is_derive())
|
||||||
&& ast::Adt::can_cast(node.syntax().kind())
|
&& ast::Adt::can_cast(node.syntax().kind())
|
||||||
{
|
{
|
||||||
let adt = ast::Adt::cast(node.syntax().clone()).unwrap();
|
let adt = ast::Adt::cast(node.syntax().clone()).unwrap();
|
||||||
|
@ -569,11 +569,11 @@ impl TokenExpander {
|
||||||
MacroDefKind::Declarative(ast_id) => {
|
MacroDefKind::Declarative(ast_id) => {
|
||||||
TokenExpander::DeclarativeMacro(db.decl_macro_expander(id.krate, ast_id))
|
TokenExpander::DeclarativeMacro(db.decl_macro_expander(id.krate, ast_id))
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltIn(expander, _) => TokenExpander::BuiltIn(expander),
|
MacroDefKind::BuiltIn(_, expander) => TokenExpander::BuiltIn(expander),
|
||||||
MacroDefKind::BuiltInAttr(expander, _) => TokenExpander::BuiltInAttr(expander),
|
MacroDefKind::BuiltInAttr(_, expander) => TokenExpander::BuiltInAttr(expander),
|
||||||
MacroDefKind::BuiltInDerive(expander, _) => TokenExpander::BuiltInDerive(expander),
|
MacroDefKind::BuiltInDerive(_, expander) => TokenExpander::BuiltInDerive(expander),
|
||||||
MacroDefKind::BuiltInEager(expander, ..) => TokenExpander::BuiltInEager(expander),
|
MacroDefKind::BuiltInEager(_, expander) => TokenExpander::BuiltInEager(expander),
|
||||||
MacroDefKind::ProcMacro(expander, ..) => TokenExpander::ProcMacro(expander),
|
MacroDefKind::ProcMacro(_, expander, _) => TokenExpander::ProcMacro(expander),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,13 +604,13 @@ fn macro_expand(
|
||||||
MacroDefKind::Declarative(id) => db
|
MacroDefKind::Declarative(id) => db
|
||||||
.decl_macro_expander(loc.def.krate, id)
|
.decl_macro_expander(loc.def.krate, id)
|
||||||
.expand(db, arg.clone(), macro_call_id, span),
|
.expand(db, arg.clone(), macro_call_id, span),
|
||||||
MacroDefKind::BuiltIn(it, _) => {
|
MacroDefKind::BuiltIn(_, it) => {
|
||||||
it.expand(db, macro_call_id, arg, span).map_err(Into::into).zip_val(None)
|
it.expand(db, macro_call_id, arg, span).map_err(Into::into).zip_val(None)
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltInDerive(it, _) => {
|
MacroDefKind::BuiltInDerive(_, it) => {
|
||||||
it.expand(db, macro_call_id, arg, span).map_err(Into::into).zip_val(None)
|
it.expand(db, macro_call_id, arg, span).map_err(Into::into).zip_val(None)
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltInEager(it, _) => {
|
MacroDefKind::BuiltInEager(_, it) => {
|
||||||
// This might look a bit odd, but we do not expand the inputs to eager macros here.
|
// This might look a bit odd, but we do not expand the inputs to eager macros here.
|
||||||
// Eager macros inputs are expanded, well, eagerly when we collect the macro calls.
|
// Eager macros inputs are expanded, well, eagerly when we collect the macro calls.
|
||||||
// That kind of expansion uses the ast id map of an eager macros input though which goes through
|
// That kind of expansion uses the ast id map of an eager macros input though which goes through
|
||||||
|
@ -634,12 +634,12 @@ fn macro_expand(
|
||||||
}
|
}
|
||||||
res.zip_val(None)
|
res.zip_val(None)
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltInAttr(it, _) => {
|
MacroDefKind::BuiltInAttr(_, it) => {
|
||||||
let mut res = it.expand(db, macro_call_id, arg, span);
|
let mut res = it.expand(db, macro_call_id, arg, span);
|
||||||
fixup::reverse_fixups(&mut res.value, &undo_info);
|
fixup::reverse_fixups(&mut res.value, &undo_info);
|
||||||
res.zip_val(None)
|
res.zip_val(None)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
MacroDefKind::ProcMacro(_, _, _) => unreachable!(),
|
||||||
};
|
};
|
||||||
(ExpandResult { value: res.value, err: res.err }, span)
|
(ExpandResult { value: res.value, err: res.err }, span)
|
||||||
}
|
}
|
||||||
|
@ -678,8 +678,8 @@ fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<A
|
||||||
let loc = db.lookup_intern_macro_call(id);
|
let loc = db.lookup_intern_macro_call(id);
|
||||||
let (macro_arg, undo_info, span) = db.macro_arg_considering_derives(id, &loc.kind);
|
let (macro_arg, undo_info, span) = db.macro_arg_considering_derives(id, &loc.kind);
|
||||||
|
|
||||||
let (expander, ast) = match loc.def.kind {
|
let (ast, expander) = match loc.def.kind {
|
||||||
MacroDefKind::ProcMacro(expander, _, ast) => (expander, ast),
|
MacroDefKind::ProcMacro(ast, expander, _) => (ast, expander),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,11 +36,6 @@ pub fn find_builtin_attr_idx(name: &str) -> Option<usize> {
|
||||||
.copied()
|
.copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl AttributeTemplate {
|
|
||||||
// const DEFAULT: AttributeTemplate =
|
|
||||||
// AttributeTemplate { word: false, list: None, name_value_str: None };
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// A convenience macro for constructing attribute templates.
|
/// A convenience macro for constructing attribute templates.
|
||||||
/// E.g., `template!(Word, List: "description")` means that the attribute
|
/// E.g., `template!(Word, List: "description")` means that the attribute
|
||||||
/// supports forms `#[attr]` and `#[attr(description)]`.
|
/// supports forms `#[attr]` and `#[attr(description)]`.
|
|
@ -16,6 +16,7 @@ pub mod declarative;
|
||||||
pub mod eager;
|
pub mod eager;
|
||||||
pub mod files;
|
pub mod files;
|
||||||
pub mod hygiene;
|
pub mod hygiene;
|
||||||
|
pub mod inert_attr_macro;
|
||||||
pub mod mod_path;
|
pub mod mod_path;
|
||||||
pub mod name;
|
pub mod name;
|
||||||
pub mod proc_macro;
|
pub mod proc_macro;
|
||||||
|
@ -186,11 +187,11 @@ pub struct MacroDefId {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum MacroDefKind {
|
pub enum MacroDefKind {
|
||||||
Declarative(AstId<ast::Macro>),
|
Declarative(AstId<ast::Macro>),
|
||||||
BuiltIn(BuiltinFnLikeExpander, AstId<ast::Macro>),
|
BuiltIn(AstId<ast::Macro>, BuiltinFnLikeExpander),
|
||||||
BuiltInAttr(BuiltinAttrExpander, AstId<ast::Macro>),
|
BuiltInAttr(AstId<ast::Macro>, BuiltinAttrExpander),
|
||||||
BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>),
|
BuiltInDerive(AstId<ast::Macro>, BuiltinDeriveExpander),
|
||||||
BuiltInEager(EagerExpander, AstId<ast::Macro>),
|
BuiltInEager(AstId<ast::Macro>, EagerExpander),
|
||||||
ProcMacro(CustomProcMacroExpander, ProcMacroKind, AstId<ast::Fn>),
|
ProcMacro(AstId<ast::Fn>, CustomProcMacroExpander, ProcMacroKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -379,7 +380,7 @@ impl MacroFileIdExt for MacroFileId {
|
||||||
fn is_custom_derive(&self, db: &dyn ExpandDatabase) -> bool {
|
fn is_custom_derive(&self, db: &dyn ExpandDatabase) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
db.lookup_intern_macro_call(self.macro_call_id).def.kind,
|
db.lookup_intern_macro_call(self.macro_call_id).def.kind,
|
||||||
MacroDefKind::ProcMacro(_, ProcMacroKind::CustomDerive, _)
|
MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,13 +441,13 @@ impl MacroDefId {
|
||||||
pub fn definition_range(&self, db: &dyn ExpandDatabase) -> InFile<TextRange> {
|
pub fn definition_range(&self, db: &dyn ExpandDatabase) -> InFile<TextRange> {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
MacroDefKind::Declarative(id)
|
MacroDefKind::Declarative(id)
|
||||||
| MacroDefKind::BuiltIn(_, id)
|
| MacroDefKind::BuiltIn(id, _)
|
||||||
| MacroDefKind::BuiltInAttr(_, id)
|
| MacroDefKind::BuiltInAttr(id, _)
|
||||||
| MacroDefKind::BuiltInDerive(_, id)
|
| MacroDefKind::BuiltInDerive(id, _)
|
||||||
| MacroDefKind::BuiltInEager(_, id) => {
|
| MacroDefKind::BuiltInEager(id, _) => {
|
||||||
id.with_value(db.ast_id_map(id.file_id).get(id.value).text_range())
|
id.with_value(db.ast_id_map(id.file_id).get(id.value).text_range())
|
||||||
}
|
}
|
||||||
MacroDefKind::ProcMacro(_, _, id) => {
|
MacroDefKind::ProcMacro(id, _, _) => {
|
||||||
id.with_value(db.ast_id_map(id.file_id).get(id.value).text_range())
|
id.with_value(db.ast_id_map(id.file_id).get(id.value).text_range())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -454,12 +455,12 @@ impl MacroDefId {
|
||||||
|
|
||||||
pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> {
|
pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
MacroDefKind::ProcMacro(.., id) => Either::Right(id),
|
MacroDefKind::ProcMacro(id, ..) => Either::Right(id),
|
||||||
MacroDefKind::Declarative(id)
|
MacroDefKind::Declarative(id)
|
||||||
| MacroDefKind::BuiltIn(_, id)
|
| MacroDefKind::BuiltIn(id, _)
|
||||||
| MacroDefKind::BuiltInAttr(_, id)
|
| MacroDefKind::BuiltInAttr(id, _)
|
||||||
| MacroDefKind::BuiltInDerive(_, id)
|
| MacroDefKind::BuiltInDerive(id, _)
|
||||||
| MacroDefKind::BuiltInEager(_, id) => Either::Left(id),
|
| MacroDefKind::BuiltInEager(id, _) => Either::Left(id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +471,7 @@ impl MacroDefId {
|
||||||
pub fn is_attribute(&self) -> bool {
|
pub fn is_attribute(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self.kind,
|
self.kind,
|
||||||
MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, ProcMacroKind::Attr, _)
|
MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,7 +479,7 @@ impl MacroDefId {
|
||||||
matches!(
|
matches!(
|
||||||
self.kind,
|
self.kind,
|
||||||
MacroDefKind::BuiltInDerive(..)
|
MacroDefKind::BuiltInDerive(..)
|
||||||
| MacroDefKind::ProcMacro(_, ProcMacroKind::CustomDerive, _)
|
| MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,26 +487,26 @@ impl MacroDefId {
|
||||||
matches!(
|
matches!(
|
||||||
self.kind,
|
self.kind,
|
||||||
MacroDefKind::BuiltIn(..)
|
MacroDefKind::BuiltIn(..)
|
||||||
| MacroDefKind::ProcMacro(_, ProcMacroKind::Bang, _)
|
| MacroDefKind::ProcMacro(_, _, ProcMacroKind::Bang)
|
||||||
| MacroDefKind::BuiltInEager(..)
|
| MacroDefKind::BuiltInEager(..)
|
||||||
| MacroDefKind::Declarative(..)
|
| MacroDefKind::Declarative(..)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_attribute_derive(&self) -> bool {
|
pub fn is_attribute_derive(&self) -> bool {
|
||||||
matches!(self.kind, MacroDefKind::BuiltInAttr(expander, ..) if expander.is_derive())
|
matches!(self.kind, MacroDefKind::BuiltInAttr(_, expander) if expander.is_derive())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_include(&self) -> bool {
|
pub fn is_include(&self) -> bool {
|
||||||
matches!(self.kind, MacroDefKind::BuiltInEager(expander, ..) if expander.is_include())
|
matches!(self.kind, MacroDefKind::BuiltInEager(_, expander) if expander.is_include())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_include_like(&self) -> bool {
|
pub fn is_include_like(&self) -> bool {
|
||||||
matches!(self.kind, MacroDefKind::BuiltInEager(expander, ..) if expander.is_include_like())
|
matches!(self.kind, MacroDefKind::BuiltInEager(_, expander) if expander.is_include_like())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_env_or_option_env(&self) -> bool {
|
pub fn is_env_or_option_env(&self) -> bool {
|
||||||
matches!(self.kind, MacroDefKind::BuiltInEager(expander, ..) if expander.is_env_or_option_env())
|
matches!(self.kind, MacroDefKind::BuiltInEager(_, expander) if expander.is_env_or_option_env())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ pub use hir_ty::method_resolution::TyFingerprint;
|
||||||
pub use {
|
pub use {
|
||||||
cfg::{CfgAtom, CfgExpr, CfgOptions},
|
cfg::{CfgAtom, CfgExpr, CfgOptions},
|
||||||
hir_def::{
|
hir_def::{
|
||||||
attr::{builtin::AttributeTemplate, AttrSourceMap, Attrs, AttrsWithOwner},
|
attr::{AttrSourceMap, Attrs, AttrsWithOwner},
|
||||||
data::adt::StructKind,
|
data::adt::StructKind,
|
||||||
find_path::PrefixKind,
|
find_path::PrefixKind,
|
||||||
import_map,
|
import_map,
|
||||||
|
@ -132,6 +132,7 @@ pub use {
|
||||||
attrs::{Attr, AttrId},
|
attrs::{Attr, AttrId},
|
||||||
change::ChangeWithProcMacros,
|
change::ChangeWithProcMacros,
|
||||||
hygiene::{marks_rev, SyntaxContextExt},
|
hygiene::{marks_rev, SyntaxContextExt},
|
||||||
|
inert_attr_macro::AttributeTemplate,
|
||||||
name::{known, Name},
|
name::{known, Name},
|
||||||
proc_macro::ProcMacros,
|
proc_macro::ProcMacros,
|
||||||
tt, ExpandResult, HirFileId, HirFileIdExt, InFile, InMacroFile, InRealFile, MacroFileId,
|
tt, ExpandResult, HirFileId, HirFileIdExt, InFile, InMacroFile, InRealFile, MacroFileId,
|
||||||
|
@ -3389,7 +3390,7 @@ impl BuiltinAttr {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn builtin(name: &str) -> Option<Self> {
|
fn builtin(name: &str) -> Option<Self> {
|
||||||
hir_def::attr::builtin::find_builtin_attr_idx(name)
|
hir_expand::inert_attr_macro::find_builtin_attr_idx(name)
|
||||||
.map(|idx| BuiltinAttr { krate: None, idx: idx as u32 })
|
.map(|idx| BuiltinAttr { krate: None, idx: idx as u32 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3397,14 +3398,18 @@ impl BuiltinAttr {
|
||||||
// FIXME: Return a `Name` here
|
// FIXME: Return a `Name` here
|
||||||
match self.krate {
|
match self.krate {
|
||||||
Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx as usize].clone(),
|
Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx as usize].clone(),
|
||||||
None => SmolStr::new(hir_def::attr::builtin::INERT_ATTRIBUTES[self.idx as usize].name),
|
None => {
|
||||||
|
SmolStr::new(hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
|
pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
|
||||||
match self.krate {
|
match self.krate {
|
||||||
Some(_) => None,
|
Some(_) => None,
|
||||||
None => Some(hir_def::attr::builtin::INERT_ATTRIBUTES[self.idx as usize].template),
|
None => {
|
||||||
|
Some(hir_expand::inert_attr_macro::INERT_ATTRIBUTES[self.idx as usize].template)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1617,17 +1617,9 @@ fn macro_call_to_macro_id(
|
||||||
macro_call_id: MacroCallId,
|
macro_call_id: MacroCallId,
|
||||||
) -> Option<MacroId> {
|
) -> Option<MacroId> {
|
||||||
let loc = db.lookup_intern_macro_call(macro_call_id);
|
let loc = db.lookup_intern_macro_call(macro_call_id);
|
||||||
match loc.def.kind {
|
match loc.def.ast_id() {
|
||||||
hir_expand::MacroDefKind::Declarative(it)
|
Either::Left(it) => ctx.macro_to_def(InFile::new(it.file_id, it.to_node(db))),
|
||||||
| hir_expand::MacroDefKind::BuiltIn(_, it)
|
Either::Right(it) => ctx.proc_macro_to_def(InFile::new(it.file_id, it.to_node(db))),
|
||||||
| hir_expand::MacroDefKind::BuiltInAttr(_, it)
|
|
||||||
| hir_expand::MacroDefKind::BuiltInDerive(_, it)
|
|
||||||
| hir_expand::MacroDefKind::BuiltInEager(_, it) => {
|
|
||||||
ctx.macro_to_def(InFile::new(it.file_id, it.to_node(db)))
|
|
||||||
}
|
|
||||||
hir_expand::MacroDefKind::ProcMacro(_, _, it) => {
|
|
||||||
ctx.proc_macro_to_def(InFile::new(it.file_id, it.to_node(db)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ pub(crate) fn macro_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroError) ->
|
||||||
d.message.clone(),
|
d.message.clone(),
|
||||||
display_range,
|
display_range,
|
||||||
)
|
)
|
||||||
.experimental()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diagnostic: macro-error
|
// Diagnostic: macro-error
|
||||||
|
@ -26,7 +25,6 @@ pub(crate) fn macro_def_error(ctx: &DiagnosticsContext<'_>, d: &hir::MacroDefErr
|
||||||
d.message.clone(),
|
d.message.clone(),
|
||||||
display_range,
|
display_range,
|
||||||
)
|
)
|
||||||
.experimental()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -317,6 +317,12 @@ pub struct ValueResult<T, E> {
|
||||||
pub err: Option<E>,
|
pub err: Option<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Default, E> Default for ValueResult<T, E> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { value: Default::default(), err: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, E> ValueResult<T, E> {
|
impl<T, E> ValueResult<T, E> {
|
||||||
pub fn new(value: T, err: E) -> Self {
|
pub fn new(value: T, err: E) -> Self {
|
||||||
Self { value, err: Some(err) }
|
Self { value, err: Some(err) }
|
||||||
|
|
|
@ -513,6 +513,10 @@ where
|
||||||
{
|
{
|
||||||
self.storage.purge();
|
self.storage.purge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn storage(&self) -> &<Q as Query>::Storage {
|
||||||
|
self.storage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return value from [the `query_mut` method] on `Database`.
|
/// Return value from [the `query_mut` method] on `Database`.
|
||||||
|
|
|
@ -147,7 +147,7 @@ pub struct Punct<S> {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum Spacing {
|
pub enum Spacing {
|
||||||
Alone,
|
Alone,
|
||||||
/// Whether the following token is joint to the current one.
|
/// Whether the following token is joint to this one.
|
||||||
Joint,
|
Joint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue