From bb6e1bf811bce09fdab115a4257e47cc0d5ddc82 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 24 Mar 2021 17:00:29 +0100 Subject: Lower traits to TraitRef instead of TypeRef --- crates/hir_def/src/data.rs | 4 ++-- crates/hir_def/src/item_tree.rs | 41 +++++++++++++++++++++++++++++++++-- crates/hir_def/src/item_tree/lower.rs | 10 +++++++-- crates/hir_def/src/type_ref.rs | 19 ++++++++++++++++ 4 files changed, 68 insertions(+), 6 deletions(-) (limited to 'crates/hir_def') diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index 0be868ba2..7d35d7083 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs @@ -10,7 +10,7 @@ use crate::{ body::Expander, db::DefDatabase, item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem, Param}, - type_ref::{TypeBound, TypeRef}, + type_ref::{TraitRef, TypeBound, TypeRef}, visibility::RawVisibility, AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, @@ -156,7 +156,7 @@ impl TraitData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ImplData { - pub target_trait: Option, + pub target_trait: Option, pub target_type: TypeRef, pub items: Vec, pub is_negative: bool, diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index ca0048b16..db94bb1ef 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -31,7 +31,7 @@ use crate::{ db::DefDatabase, generics::GenericParams, path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, - type_ref::{Mutability, TypeBound, TypeRef}, + type_ref::{Mutability, TraitRef, TypeBound, TypeRef}, visibility::RawVisibility, }; @@ -147,6 +147,7 @@ impl ItemTree { vis, generics, type_refs, + trait_refs, inner_items, } = &mut **data; @@ -173,6 +174,7 @@ impl ItemTree { generics.arena.shrink_to_fit(); type_refs.arena.shrink_to_fit(); type_refs.map.shrink_to_fit(); + trait_refs.map.shrink_to_fit(); inner_items.shrink_to_fit(); } @@ -295,6 +297,32 @@ impl TypeRefStorage { } } +/// `TraitRef` interner. +#[derive(Default, Debug, Eq, PartialEq)] +struct TraitRefStorage { + arena: Arena>, + map: FxHashMap, Idx>>, +} + +impl TraitRefStorage { + // Note: We lie about the `Idx` to hide the interner details. + + fn intern(&mut self, ty: TraitRef) -> Idx { + if let Some(id) = self.map.get(&ty) { + return Idx::from_raw(id.into_raw()); + } + + let ty = Arc::new(ty); + let idx = self.arena.alloc(ty.clone()); + self.map.insert(ty, idx); + Idx::from_raw(idx.into_raw()) + } + + fn lookup(&self, id: Idx) -> &TraitRef { + &self.arena[Idx::from_raw(id.into_raw())] + } +} + #[derive(Default, Debug, Eq, PartialEq)] struct ItemTreeData { imports: Arena, @@ -319,6 +347,7 @@ struct ItemTreeData { vis: ItemVisibilities, generics: GenericParamsStorage, type_refs: TypeRefStorage, + trait_refs: TraitRefStorage, inner_items: FxHashMap, SmallVec<[ModItem; 1]>>, } @@ -556,6 +585,14 @@ impl Index> for ItemTree { } } +impl Index> for ItemTree { + type Output = TraitRef; + + fn index(&self, id: Idx) -> &Self::Output { + self.data().trait_refs.lookup(id) + } +} + impl Index> for ItemTree { type Output = N; fn index(&self, id: FileItemTreeId) -> &N { @@ -692,7 +729,7 @@ pub struct Trait { #[derive(Debug, Clone, Eq, PartialEq)] pub struct Impl { pub generic_params: GenericParamsId, - pub target_trait: Option>, + pub target_trait: Option>, pub target_type: Idx, pub is_negative: bool, pub items: Box<[AssocItem]>, diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 3f558edd8..34af5c8d4 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -11,7 +11,7 @@ use syntax::{ use crate::{ generics::{GenericParams, TypeParamData, TypeParamProvenance}, - type_ref::LifetimeRef, + type_ref::{LifetimeRef, TraitRef}, }; use super::*; @@ -536,7 +536,7 @@ impl Ctx { fn lower_impl(&mut self, impl_def: &ast::Impl) -> Option> { let generic_params = self.lower_generic_params_and_inner_items(GenericsOwner::Impl, impl_def); - let target_trait = impl_def.trait_().map(|tr| self.lower_type_ref(&tr)); + let target_trait = impl_def.trait_().map(|tr| self.lower_trait_ref(&tr)); let target_type = self.lower_type_ref(&impl_def.self_ty()?); let is_negative = impl_def.excl_token().is_some(); @@ -740,10 +740,16 @@ impl Ctx { self.data().vis.alloc(vis) } + fn lower_trait_ref(&mut self, trait_ref: &ast::Type) -> Idx { + let trait_ref = TraitRef::from_ast(&self.body_ctx, trait_ref.clone()); + self.data().trait_refs.intern(trait_ref) + } + fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Idx { let tyref = TypeRef::from_ast(&self.body_ctx, type_ref.clone()); self.data().type_refs.intern(tyref) } + fn lower_type_ref_opt(&mut self, type_ref: Option) -> Idx { match type_ref.map(|ty| self.lower_type_ref(&ty)) { Some(it) => it, diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs index 049b2e462..b7484ed0d 100644 --- a/crates/hir_def/src/type_ref.rs +++ b/crates/hir_def/src/type_ref.rs @@ -51,6 +51,25 @@ impl Rawness { } } +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub enum TraitRef { + Path(Path), + Error, +} + +impl TraitRef { + /// Converts an `ast::PathType` to a `hir::TraitRef`. + pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::Type) -> Self { + // FIXME: Use `Path::from_src` + match node { + ast::Type::PathType(path) => path + .path() + .and_then(|it| ctx.lower_path(it)) + .map_or(TraitRef::Error, TraitRef::Path), + _ => TraitRef::Error, + } + } +} /// Compare ty::Ty #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum TypeRef { -- cgit v1.2.3 From c2a63b97a80cb738f800da61c64e748994709c31 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 29 Mar 2021 17:46:33 +0200 Subject: Rename target_ty to self_ty --- crates/hir_def/src/data.rs | 6 +++--- crates/hir_def/src/item_tree.rs | 2 +- crates/hir_def/src/item_tree/lower.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'crates/hir_def') diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index 7d35d7083..214bcc648 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs @@ -157,7 +157,7 @@ impl TraitData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ImplData { pub target_trait: Option, - pub target_type: TypeRef, + pub self_ty: TypeRef, pub items: Vec, pub is_negative: bool, } @@ -170,7 +170,7 @@ impl ImplData { let item_tree = impl_loc.id.item_tree(db); let impl_def = &item_tree[impl_loc.id.value]; let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone()); - let target_type = item_tree[impl_def.target_type].clone(); + let self_ty = item_tree[impl_def.self_ty].clone(); let is_negative = impl_def.is_negative; let module_id = impl_loc.container; let container = AssocContainerId::ImplId(id); @@ -187,7 +187,7 @@ impl ImplData { ); let items = items.into_iter().map(|(_, item)| item).collect(); - Arc::new(ImplData { target_trait, target_type, items, is_negative }) + Arc::new(ImplData { target_trait, self_ty, items, is_negative }) } } diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index db94bb1ef..5449bbf5d 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -730,7 +730,7 @@ pub struct Trait { pub struct Impl { pub generic_params: GenericParamsId, pub target_trait: Option>, - pub target_type: Idx, + pub self_ty: Idx, pub is_negative: bool, pub items: Box<[AssocItem]>, pub ast_id: FileAstId, diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 34af5c8d4..4b2af564e 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -537,7 +537,7 @@ impl Ctx { let generic_params = self.lower_generic_params_and_inner_items(GenericsOwner::Impl, impl_def); let target_trait = impl_def.trait_().map(|tr| self.lower_trait_ref(&tr)); - let target_type = self.lower_type_ref(&impl_def.self_ty()?); + let self_ty = self.lower_type_ref(&impl_def.self_ty()?); let is_negative = impl_def.excl_token().is_some(); // We cannot use `assoc_items()` here as that does not include macro calls. @@ -554,7 +554,7 @@ impl Ctx { }) .collect(); let ast_id = self.source_ast_id_map.ast_id(impl_def); - let res = Impl { generic_params, target_trait, target_type, is_negative, items, ast_id }; + let res = Impl { generic_params, target_trait, self_ty, is_negative, items, ast_id }; Some(id(self.data().impls.alloc(res))) } -- cgit v1.2.3 From b4bb7743810b1e6ac8b897a465c430e9ed8d5c44 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 29 Mar 2021 18:39:58 +0200 Subject: Remove TraitRef::Error --- crates/hir_def/src/item_tree/lower.rs | 11 +++++++---- crates/hir_def/src/type_ref.rs | 16 +++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'crates/hir_def') diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 4b2af564e..8d3862811 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -536,7 +536,10 @@ impl Ctx { fn lower_impl(&mut self, impl_def: &ast::Impl) -> Option> { let generic_params = self.lower_generic_params_and_inner_items(GenericsOwner::Impl, impl_def); - let target_trait = impl_def.trait_().map(|tr| self.lower_trait_ref(&tr)); + // FIXME: If trait lowering fails, due to a non PathType for example, we treat this impl + // as if it was an non-trait impl. Ideally we want to create a unique missing ref that only + // equals itself. + let target_trait = impl_def.trait_().and_then(|tr| self.lower_trait_ref(&tr)); let self_ty = self.lower_type_ref(&impl_def.self_ty()?); let is_negative = impl_def.excl_token().is_some(); @@ -740,9 +743,9 @@ impl Ctx { self.data().vis.alloc(vis) } - fn lower_trait_ref(&mut self, trait_ref: &ast::Type) -> Idx { - let trait_ref = TraitRef::from_ast(&self.body_ctx, trait_ref.clone()); - self.data().trait_refs.intern(trait_ref) + fn lower_trait_ref(&mut self, trait_ref: &ast::Type) -> Option> { + let trait_ref = TraitRef::from_ast(&self.body_ctx, trait_ref.clone())?; + Some(self.data().trait_refs.intern(trait_ref)) } fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Idx { diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs index b7484ed0d..4c24aae94 100644 --- a/crates/hir_def/src/type_ref.rs +++ b/crates/hir_def/src/type_ref.rs @@ -52,21 +52,19 @@ impl Rawness { } #[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub enum TraitRef { - Path(Path), - Error, +pub struct TraitRef { + pub path: Path, } impl TraitRef { /// Converts an `ast::PathType` to a `hir::TraitRef`. - pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::Type) -> Self { + pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::Type) -> Option { // FIXME: Use `Path::from_src` match node { - ast::Type::PathType(path) => path - .path() - .and_then(|it| ctx.lower_path(it)) - .map_or(TraitRef::Error, TraitRef::Path), - _ => TraitRef::Error, + ast::Type::PathType(path) => { + path.path().and_then(|it| ctx.lower_path(it)).map(|path| TraitRef { path }) + } + _ => None, } } } -- cgit v1.2.3