Skip to content

Commit 36dca8d

Browse files
bors[bot]matklad
andauthored
Merge #2410
2410: Introduce hir_ty r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents 280946e + 4e17718 commit 36dca8d

File tree

12 files changed

+329
-245
lines changed

12 files changed

+329
-245
lines changed

Cargo.lock

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_hir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ mbe = { path = "../ra_mbe", package = "ra_mbe" }
2323
tt = { path = "../ra_tt", package = "ra_tt" }
2424
hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
2525
hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
26+
hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
2627
test_utils = { path = "../test_utils" }
2728
ra_prof = { path = "../ra_prof" }
2829

crates/ra_hir/src/code_model.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,15 @@ pub struct ImplBlock {
997997
}
998998

999999
impl ImplBlock {
1000+
pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> {
1001+
let impls = db.impls_in_crate(krate.crate_id);
1002+
impls.all_impls().map(Self::from).collect()
1003+
}
1004+
pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> {
1005+
let impls = db.impls_in_crate(krate.crate_id);
1006+
impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect()
1007+
}
1008+
10001009
pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
10011010
db.impl_data(self.id).target_trait.clone()
10021011
}

crates/ra_hir/src/db.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::sync::Arc;
44

55
use ra_arena::map::ArenaMap;
6-
use ra_db::salsa;
6+
use ra_db::{salsa, CrateId};
77

88
use crate::{
99
ty::{
@@ -60,7 +60,7 @@ pub trait HirDatabase: DefDatabase {
6060
fn generic_defaults(&self, def: GenericDefId) -> Substs;
6161

6262
#[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
63-
fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
63+
fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>;
6464

6565
#[salsa::invoke(crate::ty::traits::impls_for_trait_query)]
6666
fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>;

crates/ra_hir/src/ty/lower.rs

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::iter;
99
use std::sync::Arc;
1010

1111
use hir_def::{
12-
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType},
12+
builtin_type::BuiltinType,
1313
generics::WherePredicate,
1414
path::{GenericArg, PathSegment},
1515
resolver::{HasResolver, Resolver, TypeNs},
@@ -27,7 +27,7 @@ use super::{
2727
use crate::{
2828
db::HirDatabase,
2929
ty::{
30-
primitive::{FloatTy, IntTy, Uncertain},
30+
primitive::{FloatTy, IntTy},
3131
Adt,
3232
},
3333
util::make_mut_slice,
@@ -679,36 +679,6 @@ fn type_for_builtin(def: BuiltinType) -> Ty {
679679
})
680680
}
681681

682-
impl From<BuiltinInt> for IntTy {
683-
fn from(t: BuiltinInt) -> Self {
684-
IntTy { signedness: t.signedness, bitness: t.bitness }
685-
}
686-
}
687-
688-
impl From<BuiltinFloat> for FloatTy {
689-
fn from(t: BuiltinFloat) -> Self {
690-
FloatTy { bitness: t.bitness }
691-
}
692-
}
693-
694-
impl From<Option<BuiltinInt>> for Uncertain<IntTy> {
695-
fn from(t: Option<BuiltinInt>) -> Self {
696-
match t {
697-
None => Uncertain::Unknown,
698-
Some(t) => Uncertain::Known(t.into()),
699-
}
700-
}
701-
}
702-
703-
impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
704-
fn from(t: Option<BuiltinFloat>) -> Self {
705-
match t {
706-
None => Uncertain::Unknown,
707-
Some(t) => Uncertain::Known(t.into()),
708-
}
709-
}
710-
}
711-
712682
fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig {
713683
let struct_data = db.struct_data(def.into());
714684
let fields = struct_data.variant_data.fields();

crates/ra_hir/src/ty/method_resolution.rs

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@
55
use std::sync::Arc;
66

77
use arrayvec::ArrayVec;
8-
use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule};
8+
use hir_def::{
9+
lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef,
10+
HasModule, ImplId, TraitId,
11+
};
12+
use ra_db::CrateId;
13+
use ra_prof::profile;
914
use rustc_hash::FxHashMap;
1015

1116
use crate::{
1217
db::HirDatabase,
1318
ty::primitive::{FloatBitness, Uncertain},
1419
ty::{Ty, TypeCtor},
15-
AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait,
20+
AssocItem, Crate, Function, Mutability, Name, Trait,
1621
};
1722

1823
use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
@@ -37,54 +42,58 @@ impl TyFingerprint {
3742

3843
#[derive(Debug, PartialEq, Eq)]
3944
pub struct CrateImplBlocks {
40-
impls: FxHashMap<TyFingerprint, Vec<ImplBlock>>,
41-
impls_by_trait: FxHashMap<Trait, Vec<ImplBlock>>,
45+
impls: FxHashMap<TyFingerprint, Vec<ImplId>>,
46+
impls_by_trait: FxHashMap<TraitId, Vec<ImplId>>,
4247
}
4348

4449
impl CrateImplBlocks {
4550
pub(crate) fn impls_in_crate_query(
4651
db: &impl HirDatabase,
47-
krate: Crate,
52+
krate: CrateId,
4853
) -> Arc<CrateImplBlocks> {
49-
let mut crate_impl_blocks =
54+
let _p = profile("impls_in_crate_query");
55+
let mut res =
5056
CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() };
51-
if let Some(module) = krate.root_module(db) {
52-
crate_impl_blocks.collect_recursive(db, module);
57+
58+
let crate_def_map = db.crate_def_map(krate);
59+
for (_module_id, module_data) in crate_def_map.modules.iter() {
60+
for &impl_id in module_data.impls.iter() {
61+
let impl_data = db.impl_data(impl_id);
62+
let resolver = impl_id.resolver(db);
63+
64+
let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) };
65+
66+
match &impl_data.target_trait {
67+
Some(trait_ref) => {
68+
if let Some(tr) =
69+
TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty))
70+
{
71+
res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id);
72+
}
73+
}
74+
None => {
75+
if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
76+
res.impls.entry(target_ty_fp).or_default().push(impl_id);
77+
}
78+
}
79+
}
80+
}
5381
}
54-
Arc::new(crate_impl_blocks)
82+
83+
Arc::new(res)
5584
}
56-
pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + '_ {
85+
pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplId> + '_ {
5786
let fingerprint = TyFingerprint::for_impl(ty);
5887
fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied()
5988
}
6089

