diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index faa3a8931b0..a165ba85e61 100644 --- a/crates/hir-def/src/body.rs +++ b/crates/hir-def/src/body.rs @@ -77,6 +77,10 @@ pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::HasAt let attrs = self.parse_attrs(db, owner); attrs.is_cfg_enabled(&self.cfg_options) } + + pub(crate) fn hygiene(&self) -> &Hygiene { + &self.hygiene + } } impl Expander { @@ -181,6 +185,10 @@ pub fn exit(&mut self, db: &dyn DefDatabase, mut mark: Mark) { mark.bomb.defuse(); } + pub fn ctx<'a>(&self, db: &'a dyn DefDatabase) -> LowerCtx<'a> { + LowerCtx::new(db, &self.cfg_expander.hygiene, self.current_file_id) + } + pub(crate) fn to_source(&self, value: T) -> InFile { InFile { file_id: self.current_file_id, value } } diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index 8a773899cfc..b87fb94d923 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -39,7 +39,6 @@ RecordFieldPat, RecordLitField, Statement, }, item_scope::BuiltinShadowMode, - item_tree::ItemTree, lang_item::LangItem, path::{GenericArgs, Path}, type_ref::{Mutability, Rawness, TypeRef}, @@ -53,7 +52,11 @@ pub struct LowerCtx<'a> { } impl<'a> LowerCtx<'a> { - pub fn new(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self { + pub fn new(db: &'a dyn DefDatabase, hygiene: &Hygiene, file_id: HirFileId) -> Self { + LowerCtx { db, hygiene: hygiene.clone(), ast_id_map: Some((file_id, OnceCell::new())) } + } + + pub fn with_file_id(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self { LowerCtx { db, hygiene: Hygiene::new(db.upcast(), file_id), @@ -230,7 +233,7 @@ fn collect( } fn ctx(&self) -> LowerCtx<'_> { - LowerCtx::new(self.db, self.expander.current_file_id) + self.expander.ctx(self.db) } fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId { @@ -973,8 +976,18 @@ fn collect_block_( block: ast::BlockExpr, mk_block: impl FnOnce(Option, Box<[Statement]>, Option) -> Expr, ) -> ExprId { - let block_id = if ItemTree::block_has_items(self.db, self.expander.current_file_id, &block) - { + let block_has_items = { + let statement_has_item = block.statements().any(|stmt| match stmt { + ast::Stmt::Item(_) => true, + // Macro calls can be both items and expressions. The syntax library always treats + // them as expressions here, so we undo that. + ast::Stmt::ExprStmt(es) => matches!(es.expr(), Some(ast::Expr::MacroExpr(_))), + _ => false, + }); + statement_has_item || matches!(block.tail_expr(), Some(ast::Expr::MacroExpr(_))) + }; + + let block_id = if block_has_items { let file_local_id = self.ast_id_map.ast_id(&block); let ast_id = AstId::new(self.expander.current_file_id, file_local_id); Some(self.db.intern_block(BlockLoc { diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs index 7a5025aa6a5..0b6a51fe764 100644 --- a/crates/hir-def/src/data/adt.rs +++ b/crates/hir-def/src/data/adt.rs @@ -473,7 +473,7 @@ fn lower_struct( trace: &mut Trace>, ast: &InFile, ) -> StructKind { - let ctx = LowerCtx::new(db, ast.file_id); + let ctx = LowerCtx::new(db, &expander.hygiene(), ast.file_id); match &ast.value { ast::StructKind::Tuple(fl) => { diff --git a/crates/hir-def/src/generics.rs b/crates/hir-def/src/generics.rs index 4285a0ca72c..30edaed1095 100644 --- a/crates/hir-def/src/generics.rs +++ b/crates/hir-def/src/generics.rs @@ -12,7 +12,6 @@ use intern::Interned; use la_arena::{Arena, ArenaMap, Idx}; use once_cell::unsync::Lazy; -use std::ops::DerefMut; use stdx::impl_from; use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds}; @@ -328,7 +327,7 @@ fn add_where_predicate_from_bound( pub(crate) fn fill_implicit_impl_trait_args( &mut self, db: &dyn DefDatabase, - expander: &mut impl DerefMut, + expander: &mut Expander, type_ref: &TypeRef, ) { type_ref.walk(&mut |type_ref| { @@ -350,7 +349,7 @@ pub(crate) fn fill_implicit_impl_trait_args( let macro_call = mc.to_node(db.upcast()); match expander.enter_expand::(db, macro_call) { Ok(ExpandResult { value: Some((mark, expanded)), .. }) => { - let ctx = LowerCtx::new(db, expander.current_file_id()); + let ctx = expander.ctx(db); let type_ref = TypeRef::from_ast(&ctx, expanded); self.fill_implicit_impl_trait_args(db, expander, &type_ref); expander.exit(db, mark); diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index d5b973751dd..d445e063f5f 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -152,14 +152,6 @@ pub fn top_level_items(&self) -> &[ModItem] { &self.top_level } - pub fn block_has_items( - db: &dyn DefDatabase, - file_id: HirFileId, - block: &ast::BlockExpr, - ) -> bool { - lower::Ctx::new(db, file_id).block_has_items(block) - } - /// Returns the inner attributes of the source file. pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs { Attrs::filter( diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index 5bbf8e52e8b..0488bad3f98 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -29,7 +29,7 @@ pub(super) fn new(db: &'a dyn DefDatabase, file: HirFileId) -> Self { db, tree: ItemTree::default(), source_ast_id_map: db.ast_id_map(file), - body_ctx: crate::body::LowerCtx::new(db, file), + body_ctx: crate::body::LowerCtx::with_file_id(db, file), } } @@ -101,34 +101,6 @@ pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree { self.tree } - pub(super) fn block_has_items(mut self, block: &ast::BlockExpr) -> bool { - let statement_has_item = block - .statements() - .find_map(|stmt| match stmt { - ast::Stmt::Item(item) => self.lower_mod_item(&item), - // Macro calls can be both items and expressions. The syntax library always treats - // them as expressions here, so we undo that. - ast::Stmt::ExprStmt(es) => match es.expr()? { - ast::Expr::MacroExpr(expr) => self.lower_mod_item(&expr.macro_call()?.into()), - _ => None, - }, - _ => None, - }) - .is_some(); - if statement_has_item { - return true; - } - - if let Some(ast::Expr::MacroExpr(expr)) = block.tail_expr() { - if let Some(call) = expr.macro_call() { - if let Some(_) = self.lower_mod_item(&call.into()) { - return true; - } - } - } - false - } - fn data(&mut self) -> &mut ItemTreeData { self.tree.data_mut() } diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index d69fd8c8110..fd05e516c26 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -18,7 +18,7 @@ use either::Either; use hir_def::{ - body::{Expander, LowerCtx}, + body::Expander, builtin_type::BuiltinType, data::adt::StructKind, generics::{ @@ -380,7 +380,7 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option) { let macro_call = macro_call.to_node(self.db.upcast()); match expander.enter_expand::(self.db.upcast(), macro_call) { Ok(ExpandResult { value: Some((mark, expanded)), .. }) => { - let ctx = LowerCtx::new(self.db.upcast(), expander.current_file_id()); + let ctx = expander.ctx(self.db.upcast()); let type_ref = TypeRef::from_ast(&ctx, expanded); drop(expander); diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 5b1d7649fa3..ffd0b0ad7ad 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -1065,7 +1065,7 @@ fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option