Skip to content

Commit 54da0bf

Browse files
committed
Record method resolution for call expressions
1 parent 9814d79 commit 54da0bf

File tree

10 files changed

+119
-77
lines changed

10 files changed

+119
-77
lines changed

crates/hir-expand/src/name.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ pub mod known {
347347
recursion_limit,
348348
feature,
349349
// known methods of lang items
350+
call_once,
350351
eq,
351352
ne,
352353
ge,

crates/hir-ty/src/builder.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl<D> TyBuilder<D> {
6363
}
6464

6565
fn build_internal(self) -> (D, Substitution) {
66-
assert_eq!(self.vec.len(), self.param_kinds.len());
66+
assert_eq!(self.vec.len(), self.param_kinds.len(), "{:?}", &self.param_kinds);
6767
for (a, e) in self.vec.iter().zip(self.param_kinds.iter()) {
6868
self.assert_match_kind(a, e);
6969
}
@@ -282,6 +282,21 @@ impl TyBuilder<Tuple> {
282282
let (Tuple(size), subst) = self.build_internal();
283283
TyKind::Tuple(size, subst).intern(Interner)
284284
}
285+
286+
pub fn tuple_with<I>(elements: I) -> Ty
287+
where
288+
I: IntoIterator<Item = Ty>,
289+
<I as IntoIterator>::IntoIter: ExactSizeIterator,
290+
{
291+
let elements = elements.into_iter();
292+
let len = elements.len();
293+
let mut b =
294+
TyBuilder::new(Tuple(len), iter::repeat(ParamKind::Type).take(len).collect(), None);
295+
for e in elements {
296+
b = b.push(e);
297+
}
298+
b.build()
299+
}
285300
}
286301

287302
impl TyBuilder<TraitId> {

crates/hir-ty/src/infer/expr.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,18 @@ impl<'a> InferenceContext<'a> {
331331
derefed_callee.callable_sig(self.db).map_or(false, |sig| sig.is_varargs)
332332
|| res.is_none();
333333
let (param_tys, ret_ty) = match res {
334-
Some(res) => {
334+
Some((func, params, ret_ty)) => {
335335
let adjustments = auto_deref_adjust_steps(&derefs);
336336
// FIXME: Handle call adjustments for Fn/FnMut
337337
self.write_expr_adj(*callee, adjustments);
338-
res
338+
if let Some((trait_, func)) = func {
339+
let subst = TyBuilder::subst_for_def(self.db, trait_, None)
340+
.push(callee_ty.clone())
341+
.push(TyBuilder::tuple_with(params.iter().cloned()))
342+
.build();
343+
self.write_method_resolution(tgt_expr, func, subst.clone());
344+
}
345+
(params, ret_ty)
339346
}
340347
None => (Vec::new(), self.err_ty()), // FIXME diagnostic
341348
};
@@ -586,6 +593,7 @@ impl<'a> InferenceContext<'a> {
586593
self.resolve_associated_type(inner_ty, self.resolve_future_future_output())
587594
}
588595
Expr::Try { expr } => {
596+
// FIXME: Note down method resolution her
589597
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
590598
self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok())
591599
}
@@ -626,6 +634,7 @@ impl<'a> InferenceContext<'a> {
626634
Expr::UnaryOp { expr, op } => {
627635
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
628636
let inner_ty = self.resolve_ty_shallow(&inner_ty);
637+
// FIXME: Note down method resolution her
629638
match op {
630639
UnaryOp::Deref => {
631640
autoderef::deref(&mut self.table, inner_ty).unwrap_or_else(|| self.err_ty())
@@ -732,6 +741,7 @@ impl<'a> InferenceContext<'a> {
732741
}
733742
}
734743
Expr::Index { base, index } => {
744+
// FIXME: note down method resolution for the `index`/`index_mut` function
735745
let base_ty = self.infer_expr_inner(*base, &Expectation::none());
736746
let index_ty = self.infer_expr(*index, &Expectation::none());
737747

crates/hir-ty/src/infer/unify.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use chalk_ir::{
88
};
99
use chalk_solve::infer::ParameterEnaVariableExt;
1010
use ena::unify::UnifyKey;
11+
use hir_def::{FunctionId, TraitId};
1112
use hir_expand::name;
1213
use stdx::never;
1314

@@ -626,18 +627,26 @@ impl<'a> InferenceTable<'a> {
626627
}
627628
}
628629

629-
pub(crate) fn callable_sig(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> {
630+
pub(crate) fn callable_sig(
631+
&mut self,
632+
ty: &Ty,
633+
num_args: usize,
634+
) -> Option<(Option<(TraitId, FunctionId)>, Vec<Ty>, Ty)> {
630635
match ty.callable_sig(self.db) {
631-
Some(sig) => Some((sig.params().to_vec(), sig.ret().clone())),
636+
Some(sig) => Some((None, sig.params().to_vec(), sig.ret().clone())),
632637
None => self.callable_sig_from_fn_trait(ty, num_args),
633638
}
634639
}
635640

636-
fn callable_sig_from_fn_trait(&mut self, ty: &Ty, num_args: usize) -> Option<(Vec<Ty>, Ty)> {
641+
fn callable_sig_from_fn_trait(
642+
&mut self,
643+
ty: &Ty,
644+
num_args: usize,
645+
) -> Option<(Option<(TraitId, FunctionId)>, Vec<Ty>, Ty)> {
637646
let krate = self.trait_env.krate;
638647
let fn_once_trait = FnTrait::FnOnce.get_id(self.db, krate)?;
639-
let output_assoc_type =
640-
self.db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
648+
let trait_data = self.db.trait_data(fn_once_trait);
649+
let output_assoc_type = trait_data.associated_type_by_name(&name![Output])?;
641650

642651
let mut arg_tys = vec![];
643652
let arg_ty = TyBuilder::tuple(num_args)
@@ -675,7 +684,11 @@ impl<'a> InferenceTable<'a> {
675684
if self.db.trait_solve(krate, canonical.value.cast(Interner)).is_some() {
676685
self.register_obligation(obligation.goal);
677686
let return_ty = self.normalize_projection_ty(projection);
678-
Some((arg_tys, return_ty))
687+
Some((
688+
Some(fn_once_trait).zip(trait_data.method_by_name(&name!(call_once))),
689+
arg_tys,
690+
return_ty,
691+
))
679692
} else {
680693
None
681694
}

crates/hir-ty/src/tests/method_resolution.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -986,14 +986,13 @@ fn main() {
986986
}
987987

988988
#[test]
989-
fn method_resolution_encountering_fn_type() {
989+
fn explicit_fn_once_call_fn_item() {
990990
check_types(
991991
r#"
992-
//- /main.rs
992+
//- minicore: fn
993993
fn foo() {}
994-
trait FnOnce { fn call(self); }
995-
fn test() { foo.call(); }
996-
//^^^^^^^^^^ {unknown}
994+
fn test() { foo.call_once(); }
995+
//^^^^^^^^^^^^^^^ ()
997996
"#,
998997
);
999998
}

crates/hir-ty/src/tests/traits.rs

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,25 +1757,19 @@ fn test() {
17571757
fn fn_trait() {
17581758
check_infer_with_mismatches(
17591759
r#"
1760-
trait FnOnce<Args> {
1761-
type Output;
1762-
1763-
fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output;
1764-
}
1760+
//- minicore: fn
17651761
17661762
fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
17671763
f.call_once((1, 2));
17681764
}"#,
17691765
expect![[r#"
1770-
56..60 'self': Self
1771-
62..66 'args': Args
1772-
149..150 'f': F
1773-
155..183 '{ ...2)); }': ()
1774-
161..162 'f': F
1775-
161..180 'f.call...1, 2))': u128
1776-
173..179 '(1, 2)': (u32, u64)
1777-
174..175 '1': u32
1778-
177..178 '2': u64
1766+
38..39 'f': F
1767+
44..72 '{ ...2)); }': ()
1768+
50..51 'f': F
1769+
50..69 'f.call...1, 2))': u128
1770+
62..68 '(1, 2)': (u32, u64)
1771+
63..64 '1': u32
1772+
66..67 '2': u64
17791773
"#]],
17801774
);
17811775
}
@@ -1784,12 +1778,7 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
17841778
fn fn_ptr_and_item() {
17851779
check_infer_with_mismatches(
17861780
r#"
1787-
#[lang="fn_once"]
1788-
trait FnOnce<Args> {
1789-
type Output;
1790-
1791-
fn call_once(self, args: Args) -> Self::Output;
1792-
}
1781+
//- minicore: fn
17931782
17941783
trait Foo<T> {
17951784
fn foo(&self) -> T;
@@ -1815,27 +1804,25 @@ fn test() {
18151804
opt.map(f);
18161805
}"#,
18171806
expect![[r#"
1818-
74..78 'self': Self
1819-
80..84 'args': Args
1820-
139..143 'self': &Self
1821-
243..247 'self': &Bar<F>
1822-
260..271 '{ loop {} }': (A1, R)
1823-
262..269 'loop {}': !
1824-
267..269 '{}': ()
1825-
355..359 'self': Opt<T>
1826-
361..362 'f': F
1827-
377..388 '{ loop {} }': Opt<U>
1828-
379..386 'loop {}': !
1829-
384..386 '{}': ()
1830-
402..518 '{ ...(f); }': ()
1831-
412..415 'bar': Bar<fn(u8) -> u32>
1832-
441..444 'bar': Bar<fn(u8) -> u32>
1833-
441..450 'bar.foo()': (u8, u32)
1834-
461..464 'opt': Opt<u8>
1835-
483..484 'f': fn(u8) -> u32
1836-
505..508 'opt': Opt<u8>
1837-
505..515 'opt.map(f)': Opt<u32>
1838-
513..514 'f': fn(u8) -> u32
1807+
28..32 'self': &Self
1808+
132..136 'self': &Bar<F>
1809+
149..160 '{ loop {} }': (A1, R)
1810+
151..158 'loop {}': !
1811+
156..158 '{}': ()
1812+
244..248 'self': Opt<T>
1813+
250..251 'f': F
1814+
266..277 '{ loop {} }': Opt<U>
1815+
268..275 'loop {}': !
1816+
273..275 '{}': ()
1817+
291..407 '{ ...(f); }': ()
1818+
301..304 'bar': Bar<fn(u8) -> u32>
1819+
330..333 'bar': Bar<fn(u8) -> u32>
1820+
330..339 'bar.foo()': (u8, u32)
1821+
350..353 'opt': Opt<u8>
1822+
372..373 'f': fn(u8) -> u32
1823+
394..397 'opt': Opt<u8>
1824+
394..404 'opt.map(f)': Opt<u32>
1825+
402..403 'f': fn(u8) -> u32
18391826
"#]],
18401827
);
18411828
}

crates/hir/src/lib.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2411,7 +2411,7 @@ impl Local {
24112411
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
24122412
pub struct DeriveHelper {
24132413
pub(crate) derive: MacroId,
2414-
pub(crate) idx: usize,
2414+
pub(crate) idx: u32,
24152415
}
24162416

24172417
impl DeriveHelper {
@@ -2421,15 +2421,18 @@ impl DeriveHelper {
24212421

24222422
pub fn name(&self, db: &dyn HirDatabase) -> Name {
24232423
match self.derive {
2424-
MacroId::Macro2Id(it) => {
2425-
db.macro2_data(it).helpers.as_deref().and_then(|it| it.get(self.idx)).cloned()
2426-
}
2424+
MacroId::Macro2Id(it) => db
2425+
.macro2_data(it)
2426+
.helpers
2427+
.as_deref()
2428+
.and_then(|it| it.get(self.idx as usize))
2429+
.cloned(),
24272430
MacroId::MacroRulesId(_) => None,
24282431
MacroId::ProcMacroId(proc_macro) => db
24292432
.proc_macro_data(proc_macro)
24302433
.helpers
24312434
.as_deref()
2432-
.and_then(|it| it.get(self.idx))
2435+
.and_then(|it| it.get(self.idx as usize))
24332436
.cloned(),
24342437
}
24352438
.unwrap_or_else(|| Name::missing())
@@ -2440,7 +2443,7 @@ impl DeriveHelper {
24402443
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
24412444
pub struct BuiltinAttr {
24422445
krate: Option<CrateId>,
2443-
idx: usize,
2446+
idx: u32,
24442447
}
24452448

24462449
impl BuiltinAttr {
@@ -2449,37 +2452,38 @@ impl BuiltinAttr {
24492452
if let builtin @ Some(_) = Self::builtin(name) {
24502453
return builtin;
24512454
}
2452-
let idx = db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)?;
2455+
let idx =
2456+
db.crate_def_map(krate.id).registered_attrs().iter().position(|it| it == name)? as u32;
24532457
Some(BuiltinAttr { krate: Some(krate.id), idx })
24542458
}
24552459

24562460
fn builtin(name: &str) -> Option<Self> {
24572461
hir_def::builtin_attr::INERT_ATTRIBUTES
24582462
.iter()
24592463
.position(|tool| tool.name == name)
2460-
.map(|idx| BuiltinAttr { krate: None, idx })
2464+
.map(|idx| BuiltinAttr { krate: None, idx: idx as u32 })
24612465
}
24622466

24632467
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
24642468
// FIXME: Return a `Name` here
24652469
match self.krate {
2466-
Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx].clone(),
2467-
None => SmolStr::new(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].name),
2470+
Some(krate) => db.crate_def_map(krate).registered_attrs()[self.idx as usize].clone(),
2471+
None => SmolStr::new(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx as usize].name),
24682472
}
24692473
}
24702474

24712475
pub fn template(&self, _: &dyn HirDatabase) -> Option<AttributeTemplate> {
24722476
match self.krate {
24732477
Some(_) => None,
2474-
None => Some(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx].template),
2478+
None => Some(hir_def::builtin_attr::INERT_ATTRIBUTES[self.idx as usize].template),
24752479
}
24762480
}
24772481
}
24782482

24792483
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
24802484
pub struct ToolModule {
24812485
krate: Option<CrateId>,
2482-
idx: usize,
2486+
idx: u32,
24832487
}
24842488

24852489
impl ToolModule {
@@ -2488,22 +2492,23 @@ impl ToolModule {
24882492
if let builtin @ Some(_) = Self::builtin(name) {
24892493
return builtin;
24902494
}
2491-
let idx = db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)?;
2495+
let idx =
2496+
db.crate_def_map(krate.id).registered_tools().iter().position(|it| it == name)? as u32;
24922497
Some(ToolModule { krate: Some(krate.id), idx })
24932498
}
24942499

24952500
fn builtin(name: &str) -> Option<Self> {
24962501
hir_def::builtin_attr::TOOL_MODULES
24972502
.iter()
24982503
.position(|&tool| tool == name)
2499-
.map(|idx| ToolModule { krate: None, idx })
2504+
.map(|idx| ToolModule { krate: None, idx: idx as u32 })
25002505
}
25012506

25022507
pub fn name(&self, db: &dyn HirDatabase) -> SmolStr {
25032508
// FIXME: Return a `Name` here
25042509
match self.krate {
2505-
Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx].clone(),
2506-
None => SmolStr::new(hir_def::builtin_attr::TOOL_MODULES[self.idx]),
2510+
Some(krate) => db.crate_def_map(krate).registered_tools()[self.idx as usize].clone(),
2511+
None => SmolStr::new(hir_def::builtin_attr::TOOL_MODULES[self.idx as usize]),
25072512
}
25082513
}
25092514
}
@@ -2831,7 +2836,7 @@ impl Impl {
28312836
}
28322837
}
28332838

2834-
#[derive(Clone, PartialEq, Eq, Debug)]
2839+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
28352840
pub struct TraitRef {
28362841
env: Arc<TraitEnvironment>,
28372842
trait_ref: hir_ty::TraitRef,

crates/hir/src/source_analyzer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ impl SourceAnalyzer {
628628
{
629629
return Some(PathResolution::DeriveHelper(DeriveHelper {
630630
derive: *macro_id,
631-
idx,
631+
idx: idx as u32,
632632
}));
633633
}
634634
}

crates/ide-db/src/defs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ pub enum Definition {
3434
TypeAlias(TypeAlias),
3535
BuiltinType(BuiltinType),
3636
SelfType(Impl),
37-
Local(Local),
3837
GenericParam(GenericParam),
38+
Local(Local),
3939
Label(Label),
4040
DeriveHelper(DeriveHelper),
4141
BuiltinAttr(BuiltinAttr),

0 commit comments

Comments
 (0)