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.rs63
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)
+ }
}