Skip to content

Commit bb6e1bf

Browse files
committed
Lower traits to TraitRef instead of TypeRef
1 parent bb1d925 commit bb6e1bf

File tree

6 files changed

+76
-14
lines changed

6 files changed

+76
-14
lines changed

crates/hir/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use hir_def::{
4444
per_ns::PerNs,
4545
resolver::{HasResolver, Resolver},
4646
src::HasSource as _,
47+
type_ref::TraitRef,
4748
AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId,
4849
DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId,
4950
LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
@@ -1613,7 +1614,7 @@ impl Impl {
16131614

16141615
// FIXME: the return type is wrong. This should be a hir version of
16151616
// `TraitRef` (ie, resolved `TypeRef`).
1616-
pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> {
1617+
pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TraitRef> {
16171618
db.impl_data(self.id).target_trait.clone()
16181619
}
16191620

crates/hir_def/src/data.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
body::Expander,
1111
db::DefDatabase,
1212
item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem, Param},
13-
type_ref::{TypeBound, TypeRef},
13+
type_ref::{TraitRef, TypeBound, TypeRef},
1414
visibility::RawVisibility,
1515
AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
1616
Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
@@ -156,7 +156,7 @@ impl TraitData {
156156

157157
#[derive(Debug, Clone, PartialEq, Eq)]
158158
pub struct ImplData {
159-
pub target_trait: Option<TypeRef>,
159+
pub target_trait: Option<TraitRef>,
160160
pub target_type: TypeRef,
161161
pub items: Vec<AssocItemId>,
162162
pub is_negative: bool,

crates/hir_def/src/item_tree.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::{
3131
db::DefDatabase,
3232
generics::GenericParams,
3333
path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
34-
type_ref::{Mutability, TypeBound, TypeRef},
34+
type_ref::{Mutability, TraitRef, TypeBound, TypeRef},
3535
visibility::RawVisibility,
3636
};
3737

@@ -147,6 +147,7 @@ impl ItemTree {
147147
vis,
148148
generics,
149149
type_refs,
150+
trait_refs,
150151
inner_items,
151152
} = &mut **data;
152153

@@ -173,6 +174,7 @@ impl ItemTree {
173174
generics.arena.shrink_to_fit();
174175
type_refs.arena.shrink_to_fit();
175176
type_refs.map.shrink_to_fit();
177+
trait_refs.map.shrink_to_fit();
176178

177179
inner_items.shrink_to_fit();
178180
}
@@ -295,6 +297,32 @@ impl TypeRefStorage {
295297
}
296298
}
297299

300+
/// `TraitRef` interner.
301+
#[derive(Default, Debug, Eq, PartialEq)]
302+
struct TraitRefStorage {
303+
arena: Arena<Arc<TraitRef>>,
304+
map: FxHashMap<Arc<TraitRef>, Idx<Arc<TraitRef>>>,
305+
}
306+
307+
impl TraitRefStorage {
308+
// Note: We lie about the `Idx<TraitRef>` to hide the interner details.
309+
310+
fn intern(&mut self, ty: TraitRef) -> Idx<TraitRef> {
311+
if let Some(id) = self.map.get(&ty) {
312+
return Idx::from_raw(id.into_raw());
313+
}
314+
315+
let ty = Arc::new(ty);
316+
let idx = self.arena.alloc(ty.clone());
317+
self.map.insert(ty, idx);
318+
Idx::from_raw(idx.into_raw())
319+
}
320+
321+
fn lookup(&self, id: Idx<TraitRef>) -> &TraitRef {
322+
&self.arena[Idx::from_raw(id.into_raw())]
323+
}
324+
}
325+
298326
#[derive(Default, Debug, Eq, PartialEq)]
299327
struct ItemTreeData {
300328
imports: Arena<Import>,
@@ -319,6 +347,7 @@ struct ItemTreeData {
319347
vis: ItemVisibilities,
320348
generics: GenericParamsStorage,
321349
type_refs: TypeRefStorage,
350+
trait_refs: TraitRefStorage,
322351

323352
inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
324353
}
@@ -556,6 +585,14 @@ impl Index<Idx<TypeRef>> for ItemTree {
556585
}
557586
}
558587

588+
impl Index<Idx<TraitRef>> for ItemTree {
589+
type Output = TraitRef;
590+
591+
fn index(&self, id: Idx<TraitRef>) -> &Self::Output {
592+
self.data().trait_refs.lookup(id)
593+
}
594+
}
595+
559596
impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
560597
type Output = N;
561598
fn index(&self, id: FileItemTreeId<N>) -> &N {
@@ -692,7 +729,7 @@ pub struct Trait {
692729
#[derive(Debug, Clone, Eq, PartialEq)]
693730
pub struct Impl {
694731
pub generic_params: GenericParamsId,
695-
pub target_trait: Option<Idx<TypeRef>>,
732+
pub target_trait: Option<Idx<TraitRef>>,
696733
pub target_type: Idx<TypeRef>,
697734
pub is_negative: bool,
698735
pub items: Box<[AssocItem]>,

crates/hir_def/src/item_tree/lower.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use syntax::{
1111

1212
use crate::{
1313
generics::{GenericParams, TypeParamData, TypeParamProvenance},
14-
type_ref::LifetimeRef,
14+
type_ref::{LifetimeRef, TraitRef},
1515
};
1616

1717
use super::*;
@@ -536,7 +536,7 @@ impl Ctx {
536536
fn lower_impl(&mut self, impl_def: &ast::Impl) -> Option<FileItemTreeId<Impl>> {
537537
let generic_params =
538538
self.lower_generic_params_and_inner_items(GenericsOwner::Impl, impl_def);
539-
let target_trait = impl_def.trait_().map(|tr| self.lower_type_ref(&tr));
539+
let target_trait = impl_def.trait_().map(|tr| self.lower_trait_ref(&tr));
540540
let target_type = self.lower_type_ref(&impl_def.self_ty()?);
541541
let is_negative = impl_def.excl_token().is_some();
542542

@@ -740,10 +740,16 @@ impl Ctx {
740740
self.data().vis.alloc(vis)
741741
}
742742

743+
fn lower_trait_ref(&mut self, trait_ref: &ast::Type) -> Idx<TraitRef> {
744+
let trait_ref = TraitRef::from_ast(&self.body_ctx, trait_ref.clone());
745+
self.data().trait_refs.intern(trait_ref)
746+
}
747+
743748
fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Idx<TypeRef> {
744749
let tyref = TypeRef::from_ast(&self.body_ctx, type_ref.clone());
745750
self.data().type_refs.intern(tyref)
746751
}
752+
747753
fn lower_type_ref_opt(&mut self, type_ref: Option<ast::Type>) -> Idx<TypeRef> {
748754
match type_ref.map(|ty| self.lower_type_ref(&ty)) {
749755
Some(it) => it,

crates/hir_def/src/type_ref.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,25 @@ impl Rawness {
5151
}
5252
}
5353

54+
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
55+
pub enum TraitRef {
56+
Path(Path),
57+
Error,
58+
}
59+
60+
impl TraitRef {
61+
/// Converts an `ast::PathType` to a `hir::TraitRef`.
62+
pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::Type) -> Self {
63+
// FIXME: Use `Path::from_src`
64+
match node {
65+
ast::Type::PathType(path) => path
66+
.path()
67+
.and_then(|it| ctx.lower_path(it))
68+
.map_or(TraitRef::Error, TraitRef::Path),
69+
_ => TraitRef::Error,
70+
}
71+
}
72+
}
5473
/// Compare ty::Ty
5574
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
5675
pub enum TypeRef {

crates/hir_ty/src/lower.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use hir_def::{
1515
generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
1616
path::{GenericArg, Path, PathSegment, PathSegments},
1717
resolver::{HasResolver, Resolver, TypeNs},
18-
type_ref::{TypeBound, TypeRef},
18+
type_ref::{TraitRef as HirTraitRef, TypeBound, TypeRef},
1919
AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId,
2020
GenericDefId, HasModule, ImplId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
2121
TypeAliasId, TypeParamId, UnionId, VariantId,
@@ -667,14 +667,13 @@ impl<'a> TyLoweringContext<'a> {
667667

668668
fn lower_trait_ref(
669669
&self,
670-
type_ref: &TypeRef,
670+
trait_ref: &HirTraitRef,
671671
explicit_self_ty: Option<Ty>,
672672
) -> Option<TraitRef> {
673-
let path = match type_ref {
674-
TypeRef::Path(path) => path,
675-
_ => return None,
676-
};
677-
self.lower_trait_ref_from_path(path, explicit_self_ty)
673+
match trait_ref {
674+
HirTraitRef::Path(path) => self.lower_trait_ref_from_path(path, explicit_self_ty),
675+
HirTraitRef::Error => None,
676+
}
678677
}
679678

680679
fn trait_ref_substs_from_path(

0 commit comments

Comments
 (0)