eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
hygiene::Hygiene,
AstId, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
+ UnresolvedMacro,
};
+use item_tree::ExternBlock;
use la_arena::Idx;
use nameres::DefMap;
-use path::ModPath;
use stdx::impl_from;
use syntax::ast;
#[derive(Debug)]
pub struct AssocItemLoc<N: ItemTreeNode> {
- pub container: AssocContainerId,
+ pub container: ItemContainerId,
pub id: ItemTreeId<N>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StaticId(salsa::InternId);
-pub type StaticLoc = ItemLoc<Static>;
+pub type StaticLoc = AssocItemLoc<Static>;
impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
type ImplLoc = ItemLoc<Impl>;
impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
+pub struct ExternBlockId(salsa::InternId);
+type ExternBlockLoc = ItemLoc<ExternBlock>;
+impl_intern!(ExternBlockId, ExternBlockLoc, intern_extern_block, lookup_intern_extern_block);
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct BlockId(salsa::InternId);
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
pub type LocalConstParamId = Idx<generics::ConstParamData>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub enum AssocContainerId {
+pub enum ItemContainerId {
+ ExternBlockId(ExternBlockId),
ModuleId(ModuleId),
ImplId(ImplId),
TraitId(TraitId),
}
-impl_from!(ModuleId for AssocContainerId);
+impl_from!(ModuleId for ItemContainerId);
/// A Data Type
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
MacroDefId(MacroDefId),
ImplId(ImplId),
GenericParamId(GenericParamId),
+ ExternBlockId(ExternBlockId),
}
impl_from!(
for AttrDefId
);
-impl From<AssocContainerId> for AttrDefId {
- fn from(acid: AssocContainerId) -> Self {
+impl From<ItemContainerId> for AttrDefId {
+ fn from(acid: ItemContainerId) -> Self {
match acid {
- AssocContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
- AssocContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
- AssocContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
+ ItemContainerId::ModuleId(mid) => AttrDefId::ModuleId(mid),
+ ItemContainerId::ImplId(iid) => AttrDefId::ImplId(iid),
+ ItemContainerId::TraitId(tid) => AttrDefId::TraitId(tid),
+ ItemContainerId::ExternBlockId(id) => AttrDefId::ExternBlockId(id),
}
}
}
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
}
-impl HasModule for AssocContainerId {
+impl HasModule for ItemContainerId {
fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
match *self {
- AssocContainerId::ModuleId(it) => it,
- AssocContainerId::ImplId(it) => it.lookup(db).container,
- AssocContainerId::TraitId(it) => it.lookup(db).container,
+ ItemContainerId::ModuleId(it) => it,
+ ItemContainerId::ImplId(it) => it.lookup(db).container,
+ ItemContainerId::TraitId(it) => it.lookup(db).container,
+ ItemContainerId::ExternBlockId(it) => it.lookup(db).container,
}
}
}
}
}
-impl HasModule for StaticLoc {
- fn module(&self, _db: &dyn db::DefDatabase) -> ModuleId {
- self.container
- }
-}
-
impl ModuleDefId {
/// Returns the module containing `self` (or `self`, if `self` is itself a module).
///
ModuleDefId::AdtId(id) => id.module(db),
ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
- ModuleDefId::StaticId(id) => id.lookup(db).container,
+ ModuleDefId::StaticId(id) => id.lookup(db).module(db),
ModuleDefId::TraitId(id) => id.lookup(db).container,
ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
ModuleDefId::BuiltinType(_) => return None,
AttrDefId::TraitId(it) => it.lookup(db).container.krate,
AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
AttrDefId::ImplId(it) => it.lookup(db).container.krate,
+ AttrDefId::ExternBlockId(it) => it.lookup(db).container.krate,
AttrDefId::GenericParamId(it) => {
match it {
GenericParamId::TypeParamId(it) => it.parent,
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 h = Hygiene::new(db.upcast(), self.file_id);
- let path = self.value.path().and_then(|path| path::ModPath::from_src(db, path, &h));
+ let path =
+ self.value.path().and_then(|path| path::ModPath::from_src(db.upcast(), path, &h));
let path = match error_sink
.option(path, || mbe::ExpandError::Other("malformed macro invocation".into()))
}
}
-#[derive(Debug)]
-pub struct UnresolvedMacro {
- pub path: ModPath,
-}
-
fn macro_call_as_call_id(
call: &AstIdWithPath<ast::MacroCall>,
expand_to: ExpandTo,
let res = if let MacroDefKind::BuiltInEager(..) = def.kind {
let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
- let hygiene = Hygiene::new(db.upcast(), call.ast_id.file_id);
- expand_eager_macro(
- db.upcast(),
- krate,
- macro_call,
- def,
- &|path: ast::Path| resolver(path::ModPath::from_src(db, path, &hygiene)?),
- error_sink,
- )
+ expand_eager_macro(db.upcast(), krate, macro_call, def, &resolver, error_sink)?
} else {
Ok(def.as_lazy_macro(
db.upcast(),
}
fn derive_macro_as_call_id(
- item_attr: &AstIdWithPath<ast::Item>,
+ item_attr: &AstIdWithPath<ast::Adt>,
derive_attr: AttrId,
db: &dyn db::DefDatabase,
krate: CrateId,
krate,
MacroCallKind::Derive {
ast_id: item_attr.ast_id,
- derive_name: last_segment.to_string(),
+ derive_name: last_segment.to_string().into_boxed_str(),
derive_attr_index: derive_attr.ast_index,
},
);
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())
- .filter(MacroDefId::is_attribute)
- .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, map) => (tt.clone(), map.clone()),
- },
- None => Default::default(),
+ def: MacroDefId,
+) -> MacroCallId {
+ let attr_path = &item_attr.path;
+ let last_segment = attr_path.segments().last().expect("empty attribute path");
+ let mut arg = match macro_attr.input.as_deref() {
+ Some(attr::AttrInput::TokenTree(tt, map)) => (tt.clone(), map.clone()),
+ _ => Default::default(),
};
+
// The parentheses are always disposed here.
arg.0.delimiter = None;
krate,
MacroCallKind::Attr {
ast_id: item_attr.ast_id,
- attr_name: last_segment.to_string(),
+ attr_name: last_segment.to_string().into_boxed_str(),
attr_args: arg,
invoc_attr_index: macro_attr.id.ast_index,
},
);
- Ok(res)
+ res
}