From 8c3e372835243c922b0eff7ca23f79f227991e88 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Nov 2019 13:10:26 +0300 Subject: Remove Resolver from autoderef Resolver holds onto too much context, including local scopes. Let's try to pass in only what is necessary -- the trait environment. --- crates/ra_hir/src/ty/infer/coerce.rs | 13 ++++++++---- crates/ra_hir/src/ty/infer/expr.rs | 40 +++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 18 deletions(-) (limited to 'crates/ra_hir/src/ty/infer') diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 54765da35..4b53bba73 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -14,7 +14,7 @@ use crate::{ Adt, Mutability, }; -use super::{InferTy, InferenceContext, TypeVarValue}; +use super::{InEnvironment, InferTy, InferenceContext, TypeVarValue}; impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// Unify two types, but may coerce the first one to the second one @@ -320,9 +320,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let canonicalized = self.canonicalizer().canonicalize_ty(from_ty.clone()); let to_ty = self.resolve_ty_shallow(&to_ty); // FIXME: Auto DerefMut - for derefed_ty in - autoderef::autoderef(self.db, &self.resolver.clone(), canonicalized.value.clone()) - { + for derefed_ty in autoderef::autoderef( + self.db, + self.resolver.krate(), + InEnvironment { + value: canonicalized.value.clone(), + environment: self.trait_env.clone(), + }, + ) { let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { // Stop when constructor matches. diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 663ff9435..194e55819 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -15,9 +15,9 @@ use crate::{ db::HirDatabase, expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, ty::{ - autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, - Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, - Uncertain, + autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, + Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, + TypeCtor, TypeWalk, Uncertain, }, Adt, Name, }; @@ -245,8 +245,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); let ty = autoderef::autoderef( self.db, - &self.resolver.clone(), - canonicalized.value.clone(), + self.resolver.krate(), + InEnvironment { + value: canonicalized.value.clone(), + environment: self.trait_env.clone(), + }, ) .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { Ty::Apply(a_ty) => match a_ty.ctor { @@ -337,16 +340,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { Expr::UnaryOp { expr, op } => { let inner_ty = self.infer_expr(*expr, &Expectation::none()); match op { - UnaryOp::Deref => { - let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); - if let Some(derefed_ty) = - autoderef::deref(self.db, &self.resolver, &canonicalized.value) - { - canonicalized.decanonicalize_ty(derefed_ty.value) - } else { - Ty::Unknown + UnaryOp::Deref => match self.resolver.krate() { + Some(krate) => { + let canonicalized = self.canonicalizer().canonicalize_ty(inner_ty); + match autoderef::deref( + self.db, + krate, + InEnvironment { + value: &canonicalized.value, + environment: self.trait_env.clone(), + }, + ) { + Some(derefed_ty) => { + canonicalized.decanonicalize_ty(derefed_ty.value) + } + None => Ty::Unknown, + } } - } + None => Ty::Unknown, + }, UnaryOp::Neg => { match &inner_ty { Ty::Apply(a_ty) => match a_ty.ctor { -- cgit v1.2.3