]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_def/src/lib.rs
Merge #11461
[rust.git] / crates / hir_def / src / lib.rs
index 6cc6bf98fbb5d573c35a51187f20a458845aaf3d..bb65d1dec87d4610a1ed49198abf9f187fbfeb71 100644 (file)
@@ -63,11 +63,12 @@ macro_rules! eprintln {
     ast_id_map::FileAstId,
     eager::{expand_eager_macro, ErrorEmitted, ErrorSink},
     hygiene::Hygiene,
-    AstId, ExpandTo, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
+    AstId, ExpandError, 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;
 
@@ -153,7 +154,7 @@ fn hash<H: Hasher>(&self, state: &mut H) {
 
 #[derive(Debug)]
 pub struct AssocItemLoc<N: ItemTreeNode> {
-    pub container: AssocContainerId,
+    pub container: ItemContainerId,
     pub id: ItemTreeId<N>,
 }
 
@@ -244,7 +245,7 @@ pub struct FieldId {
 
 #[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)]
@@ -262,6 +263,11 @@ pub struct FieldId {
 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)]
@@ -295,12 +301,13 @@ pub struct ConstParamId {
 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)]
@@ -427,6 +434,7 @@ pub enum AttrDefId {
     MacroDefId(MacroDefId),
     ImplId(ImplId),
     GenericParamId(GenericParamId),
+    ExternBlockId(ExternBlockId),
 }
 
 impl_from!(
@@ -445,12 +453,13 @@ pub enum AttrDefId {
     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),
         }
     }
 }
@@ -505,12 +514,13 @@ pub trait HasModule {
     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,
         }
     }
 }
@@ -587,12 +597,6 @@ fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
     }
 }
 
-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).
     ///
@@ -604,7 +608,7 @@ pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
             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,
@@ -625,6 +629,7 @@ pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId {
             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,
@@ -657,7 +662,7 @@ fn as_call_id_with_errors(
         db: &dyn db::DefDatabase,
         krate: CrateId,
         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
-        error_sink: &mut dyn FnMut(mbe::ExpandError),
+        error_sink: &mut dyn FnMut(ExpandError),
     ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro>;
 }
 
@@ -667,15 +672,16 @@ fn as_call_id_with_errors(
         db: &dyn db::DefDatabase,
         krate: CrateId,
         resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
-        mut error_sink: &mut dyn FnMut(mbe::ExpandError),
+        mut error_sink: &mut dyn FnMut(ExpandError),
     ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
         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()))
+            .option(path, || ExpandError::Other("malformed macro invocation".into()))
         {
             Ok(path) => path,
             Err(error) => {
@@ -684,9 +690,9 @@ fn as_call_id_with_errors(
         };
 
         macro_call_as_call_id(
+            db,
             &AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
             expands_to,
-            db,
             krate,
             resolver,
             error_sink,
@@ -707,34 +713,21 @@ fn new(file_id: HirFileId, ast_id: FileAstId<T>, path: path::ModPath) -> AstIdWi
     }
 }
 
-#[derive(Debug)]
-pub struct UnresolvedMacro {
-    pub path: ModPath,
-}
-
 fn macro_call_as_call_id(
+    db: &dyn db::DefDatabase,
     call: &AstIdWithPath<ast::MacroCall>,
     expand_to: ExpandTo,
-    db: &dyn db::DefDatabase,
     krate: CrateId,
     resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
-    error_sink: &mut dyn FnMut(mbe::ExpandError),
+    error_sink: &mut dyn FnMut(ExpandError),
 ) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
     let def: MacroDefId =
         resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
 
     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(),
@@ -746,25 +739,21 @@ fn macro_call_as_call_id(
 }
 
 fn derive_macro_as_call_id(
-    item_attr: &AstIdWithPath<ast::Item>,
-    derive_attr: AttrId,
     db: &dyn db::DefDatabase,
+    item_attr: &AstIdWithPath<ast::Adt>,
+    derive_attr: AttrId,
+    derive_pos: u32,
     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 res = def.as_lazy_macro(
         db.upcast(),
         krate,
         MacroCallKind::Derive {
             ast_id: item_attr.ast_id,
-            derive_name: last_segment.to_string(),
+            derive_index: derive_pos,
             derive_attr_index: derive_attr.ast_index,
         },
     );
@@ -772,27 +761,18 @@ fn derive_macro_as_call_id(
 }
 
 fn attr_macro_as_call_id(
+    db: &dyn db::DefDatabase,
     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())
-        .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 &macro_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,
+    is_derive: bool,
+) -> MacroCallId {
+    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;
 
@@ -801,10 +781,10 @@ fn attr_macro_as_call_id(
         krate,
         MacroCallKind::Attr {
             ast_id: item_attr.ast_id,
-            attr_name: last_segment.to_string(),
-            attr_args: arg,
+            attr_args: Arc::new(arg),
             invoc_attr_index: macro_attr.id.ast_index,
+            is_derive,
         },
     );
-    Ok(res)
+    res
 }