mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-15 06:33:58 +00:00
Auto merge of #15435 - Veykril:block-src, r=Veykril
Derive block attributes from block item tree
This commit is contained in:
commit
1b678231d7
12 changed files with 81 additions and 73 deletions
|
@ -431,12 +431,10 @@ impl AttrsWithOwner {
|
||||||
.item_tree(db)
|
.item_tree(db)
|
||||||
.raw_attrs(AttrOwner::ModItem(definition_tree_id.value.into()))
|
.raw_attrs(AttrOwner::ModItem(definition_tree_id.value.into()))
|
||||||
.clone(),
|
.clone(),
|
||||||
ModuleOrigin::BlockExpr { block } => RawAttrs::from_attrs_owner(
|
ModuleOrigin::BlockExpr { id, .. } => {
|
||||||
db.upcast(),
|
let tree = db.block_item_tree_query(id);
|
||||||
InFile::new(block.file_id, block.to_node(db.upcast()))
|
tree.raw_attrs(AttrOwner::TopLevel).clone()
|
||||||
.as_ref()
|
}
|
||||||
.map(|it| it as &dyn ast::HasAttrs),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AttrDefId::FieldId(it) => {
|
AttrDefId::FieldId(it) => {
|
||||||
|
|
|
@ -1100,7 +1100,9 @@ impl ExprCollector<'_> {
|
||||||
ast::Stmt::ExprStmt(es) => matches!(es.expr(), Some(ast::Expr::MacroExpr(_))),
|
ast::Stmt::ExprStmt(es) => matches!(es.expr(), Some(ast::Expr::MacroExpr(_))),
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
statement_has_item || matches!(block.tail_expr(), Some(ast::Expr::MacroExpr(_)))
|
statement_has_item
|
||||||
|
|| matches!(block.tail_expr(), Some(ast::Expr::MacroExpr(_)))
|
||||||
|
|| (block.may_carry_attributes() && block.attrs().next().is_some())
|
||||||
};
|
};
|
||||||
|
|
||||||
let block_id = if block_has_items {
|
let block_id = if block_has_items {
|
||||||
|
|
|
@ -82,6 +82,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
|
||||||
#[salsa::invoke(ItemTree::file_item_tree_query)]
|
#[salsa::invoke(ItemTree::file_item_tree_query)]
|
||||||
fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
|
fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
|
||||||
|
|
||||||
|
#[salsa::invoke(ItemTree::block_item_tree_query)]
|
||||||
|
fn block_item_tree_query(&self, block_id: BlockId) -> Arc<ItemTree>;
|
||||||
|
|
||||||
#[salsa::invoke(crate_def_map_wait)]
|
#[salsa::invoke(crate_def_map_wait)]
|
||||||
#[salsa::transparent]
|
#[salsa::transparent]
|
||||||
fn crate_def_map(&self, krate: CrateId) -> Arc<DefMap>;
|
fn crate_def_map(&self, krate: CrateId) -> Arc<DefMap>;
|
||||||
|
|
|
@ -68,7 +68,7 @@ use crate::{
|
||||||
path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
|
path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
|
||||||
type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
|
type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
|
||||||
visibility::RawVisibility,
|
visibility::RawVisibility,
|
||||||
BlockId,
|
BlockId, Lookup,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
|
@ -143,6 +143,16 @@ impl ItemTree {
|
||||||
Arc::new(item_tree)
|
Arc::new(item_tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
|
||||||
|
let loc = block.lookup(db);
|
||||||
|
let block = loc.ast_id.to_node(db.upcast());
|
||||||
|
|
||||||
|
let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
|
||||||
|
let mut item_tree = ctx.lower_block(&block);
|
||||||
|
item_tree.shrink_to_fit();
|
||||||
|
Arc::new(item_tree)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all items located at the top level of the `HirFileId` this
|
/// Returns an iterator over all items located at the top level of the `HirFileId` this
|
||||||
/// `ItemTree` was created from.
|
/// `ItemTree` was created from.
|
||||||
pub fn top_level_items(&self) -> &[ModItem] {
|
pub fn top_level_items(&self) -> &[ModItem] {
|
||||||
|
@ -178,13 +188,6 @@ impl ItemTree {
|
||||||
self.data.get_or_insert_with(Box::default)
|
self.data.get_or_insert_with(Box::default)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_item_tree(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
|
|
||||||
let loc = db.lookup_intern_block(block);
|
|
||||||
let block = loc.ast_id.to_node(db.upcast());
|
|
||||||
let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
|
|
||||||
Arc::new(ctx.lower_block(&block))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn shrink_to_fit(&mut self) {
|
fn shrink_to_fit(&mut self) {
|
||||||
if let Some(data) = &mut self.data {
|
if let Some(data) = &mut self.data {
|
||||||
let ItemTreeData {
|
let ItemTreeData {
|
||||||
|
@ -382,7 +385,7 @@ impl TreeId {
|
||||||
|
|
||||||
pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
|
pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
|
||||||
match self.block {
|
match self.block {
|
||||||
Some(block) => ItemTree::block_item_tree(db, block),
|
Some(block) => db.block_item_tree_query(block),
|
||||||
None => db.file_item_tree(self.file),
|
None => db.file_item_tree(self.file),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,9 @@ impl<'a> Ctx<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree {
|
pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree {
|
||||||
|
self.tree
|
||||||
|
.attrs
|
||||||
|
.insert(AttrOwner::TopLevel, RawAttrs::new(self.db.upcast(), block, self.hygiene()));
|
||||||
self.tree.top_level = block
|
self.tree.top_level = block
|
||||||
.statements()
|
.statements()
|
||||||
.filter_map(|stmt| match stmt {
|
.filter_map(|stmt| match stmt {
|
||||||
|
|
|
@ -60,7 +60,7 @@ mod tests;
|
||||||
use std::{cmp::Ord, ops::Deref};
|
use std::{cmp::Ord, ops::Deref};
|
||||||
|
|
||||||
use base_db::{CrateId, Edition, FileId, ProcMacroKind};
|
use base_db::{CrateId, Edition, FileId, ProcMacroKind};
|
||||||
use hir_expand::{name::Name, HirFileId, InFile, MacroCallId, MacroDefId};
|
use hir_expand::{ast_id_map::FileAstId, name::Name, HirFileId, InFile, MacroCallId, MacroDefId};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use la_arena::Arena;
|
use la_arena::Arena;
|
||||||
use profile::Count;
|
use profile::Count;
|
||||||
|
@ -217,16 +217,17 @@ pub enum ModuleOrigin {
|
||||||
/// Note that non-inline modules, by definition, live inside non-macro file.
|
/// Note that non-inline modules, by definition, live inside non-macro file.
|
||||||
File {
|
File {
|
||||||
is_mod_rs: bool,
|
is_mod_rs: bool,
|
||||||
declaration: AstId<ast::Module>,
|
declaration: FileAstId<ast::Module>,
|
||||||
declaration_tree_id: ItemTreeId<Mod>,
|
declaration_tree_id: ItemTreeId<Mod>,
|
||||||
definition: FileId,
|
definition: FileId,
|
||||||
},
|
},
|
||||||
Inline {
|
Inline {
|
||||||
definition_tree_id: ItemTreeId<Mod>,
|
definition_tree_id: ItemTreeId<Mod>,
|
||||||
definition: AstId<ast::Module>,
|
definition: FileAstId<ast::Module>,
|
||||||
},
|
},
|
||||||
/// Pseudo-module introduced by a block scope (contains only inner items).
|
/// Pseudo-module introduced by a block scope (contains only inner items).
|
||||||
BlockExpr {
|
BlockExpr {
|
||||||
|
id: BlockId,
|
||||||
block: AstId<ast::BlockExpr>,
|
block: AstId<ast::BlockExpr>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -234,8 +235,12 @@ pub enum ModuleOrigin {
|
||||||
impl ModuleOrigin {
|
impl ModuleOrigin {
|
||||||
pub fn declaration(&self) -> Option<AstId<ast::Module>> {
|
pub fn declaration(&self) -> Option<AstId<ast::Module>> {
|
||||||
match self {
|
match self {
|
||||||
ModuleOrigin::File { declaration: module, .. }
|
&ModuleOrigin::File { declaration, declaration_tree_id, .. } => {
|
||||||
| ModuleOrigin::Inline { definition: module, .. } => Some(*module),
|
Some(AstId::new(declaration_tree_id.file_id(), declaration))
|
||||||
|
}
|
||||||
|
&ModuleOrigin::Inline { definition, definition_tree_id } => {
|
||||||
|
Some(AstId::new(definition_tree_id.file_id(), definition))
|
||||||
|
}
|
||||||
ModuleOrigin::CrateRoot { .. } | ModuleOrigin::BlockExpr { .. } => None,
|
ModuleOrigin::CrateRoot { .. } | ModuleOrigin::BlockExpr { .. } => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,16 +265,17 @@ impl ModuleOrigin {
|
||||||
/// That is, a file or a `mod foo {}` with items.
|
/// That is, a file or a `mod foo {}` with items.
|
||||||
fn definition_source(&self, db: &dyn DefDatabase) -> InFile<ModuleSource> {
|
fn definition_source(&self, db: &dyn DefDatabase) -> InFile<ModuleSource> {
|
||||||
match self {
|
match self {
|
||||||
ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
|
&ModuleOrigin::File { definition, .. } | &ModuleOrigin::CrateRoot { definition } => {
|
||||||
let file_id = *definition;
|
let sf = db.parse(definition).tree();
|
||||||
let sf = db.parse(file_id).tree();
|
InFile::new(definition.into(), ModuleSource::SourceFile(sf))
|
||||||
InFile::new(file_id.into(), ModuleSource::SourceFile(sf))
|
|
||||||
}
|
}
|
||||||
ModuleOrigin::Inline { definition, .. } => InFile::new(
|
&ModuleOrigin::Inline { definition, definition_tree_id } => InFile::new(
|
||||||
definition.file_id,
|
definition_tree_id.file_id(),
|
||||||
ModuleSource::Module(definition.to_node(db.upcast())),
|
ModuleSource::Module(
|
||||||
|
AstId::new(definition_tree_id.file_id(), definition).to_node(db.upcast()),
|
||||||
),
|
),
|
||||||
ModuleOrigin::BlockExpr { block } => {
|
),
|
||||||
|
ModuleOrigin::BlockExpr { block, .. } => {
|
||||||
InFile::new(block.file_id, ModuleSource::BlockExpr(block.to_node(db.upcast())))
|
InFile::new(block.file_id, ModuleSource::BlockExpr(block.to_node(db.upcast())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,9 +320,7 @@ impl DefMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> {
|
pub(crate) fn block_def_map_query(db: &dyn DefDatabase, block_id: BlockId) -> Arc<DefMap> {
|
||||||
let block: BlockLoc = db.lookup_intern_block(block_id);
|
let block: BlockLoc = block_id.lookup(db);
|
||||||
|
|
||||||
let tree_id = TreeId::new(block.ast_id.file_id, Some(block_id));
|
|
||||||
|
|
||||||
let parent_map = block.module.def_map(db);
|
let parent_map = block.module.def_map(db);
|
||||||
let krate = block.module.krate;
|
let krate = block.module.krate;
|
||||||
|
@ -325,8 +329,10 @@ impl DefMap {
|
||||||
// modules declared by blocks with items. At the moment, we don't use
|
// modules declared by blocks with items. At the moment, we don't use
|
||||||
// this visibility for anything outside IDE, so that's probably OK.
|
// this visibility for anything outside IDE, so that's probably OK.
|
||||||
let visibility = Visibility::Module(ModuleId { krate, local_id, block: None });
|
let visibility = Visibility::Module(ModuleId { krate, local_id, block: None });
|
||||||
let module_data =
|
let module_data = ModuleData::new(
|
||||||
ModuleData::new(ModuleOrigin::BlockExpr { block: block.ast_id }, visibility);
|
ModuleOrigin::BlockExpr { block: block.ast_id, id: block_id },
|
||||||
|
visibility,
|
||||||
|
);
|
||||||
|
|
||||||
let mut def_map = DefMap::empty(krate, parent_map.data.edition, module_data);
|
let mut def_map = DefMap::empty(krate, parent_map.data.edition, module_data);
|
||||||
def_map.data = parent_map.data.clone();
|
def_map.data = parent_map.data.clone();
|
||||||
|
@ -338,7 +344,8 @@ impl DefMap {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let def_map = collector::collect_defs(db, def_map, tree_id);
|
let def_map =
|
||||||
|
collector::collect_defs(db, def_map, TreeId::new(block.ast_id.file_id, Some(block_id)));
|
||||||
Arc::new(def_map)
|
Arc::new(def_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,8 +649,8 @@ impl ModuleData {
|
||||||
ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
|
ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => {
|
||||||
definition.into()
|
definition.into()
|
||||||
}
|
}
|
||||||
ModuleOrigin::Inline { definition, .. } => definition.file_id,
|
ModuleOrigin::Inline { definition_tree_id, .. } => definition_tree_id.file_id(),
|
||||||
ModuleOrigin::BlockExpr { block } => block.file_id,
|
ModuleOrigin::BlockExpr { block, .. } => block.file_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,9 @@ use crate::{
|
||||||
visibility::{RawVisibility, Visibility},
|
visibility::{RawVisibility, Visibility},
|
||||||
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
|
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
|
||||||
ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern,
|
ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern,
|
||||||
ItemContainerId, LocalModuleId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId,
|
ItemContainerId, LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId,
|
||||||
MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc,
|
MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc,
|
||||||
TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc,
|
StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc,
|
||||||
};
|
};
|
||||||
|
|
||||||
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
||||||
|
@ -1461,7 +1461,7 @@ impl DefCollector<'_> {
|
||||||
let mut diagnosed_extern_crates = FxHashSet::default();
|
let mut diagnosed_extern_crates = FxHashSet::default();
|
||||||
for directive in &self.unresolved_imports {
|
for directive in &self.unresolved_imports {
|
||||||
if let ImportSource::ExternCrate { id } = directive.import.source {
|
if let ImportSource::ExternCrate { id } = directive.import.source {
|
||||||
let item_tree_id = self.db.lookup_intern_extern_crate(id).id;
|
let item_tree_id = id.lookup(self.db).id;
|
||||||
let item_tree = item_tree_id.item_tree(self.db);
|
let item_tree = item_tree_id.item_tree(self.db);
|
||||||
let extern_crate = &item_tree[item_tree_id.value];
|
let extern_crate = &item_tree[item_tree_id.value];
|
||||||
|
|
||||||
|
@ -1482,7 +1482,7 @@ impl DefCollector<'_> {
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let item_tree_id = self.db.lookup_intern_use(id).id;
|
let item_tree_id = id.lookup(self.db).id;
|
||||||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
|
self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
|
||||||
directive.module_id,
|
directive.module_id,
|
||||||
item_tree_id,
|
item_tree_id,
|
||||||
|
@ -1843,7 +1843,7 @@ impl ModCollector<'_, '_> {
|
||||||
ModKind::Inline { items } => {
|
ModKind::Inline { items } => {
|
||||||
let module_id = self.push_child_module(
|
let module_id = self.push_child_module(
|
||||||
module.name.clone(),
|
module.name.clone(),
|
||||||
AstId::new(self.file_id(), module.ast_id),
|
module.ast_id,
|
||||||
None,
|
None,
|
||||||
&self.item_tree[module.visibility],
|
&self.item_tree[module.visibility],
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -1881,7 +1881,7 @@ impl ModCollector<'_, '_> {
|
||||||
if is_enabled {
|
if is_enabled {
|
||||||
let module_id = self.push_child_module(
|
let module_id = self.push_child_module(
|
||||||
module.name.clone(),
|
module.name.clone(),
|
||||||
ast_id,
|
ast_id.value,
|
||||||
Some((file_id, is_mod_rs)),
|
Some((file_id, is_mod_rs)),
|
||||||
&self.item_tree[module.visibility],
|
&self.item_tree[module.visibility],
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -1908,7 +1908,7 @@ impl ModCollector<'_, '_> {
|
||||||
Err(candidates) => {
|
Err(candidates) => {
|
||||||
self.push_child_module(
|
self.push_child_module(
|
||||||
module.name.clone(),
|
module.name.clone(),
|
||||||
ast_id,
|
ast_id.value,
|
||||||
None,
|
None,
|
||||||
&self.item_tree[module.visibility],
|
&self.item_tree[module.visibility],
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -1925,7 +1925,7 @@ impl ModCollector<'_, '_> {
|
||||||
fn push_child_module(
|
fn push_child_module(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: Name,
|
name: Name,
|
||||||
declaration: AstId<ast::Module>,
|
declaration: FileAstId<ast::Module>,
|
||||||
definition: Option<(FileId, bool)>,
|
definition: Option<(FileId, bool)>,
|
||||||
visibility: &crate::visibility::RawVisibility,
|
visibility: &crate::visibility::RawVisibility,
|
||||||
mod_tree_id: FileItemTreeId<Mod>,
|
mod_tree_id: FileItemTreeId<Mod>,
|
||||||
|
|
|
@ -342,14 +342,7 @@ fn inner_attributes(
|
||||||
ast::Impl(it) => it.assoc_item_list()?.syntax().clone(),
|
ast::Impl(it) => it.assoc_item_list()?.syntax().clone(),
|
||||||
ast::Module(it) => it.item_list()?.syntax().clone(),
|
ast::Module(it) => it.item_list()?.syntax().clone(),
|
||||||
ast::BlockExpr(it) => {
|
ast::BlockExpr(it) => {
|
||||||
use syntax::SyntaxKind::{BLOCK_EXPR , EXPR_STMT};
|
if !it.may_carry_attributes() {
|
||||||
// Block expressions accept outer and inner attributes, but only when they are the outer
|
|
||||||
// expression of an expression statement or the final expression of another block expression.
|
|
||||||
let may_carry_attributes = matches!(
|
|
||||||
it.syntax().parent().map(|it| it.kind()),
|
|
||||||
Some(BLOCK_EXPR | EXPR_STMT)
|
|
||||||
);
|
|
||||||
if !may_carry_attributes {
|
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
syntax.clone()
|
syntax.clone()
|
||||||
|
|
|
@ -544,7 +544,7 @@ impl MacroCallKind {
|
||||||
};
|
};
|
||||||
|
|
||||||
let range = match kind {
|
let range = match kind {
|
||||||
MacroCallKind::FnLike { ast_id, .. } => ast_id.to_node(db).syntax().text_range(),
|
MacroCallKind::FnLike { ast_id, .. } => ast_id.to_ptr(db).text_range(),
|
||||||
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
|
MacroCallKind::Derive { ast_id, derive_attr_index, .. } => {
|
||||||
// FIXME: should be the range of the macro name, not the whole derive
|
// FIXME: should be the range of the macro name, not the whole derive
|
||||||
// FIXME: handle `cfg_attr`
|
// FIXME: handle `cfg_attr`
|
||||||
|
@ -840,9 +840,6 @@ impl<N: AstIdNode> AstId<N> {
|
||||||
pub type ErasedAstId = InFile<ErasedFileAstId>;
|
pub type ErasedAstId = InFile<ErasedFileAstId>;
|
||||||
|
|
||||||
impl ErasedAstId {
|
impl ErasedAstId {
|
||||||
pub fn to_node(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
|
|
||||||
self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id))
|
|
||||||
}
|
|
||||||
pub fn to_ptr(&self, db: &dyn db::ExpandDatabase) -> SyntaxNodePtr {
|
pub fn to_ptr(&self, db: &dyn db::ExpandDatabase) -> SyntaxNodePtr {
|
||||||
db.ast_id_map(self.file_id).get_raw(self.value)
|
db.ast_id_map(self.file_id).get_raw(self.value)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use hir_def::{
|
||||||
path::Path,
|
path::Path,
|
||||||
resolver::{resolver_for_expr, HasResolver, ResolveValueResult, ValueNs},
|
resolver::{resolver_for_expr, HasResolver, ResolveValueResult, ValueNs},
|
||||||
AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId,
|
AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId,
|
||||||
TraitId, TypeOrConstParamId,
|
Lookup, TraitId, TypeOrConstParamId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
|
@ -372,7 +372,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
||||||
match &self.body.exprs[expr_id] {
|
match &self.body.exprs[expr_id] {
|
||||||
Expr::Missing => {
|
Expr::Missing => {
|
||||||
if let DefWithBodyId::FunctionId(f) = self.owner {
|
if let DefWithBodyId::FunctionId(f) = self.owner {
|
||||||
let assoc = self.db.lookup_intern_function(f);
|
let assoc = f.lookup(self.db.upcast());
|
||||||
if let ItemContainerId::TraitId(t) = assoc.container {
|
if let ItemContainerId::TraitId(t) = assoc.container {
|
||||||
let name = &self.db.function_data(f).name;
|
let name = &self.db.function_data(f).name;
|
||||||
return Err(MirLowerError::TraitFunctionDefinition(t, name.clone()));
|
return Err(MirLowerError::TraitFunctionDefinition(t, name.clone()));
|
||||||
|
|
|
@ -719,20 +719,18 @@ fn emit_def_diagnostic_(
|
||||||
) {
|
) {
|
||||||
match diag {
|
match diag {
|
||||||
DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates } => {
|
DefDiagnosticKind::UnresolvedModule { ast: declaration, candidates } => {
|
||||||
let decl = declaration.to_node(db.upcast());
|
let decl = declaration.to_ptr(db.upcast());
|
||||||
acc.push(
|
acc.push(
|
||||||
UnresolvedModule {
|
UnresolvedModule {
|
||||||
decl: InFile::new(declaration.file_id, AstPtr::new(&decl)),
|
decl: InFile::new(declaration.file_id, decl),
|
||||||
candidates: candidates.clone(),
|
candidates: candidates.clone(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
DefDiagnosticKind::UnresolvedExternCrate { ast } => {
|
DefDiagnosticKind::UnresolvedExternCrate { ast } => {
|
||||||
let item = ast.to_node(db.upcast());
|
let item = ast.to_ptr(db.upcast());
|
||||||
acc.push(
|
acc.push(UnresolvedExternCrate { decl: InFile::new(ast.file_id, item) }.into());
|
||||||
UnresolvedExternCrate { decl: InFile::new(ast.file_id, AstPtr::new(&item)) }.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DefDiagnosticKind::UnresolvedImport { id, index } => {
|
DefDiagnosticKind::UnresolvedImport { id, index } => {
|
||||||
|
@ -747,13 +745,9 @@ fn emit_def_diagnostic_(
|
||||||
}
|
}
|
||||||
|
|
||||||
DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
|
DefDiagnosticKind::UnconfiguredCode { ast, cfg, opts } => {
|
||||||
let item = ast.to_node(db.upcast());
|
let item = ast.to_ptr(db.upcast());
|
||||||
acc.push(
|
acc.push(
|
||||||
InactiveCode {
|
InactiveCode { node: ast.with_value(item), cfg: cfg.clone(), opts: opts.clone() }
|
||||||
node: ast.with_value(SyntaxNodePtr::new(&item).into()),
|
|
||||||
cfg: cfg.clone(),
|
|
||||||
opts: opts.clone(),
|
|
||||||
}
|
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,14 @@ impl ast::BlockExpr {
|
||||||
pub fn tail_expr(&self) -> Option<ast::Expr> {
|
pub fn tail_expr(&self) -> Option<ast::Expr> {
|
||||||
self.stmt_list()?.tail_expr()
|
self.stmt_list()?.tail_expr()
|
||||||
}
|
}
|
||||||
|
/// Block expressions accept outer and inner attributes, but only when they are the outer
|
||||||
|
/// expression of an expression statement or the final expression of another block expression.
|
||||||
|
pub fn may_carry_attributes(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self.syntax().parent().map(|it| it.kind()),
|
||||||
|
Some(SyntaxKind::BLOCK_EXPR | SyntaxKind::EXPR_STMT)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
|
|
Loading…
Reference in a new issue