Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/lower.rs')
| -rw-r--r-- | crates/hir-def/src/lower.rs | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/crates/hir-def/src/lower.rs b/crates/hir-def/src/lower.rs index e4786a1dd4..df5847929c 100644 --- a/crates/hir-def/src/lower.rs +++ b/crates/hir-def/src/lower.rs @@ -5,43 +5,53 @@ use hir_expand::{ span_map::{SpanMap, SpanMapRef}, AstId, HirFileId, InFile, }; -use intern::Interned; use span::{AstIdMap, AstIdNode}; +use stdx::thin_vec::ThinVec; use syntax::ast; use triomphe::Arc; -use crate::{db::DefDatabase, path::Path, type_ref::TypeBound}; +use crate::{ + db::DefDatabase, + path::Path, + type_ref::{TypeBound, TypePtr, TypeRef, TypeRefId, TypesMap, TypesSourceMap}, +}; pub struct LowerCtx<'a> { pub db: &'a dyn DefDatabase, file_id: HirFileId, span_map: OnceCell<SpanMap>, ast_id_map: OnceCell<Arc<AstIdMap>>, - impl_trait_bounds: RefCell<Vec<Vec<Interned<TypeBound>>>>, + impl_trait_bounds: RefCell<Vec<ThinVec<TypeBound>>>, // Prevent nested impl traits like `impl Foo<impl Bar>`. outer_impl_trait: RefCell<bool>, + types_map: RefCell<(&'a mut TypesMap, &'a mut TypesSourceMap)>, } -pub(crate) struct OuterImplTraitGuard<'a> { - ctx: &'a LowerCtx<'a>, +pub(crate) struct OuterImplTraitGuard<'a, 'b> { + ctx: &'a LowerCtx<'b>, old: bool, } -impl<'a> OuterImplTraitGuard<'a> { - fn new(ctx: &'a LowerCtx<'a>, impl_trait: bool) -> Self { +impl<'a, 'b> OuterImplTraitGuard<'a, 'b> { + fn new(ctx: &'a LowerCtx<'b>, impl_trait: bool) -> Self { let old = ctx.outer_impl_trait.replace(impl_trait); Self { ctx, old } } } -impl<'a> Drop for OuterImplTraitGuard<'a> { +impl Drop for OuterImplTraitGuard<'_, '_> { fn drop(&mut self) { self.ctx.outer_impl_trait.replace(self.old); } } impl<'a> LowerCtx<'a> { - pub fn new(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self { + pub fn new( + db: &'a dyn DefDatabase, + file_id: HirFileId, + types_map: &'a mut TypesMap, + types_source_map: &'a mut TypesSourceMap, + ) -> Self { LowerCtx { db, file_id, @@ -49,6 +59,7 @@ impl<'a> LowerCtx<'a> { ast_id_map: OnceCell::new(), impl_trait_bounds: RefCell::new(Vec::new()), outer_impl_trait: RefCell::default(), + types_map: RefCell::new((types_map, types_source_map)), } } @@ -56,6 +67,8 @@ impl<'a> LowerCtx<'a> { db: &'a dyn DefDatabase, file_id: HirFileId, span_map: OnceCell<SpanMap>, + types_map: &'a mut TypesMap, + types_source_map: &'a mut TypesSourceMap, ) -> Self { LowerCtx { db, @@ -64,6 +77,7 @@ impl<'a> LowerCtx<'a> { ast_id_map: OnceCell::new(), impl_trait_bounds: RefCell::new(Vec::new()), outer_impl_trait: RefCell::default(), + types_map: RefCell::new((types_map, types_source_map)), } } @@ -82,11 +96,11 @@ impl<'a> LowerCtx<'a> { ) } - pub fn update_impl_traits_bounds(&self, bounds: Vec<Interned<TypeBound>>) { + pub fn update_impl_traits_bounds(&self, bounds: ThinVec<TypeBound>) { self.impl_trait_bounds.borrow_mut().push(bounds); } - pub fn take_impl_traits_bounds(&self) -> Vec<Vec<Interned<TypeBound>>> { + pub fn take_impl_traits_bounds(&self) -> Vec<ThinVec<TypeBound>> { self.impl_trait_bounds.take() } @@ -94,7 +108,32 @@ impl<'a> LowerCtx<'a> { *self.outer_impl_trait.borrow() } - pub(crate) fn outer_impl_trait_scope(&'a self, impl_trait: bool) -> OuterImplTraitGuard<'a> { + pub(crate) fn outer_impl_trait_scope<'b>( + &'b self, + impl_trait: bool, + ) -> OuterImplTraitGuard<'b, 'a> { OuterImplTraitGuard::new(self, impl_trait) } + + pub(crate) fn alloc_type_ref(&self, type_ref: TypeRef, node: TypePtr) -> TypeRefId { + let mut types_map = self.types_map.borrow_mut(); + let (types_map, types_source_map) = &mut *types_map; + let id = types_map.types.alloc(type_ref); + types_source_map.types_map_back.insert(id, InFile::new(self.file_id, node)); + id + } + + pub(crate) fn alloc_type_ref_desugared(&self, type_ref: TypeRef) -> TypeRefId { + self.types_map.borrow_mut().0.types.alloc(type_ref) + } + + pub(crate) fn alloc_error_type(&self) -> TypeRefId { + self.types_map.borrow_mut().0.types.alloc(TypeRef::Error) + } + + // FIXME: If we alloc while holding this, well... Bad Things will happen. Need to change this + // to use proper mutability instead of interior mutability. + pub(crate) fn types_map(&self) -> std::cell::Ref<'_, TypesMap> { + std::cell::Ref::map(self.types_map.borrow(), |it| &*it.0) + } } |