pub mod type_ref;
pub mod builtin_type;
pub mod builtin_attr;
-pub mod diagnostics;
pub mod per_ns;
pub mod item_scope;
sync::Arc,
};
-use adt::VariantData;
+use attr::Attr;
use base_db::{impl_intern_key, salsa, CrateId};
use hir_expand::{
ast_id_map::FileAstId,
use la_arena::Idx;
use nameres::DefMap;
use path::ModPath;
+use stdx::impl_from;
use syntax::ast;
-use crate::attr::AttrId;
-use crate::builtin_type::BuiltinType;
-use item_tree::{
- Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait,
- TypeAlias, Union,
+use crate::{
+ adt::VariantData,
+ attr::AttrId,
+ builtin_type::BuiltinType,
+ item_tree::{
+ Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait,
+ TypeAlias, Union,
+ },
};
-use stdx::impl_from;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ModuleId {
self.def_map(db).containing_module(self.local_id)
}
- /// Returns `true` if this module represents a block expression.
- ///
- /// Returns `false` if this module is a submodule *inside* a block expression
- /// (eg. `m` in `{ mod m {} }`).
- pub fn is_block_root(&self, db: &dyn db::DefDatabase) -> bool {
- if self.block.is_none() {
- return false;
- }
-
- self.def_map(db)[self.local_id].parent.is_none()
+ pub fn containing_block(&self) -> Option<BlockId> {
+ self.block
}
}
}
}
+impl HasModule for TypeAliasId {
+ fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
+ self.lookup(db).module(db)
+ }
+}
+
+impl HasModule for TraitId {
+ fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
+ self.lookup(db).container
+ }
+}
+
impl HasModule for StaticLoc {
fn module(&self, _db: &dyn db::DefDatabase) -> ModuleId {
self.container
)
.map(MacroCallId::from)
} else {
- Ok(def
- .as_lazy_macro(
- db.upcast(),
- krate,
- MacroCallKind::FnLike { ast_id: call.ast_id, fragment },
- )
- .into())
+ Ok(def.as_lazy_macro(
+ db.upcast(),
+ krate,
+ MacroCallKind::FnLike { ast_id: call.ast_id, fragment },
+ ))
};
Ok(res)
}
.segments()
.last()
.ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
- let res = def
- .as_lazy_macro(
- db.upcast(),
- krate,
- MacroCallKind::Derive {
- ast_id: item_attr.ast_id,
- derive_name: last_segment.to_string(),
- derive_attr_index: derive_attr.ast_index,
- },
- )
- .into();
+ let res = def.as_lazy_macro(
+ db.upcast(),
+ krate,
+ MacroCallKind::Derive {
+ ast_id: item_attr.ast_id,
+ derive_name: last_segment.to_string(),
+ derive_attr_index: derive_attr.ast_index,
+ },
+ );
+ Ok(res)
+}
+
+fn attr_macro_as_call_id(
+ item_attr: &AstIdWithPath<ast::Item>,
+ macro_attr: &Attr,
+ db: &dyn db::DefDatabase,
+ krate: CrateId,
+ resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
+) -> Result<MacroCallId, UnresolvedMacro> {
+ let def: MacroDefId = resolver(item_attr.path.clone())
+ .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
+ let last_segment = item_attr
+ .path
+ .segments()
+ .last()
+ .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
+ let mut arg = match ¯o_attr.input {
+ Some(input) => match &**input {
+ attr::AttrInput::Literal(_) => Default::default(),
+ attr::AttrInput::TokenTree(tt) => tt.clone(),
+ },
+ None => Default::default(),
+ };
+ // The parentheses are always disposed here.
+ arg.tree.delimiter = None;
+
+ let res = def.as_lazy_macro(
+ db.upcast(),
+ krate,
+ MacroCallKind::Attr {
+ ast_id: item_attr.ast_id,
+ attr_name: last_segment.to_string(),
+ attr_args: arg,
+ invoc_attr_index: macro_attr.id.ast_index,
+ },
+ );
Ok(res)
}