aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_ty/src/autoderef.rs38
1 files changed, 15 insertions, 23 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index c859f9491..70c56cc45 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -13,11 +13,9 @@ use log::{info, warn};
13 13
14use crate::{ 14use crate::{
15 db::HirDatabase, 15 db::HirDatabase,
16 to_assoc_type_id, to_chalk_trait_id,
17 traits::{InEnvironment, Solution}, 16 traits::{InEnvironment, Solution},
18 utils::generics, 17 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, Ty,
19 AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, 18 TyBuilder, TyKind,
20 ProjectionTy, Substitution, TraitRef, Ty, TyKind,
21}; 19};
22 20
23const AUTODEREF_RECURSION_LIMIT: usize = 10; 21const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -57,21 +55,20 @@ fn deref_by_trait(
57 }; 55 };
58 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?; 56 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
59 57
60 let generic_params = generics(db.upcast(), target.into()); 58 let projection = {
61 if generic_params.len() != 1 { 59 let b = TyBuilder::assoc_type_projection(db, target);
62 // the Target type + Deref trait should only have one generic parameter, 60 if b.remaining() != 1 {
63 // namely Deref's Self type 61 // the Target type + Deref trait should only have one generic parameter,
64 return None; 62 // namely Deref's Self type
65 } 63 return None;
64 }
65 b.push(ty.goal.value.clone()).build()
66 };
66 67
67 // FIXME make the Canonical / bound var handling nicer 68 // FIXME make the Canonical / bound var handling nicer
68 69
69 let parameters =
70 Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
71
72 // Check that the type implements Deref at all 70 // Check that the type implements Deref at all
73 let trait_ref = 71 let trait_ref = projection.trait_ref(db);
74 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
75 let implements_goal = Canonical { 72 let implements_goal = Canonical {
76 binders: ty.goal.binders.clone(), 73 binders: ty.goal.binders.clone(),
77 value: InEnvironment { 74 value: InEnvironment {
@@ -84,11 +81,8 @@ fn deref_by_trait(
84 } 81 }
85 82
86 // Now do the assoc type projection 83 // Now do the assoc type projection
87 let projection = AliasEq { 84 let alias_eq = AliasEq {
88 alias: AliasTy::Projection(ProjectionTy { 85 alias: AliasTy::Projection(projection),
89 associated_ty_id: to_assoc_type_id(target),
90 substitution: parameters,
91 }),
92 ty: TyKind::BoundVar(BoundVar::new( 86 ty: TyKind::BoundVar(BoundVar::new(
93 DebruijnIndex::INNERMOST, 87 DebruijnIndex::INNERMOST,
94 ty.goal.binders.len(&Interner), 88 ty.goal.binders.len(&Interner),
@@ -96,9 +90,7 @@ fn deref_by_trait(
96 .intern(&Interner), 90 .intern(&Interner),
97 }; 91 };
98 92
99 let obligation = projection.cast(&Interner); 93 let in_env = InEnvironment { goal: alias_eq.cast(&Interner), environment: ty.environment };
100
101 let in_env = InEnvironment { goal: obligation, environment: ty.environment };
102 94
103 let canonical = Canonical { 95 let canonical = Canonical {
104 value: in_env, 96 value: in_env,