Don't recreate Hygiene unnecessarily
This commit is contained in:
parent
b7c443569a
commit
f742943a4b
@ -77,6 +77,10 @@ impl CfgExpander {
|
|||||||
let attrs = self.parse_attrs(db, owner);
|
let attrs = self.parse_attrs(db, owner);
|
||||||
attrs.is_cfg_enabled(&self.cfg_options)
|
attrs.is_cfg_enabled(&self.cfg_options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn hygiene(&self) -> &Hygiene {
|
||||||
|
&self.hygiene
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expander {
|
impl Expander {
|
||||||
@ -181,6 +185,10 @@ impl Expander {
|
|||||||
mark.bomb.defuse();
|
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> {
|
pub(crate) fn to_source<T>(&self, value: T) -> InFile<T> {
|
||||||
InFile { file_id: self.current_file_id, value }
|
InFile { file_id: self.current_file_id, value }
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,6 @@ use crate::{
|
|||||||
RecordFieldPat, RecordLitField, Statement,
|
RecordFieldPat, RecordLitField, Statement,
|
||||||
},
|
},
|
||||||
item_scope::BuiltinShadowMode,
|
item_scope::BuiltinShadowMode,
|
||||||
item_tree::ItemTree,
|
|
||||||
lang_item::LangItem,
|
lang_item::LangItem,
|
||||||
path::{GenericArgs, Path},
|
path::{GenericArgs, Path},
|
||||||
type_ref::{Mutability, Rawness, TypeRef},
|
type_ref::{Mutability, Rawness, TypeRef},
|
||||||
@ -53,7 +52,11 @@ pub struct LowerCtx<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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 {
|
LowerCtx {
|
||||||
db,
|
db,
|
||||||
hygiene: Hygiene::new(db.upcast(), file_id),
|
hygiene: Hygiene::new(db.upcast(), file_id),
|
||||||
@ -230,7 +233,7 @@ impl ExprCollector<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ctx(&self) -> LowerCtx<'_> {
|
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 {
|
fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
|
||||||
@ -973,8 +976,18 @@ impl ExprCollector<'_> {
|
|||||||
block: ast::BlockExpr,
|
block: ast::BlockExpr,
|
||||||
mk_block: impl FnOnce(Option<BlockId>, Box<[Statement]>, Option<ExprId>) -> Expr,
|
mk_block: impl FnOnce(Option<BlockId>, Box<[Statement]>, Option<ExprId>) -> Expr,
|
||||||
) -> ExprId {
|
) -> 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 file_local_id = self.ast_id_map.ast_id(&block);
|
||||||
let ast_id = AstId::new(self.expander.current_file_id, file_local_id);
|
let ast_id = AstId::new(self.expander.current_file_id, file_local_id);
|
||||||
Some(self.db.intern_block(BlockLoc {
|
Some(self.db.intern_block(BlockLoc {
|
||||||
|
@ -473,7 +473,7 @@ fn lower_struct(
|
|||||||
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
|
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
|
||||||
ast: &InFile<ast::StructKind>,
|
ast: &InFile<ast::StructKind>,
|
||||||
) -> StructKind {
|
) -> StructKind {
|
||||||
let ctx = LowerCtx::new(db, ast.file_id);
|
let ctx = LowerCtx::new(db, &expander.hygiene(), ast.file_id);
|
||||||
|
|
||||||
match &ast.value {
|
match &ast.value {
|
||||||
ast::StructKind::Tuple(fl) => {
|
ast::StructKind::Tuple(fl) => {
|
||||||
|
@ -12,7 +12,6 @@ use hir_expand::{
|
|||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use la_arena::{Arena, ArenaMap, Idx};
|
use la_arena::{Arena, ArenaMap, Idx};
|
||||||
use once_cell::unsync::Lazy;
|
use once_cell::unsync::Lazy;
|
||||||
use std::ops::DerefMut;
|
|
||||||
use stdx::impl_from;
|
use stdx::impl_from;
|
||||||
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
|
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
|
||||||
|
|
||||||
@ -328,7 +327,7 @@ impl GenericParams {
|
|||||||
pub(crate) fn fill_implicit_impl_trait_args(
|
pub(crate) fn fill_implicit_impl_trait_args(
|
||||||
&mut self,
|
&mut self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
expander: &mut impl DerefMut<Target = Expander>,
|
expander: &mut Expander,
|
||||||
type_ref: &TypeRef,
|
type_ref: &TypeRef,
|
||||||
) {
|
) {
|
||||||
type_ref.walk(&mut |type_ref| {
|
type_ref.walk(&mut |type_ref| {
|
||||||
@ -350,7 +349,7 @@ impl GenericParams {
|
|||||||
let macro_call = mc.to_node(db.upcast());
|
let macro_call = mc.to_node(db.upcast());
|
||||||
match expander.enter_expand::<ast::Type>(db, macro_call) {
|
match expander.enter_expand::<ast::Type>(db, macro_call) {
|
||||||
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
|
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);
|
let type_ref = TypeRef::from_ast(&ctx, expanded);
|
||||||
self.fill_implicit_impl_trait_args(db, expander, &type_ref);
|
self.fill_implicit_impl_trait_args(db, expander, &type_ref);
|
||||||
expander.exit(db, mark);
|
expander.exit(db, mark);
|
||||||
|
@ -152,14 +152,6 @@ impl ItemTree {
|
|||||||
&self.top_level
|
&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.
|
/// Returns the inner attributes of the source file.
|
||||||
pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs {
|
pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs {
|
||||||
Attrs::filter(
|
Attrs::filter(
|
||||||
|
@ -29,7 +29,7 @@ impl<'a> Ctx<'a> {
|
|||||||
db,
|
db,
|
||||||
tree: ItemTree::default(),
|
tree: ItemTree::default(),
|
||||||
source_ast_id_map: db.ast_id_map(file),
|
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
|
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 {
|
fn data(&mut self) -> &mut ItemTreeData {
|
||||||
self.tree.data_mut()
|
self.tree.data_mut()
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ use chalk_ir::{
|
|||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
body::{Expander, LowerCtx},
|
body::Expander,
|
||||||
builtin_type::BuiltinType,
|
builtin_type::BuiltinType,
|
||||||
data::adt::StructKind,
|
data::adt::StructKind,
|
||||||
generics::{
|
generics::{
|
||||||
@ -380,7 +380,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||||||
let macro_call = macro_call.to_node(self.db.upcast());
|
let macro_call = macro_call.to_node(self.db.upcast());
|
||||||
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
|
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call) {
|
||||||
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
|
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);
|
let type_ref = TypeRef::from_ast(&ctx, expanded);
|
||||||
|
|
||||||
drop(expander);
|
drop(expander);
|
||||||
|
@ -1065,7 +1065,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
|
|
||||||
fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
|
fn resolve_type(&self, ty: &ast::Type) -> Option<Type> {
|
||||||
let analyze = self.analyze(ty.syntax())?;
|
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)
|
let ty = hir_ty::TyLoweringContext::new(self.db, &analyze.resolver)
|
||||||
.lower_ty(&crate::TypeRef::from_ast(&ctx, ty.clone()));
|
.lower_ty(&crate::TypeRef::from_ast(&ctx, ty.clone()));
|
||||||
Some(Type::new_with_resolver(self.db, &analyze.resolver, ty))
|
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
|
/// 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.
|
/// necessary a heuristic, as it doesn't take hygiene into account.
|
||||||
pub fn speculative_resolve(&self, path: &ast::Path) -> Option<PathResolution> {
|
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)?;
|
let path = Path::from_src(path.clone(), &ctx)?;
|
||||||
resolve_hir_path(self.db, &self.resolver, &path)
|
resolve_hir_path(self.db, &self.resolver, &path)
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,7 @@ impl SourceAnalyzer {
|
|||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
macro_call: InFile<&ast::MacroCall>,
|
macro_call: InFile<&ast::MacroCall>,
|
||||||
) -> Option<Macro> {
|
) -> 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))?;
|
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())
|
self.resolver.resolve_path_as_macro(db.upcast(), path.mod_path()?).map(|it| it.into())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user