From 3e78a6e3e0dbe5ad2ae712ec5c94a3792745f26c Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 15 Jun 2019 18:20:59 +0200 Subject: Somewhat handle variables in the derefed type, and add another test --- crates/ra_hir/src/ty/autoderef.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir/src/ty/autoderef.rs') diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index bee756d80..11f489489 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -5,7 +5,7 @@ use std::iter::successors; -use log::info; +use log::{info, warn}; use crate::{HirDatabase, Name, Resolver}; use super::{traits::Solution, Ty, Canonical}; @@ -43,15 +43,13 @@ fn deref_by_trait( let target = deref_trait.associated_type_by_name(db, Name::target())?; // FIXME we should check that Deref has no type parameters, because we assume it below - // FIXME make the Canonical handling nicer - // TODO shift inference variables in ty let projection = super::traits::ProjectionPredicate { ty: Ty::Bound(0), projection_ty: super::ProjectionTy { associated_ty: target, - parameters: vec![ty.value.clone()].into(), + parameters: vec![ty.value.clone().shift_bound_vars(1)].into(), }, }; @@ -61,10 +59,26 @@ fn deref_by_trait( match &solution { Solution::Unique(vars) => { + // FIXME: vars may contain solutions for any inference variables + // that happened to be inside ty. To correctly handle these, we + // would have to pass the solution up to the inference context, but + // that requires a larger refactoring (especially if the deref + // happens during method resolution). So for the moment, we just + // check that we're not in the situation we're we would actually + // need to handle the values of the additional variables, i.e. + // they're just being 'passed through'. In the 'standard' case where + // we have `impl Deref for Foo { Target = T }`, that should be + // the case. + for i in 1..vars.0.num_vars { + if vars.0.value[i] != Ty::Bound((i - 1) as u32) { + warn!("complex solution for derefing {:?}: {:?}, ignoring", ty, solution); + return None; + } + } Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars }) } Solution::Ambig(_) => { - info!("Ambiguous solution for deref: {:?}", solution); + info!("Ambiguous solution for derefing {:?}: {:?}", ty, solution); None } } -- cgit v1.2.3