From 082ef52bcb15d779c6aff78d9860d328bf7df9b2 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Mon, 7 Jan 2019 13:44:54 +0100 Subject: Implement basic inherent method resolution --- crates/ra_hir/src/ty.rs | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir/src/ty.rs') diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 2d533eb6a..2dcba5283 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -17,6 +17,7 @@ mod autoderef; mod primitive; #[cfg(test)] mod tests; +pub(crate) mod method_resolution; use std::borrow::Cow; use std::ops::Index; @@ -891,14 +892,38 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } ret_ty } - Expr::MethodCall { receiver, args, .. } => { - let _receiver_ty = self.infer_expr(*receiver, &Expectation::none())?; - // TODO resolve method... - for (_i, arg) in args.iter().enumerate() { - // TODO unify / expect argument type - self.infer_expr(*arg, &Expectation::none())?; + Expr::MethodCall { + receiver, + args, + method_name, + } => { + let receiver_ty = self.infer_expr(*receiver, &Expectation::none())?; + let resolved = receiver_ty.clone().lookup_method(self.db, method_name)?; + let method_ty = match resolved { + Some(def_id) => self.db.type_for_def(def_id)?, + None => Ty::Unknown, + }; + let method_ty = self.insert_type_vars(method_ty); + let (expected_receiver_ty, arg_tys, ret_ty) = match &method_ty { + Ty::FnPtr(sig) => { + if sig.input.len() > 0 { + (&sig.input[0], &sig.input[1..], sig.output.clone()) + } else { + (&Ty::Unknown, &[][..], sig.output.clone()) + } + } + _ => (&Ty::Unknown, &[][..], Ty::Unknown), + }; + // TODO we would have to apply the autoderef/autoref steps here + // to get the correct receiver type to unify... + self.unify(expected_receiver_ty, &receiver_ty); + for (i, arg) in args.iter().enumerate() { + self.infer_expr( + *arg, + &Expectation::has_type(arg_tys.get(i).cloned().unwrap_or(Ty::Unknown)), + )?; } - Ty::Unknown + ret_ty } Expr::Match { expr, arms } => { let _ty = self.infer_expr(*expr, &Expectation::none())?; -- cgit v1.2.3