about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir-def/src/body.rs8
-rw-r--r--crates/hir-def/src/body/lower.rs23
-rw-r--r--crates/hir-def/src/data/adt.rs2
-rw-r--r--crates/hir-def/src/generics.rs5
-rw-r--r--crates/hir-def/src/item_tree.rs8
-rw-r--r--crates/hir-def/src/item_tree/lower.rs30
-rw-r--r--crates/hir-ty/src/lower.rs4
-rw-r--r--crates/hir/src/semantics.rs4
-rw-r--r--crates/hir/src/source_analyzer.rs2
9 files changed, 35 insertions, 51 deletions
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 @@ impl CfgExpander {
         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 @@ impl Expander {
         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<T>(&self, value: T) -> InFile<T> {
         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 @@ use crate::{
         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 @@ impl ExprCollector<'_> {
     }
 
     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 @@ impl ExprCollector<'_> {
         block: ast::BlockExpr,
         mk_block: impl FnOnce(Option<BlockId>, Box<[Statement]>, Option<ExprId>) -> 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<FieldData, Either<ast::TupleField, ast::RecordField>>,
     ast: &InFile<ast::StructKind>,
 ) -> 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 hir_expand::{
 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 @@ impl GenericParams {
     pub(crate) fn fill_implicit_impl_trait_args(
         &mut self,
         db: &dyn DefDatabase,
-        expander: &mut impl DerefMut<Target = Expander>,
+        expander: &mut Expander,
         type_ref: &TypeRef,
     ) {
         type_ref.walk(&mut |type_ref| {
@@ -350,7 +349,7 @@ impl GenericParams {
                 let macro_call = mc.to_node(db.upcast());
                 match expander.enter_expand::<ast::Type>(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 @@ impl ItemTree {
         &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 @@ impl<'a> Ctx<'a> {
             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 @@ impl<'a> Ctx<'a> {
         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 chalk_ir::{
 
 use either::Either;
 use hir_def::{
-    body::{Expander, LowerCtx},
+    body::Expander,
     builtin_type::BuiltinType,
     data::adt::StructKind,
     generics::{
@@ -380,7 +380,7 @@ impl<'a> TyLoweringContext<'a> {
                     let macro_call = macro_call.to_node(self.db.upcast());
                     match expander.enter_expand::<ast::Type>(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 @@ impl<'db> SemanticsImpl<'db> {
 
     fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
         let analyze = self.analyze(ty.syntax())?;
-        let ctx = body::LowerCtx::new(self.db.upcast(), analyze.file_id);
+        let ctx = body::LowerCtx::with_file_id(self.db.upcast(), analyze.file_id);
         let ty = hir_ty::TyLoweringContext::new(self.db, &analyze.resolver)
             .lower_ty(&crate::TypeRef::from_ast(&ctx, ty.clone()));
         Some(Type::new_with_resolver(self.db, &analyze.resolver, ty))
@@ -1672,7 +1672,7 @@ impl<'a> SemanticsScope<'a> {
     /// Resolve a path as-if it was written at the given scope. This is
     /// necessary a heuristic, as it doesn't take hygiene into account.
     pub fn speculative_resolve(&self, path: &ast::Path) -> Option<PathResolution> {
-        let ctx = body::LowerCtx::new(self.db.upcast(), self.file_id);
+        let ctx = body::LowerCtx::with_file_id(self.db.upcast(), self.file_id);
         let path = Path::from_src(path.clone(), &ctx)?;
         resolve_hir_path(self.db, &self.resolver, &path)
     }
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 1c50d81e1bd..2a7a0ae4c43 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -463,7 +463,7 @@ impl SourceAnalyzer {
         db: &dyn HirDatabase,
         macro_call: InFile<&ast::MacroCall>,
     ) -> Option<Macro> {
-        let ctx = body::LowerCtx::new(db.upcast(), macro_call.file_id);
+        let ctx = body::LowerCtx::with_file_id(db.upcast(), macro_call.file_id);
         let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
         self.resolver.resolve_path_as_macro(db.upcast(), path.mod_path()?).map(|it| it.into())
     }