61-
pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplBlock> + '_ {
62-
self.impls_by_trait.get(&tr).into_iter().flatten().copied()
90+
pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplId> + '_ {
91+
self.impls_by_trait.get(&tr.id).into_iter().flatten().copied()
6392
}
6493

65-
pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a {
94+
pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a {
6695
self.impls.values().chain(self.impls_by_trait.values()).flatten().copied()
6796
}
68-
69-
fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) {
70-
for impl_block in module.impl_blocks(db) {
71-
let target_ty = impl_block.target_ty(db);
72-
73-
if impl_block.target_trait(db).is_some() {
74-
if let Some(tr) = impl_block.target_trait_ref(db) {
75-
self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block);
76-
}
77-
} else {
78-
if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
79-
self.impls.entry(target_ty_fp).or_default().push(impl_block);
80-
}
81-
}
82-
}
83-
84-
for child in module.children(db) {
85-
self.collect_recursive(db, child);
86-
}
87-
}
8897
}
8998

9099
fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> {
@@ -279,14 +288,14 @@ fn iterate_inherent_methods<T>(
279288
mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
280289
) -> Option<T> {
281290
for krate in def_crates(db, krate, &ty.value)? {
282-
let impls = db.impls_in_crate(krate);
291+
let impls = db.impls_in_crate(krate.crate_id);
283292

284293
for impl_block in impls.lookup_impl_blocks(&ty.value) {
285-
for item in impl_block.items(db) {
294+
for &item in db.impl_data(impl_block).items.iter() {
286295
if !is_valid_candidate(db, name, mode, item) {
287296
continue;
288297
}
289-
if let Some(result) = callback(&ty.value, item) {
298+
if let Some(result) = callback(&ty.value, item.into()) {
290299
return Some(result);
291300
}
292301
}
@@ -299,17 +308,17 @@ fn is_valid_candidate(
299308
db: &impl HirDatabase,
300309
name: Option<&Name>,
301310
mode: LookupMode,
302-
item: AssocItem,
311+
item: AssocItemId,
303312
) -> bool {
304313
match item {
305-
AssocItem::Function(m) => {
306-
let data = db.function_data(m.id);
307-
name.map_or(true, |name| data.name == *name)
314+
AssocItemId::FunctionId(m) => {
315+
let data = db.function_data(m);
316+
name.map_or(true, |name| &data.name == name)
308317
&& (data.has_self_param || mode == LookupMode::Path)
309318
}
310-
AssocItem::Const(c) => {
311-
name.map_or(true, |name| Some(name) == c.name(db).as_ref())
312-
&& (mode == LookupMode::Path)
319+
AssocItemId::ConstId(c) => {
320+
let data = db.const_data(c);
321+
name.map_or(true, |name| data.name.as_ref() == Some(name)) && (mode == LookupMode::Path)
313322
}
314323
_ => false,
315324
}
@@ -344,11 +353,11 @@ impl Ty {
344353
mut callback: impl FnMut(AssocItem) -> Option<T>,
345354
) -> Option<T> {
346355
for krate in def_crates(db, krate, &self)? {
347-
let impls = db.impls_in_crate(krate);
356+
let impls = db.impls_in_crate(krate.crate_id);
348357

349358
for impl_block in impls.lookup_impl_blocks(&self) {
350-
for item in impl_block.items(db) {
351-
if let Some(result) = callback(item) {
359+
for &item in db.impl_data(impl_block).items.iter() {
360+
if let Some(result) = callback(item.into()) {
352361
return Some(result);
353362
}
354363
}

0 commit comments

Comments
 (0)