diff options
Diffstat (limited to 'crates/hir_ty/src/traits.rs')
-rw-r--r-- | crates/hir_ty/src/traits.rs | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index 9936d0803..294cb531c 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::env::var; | 3 | use std::env::var; |
4 | 4 | ||
5 | use chalk_ir::cast::Cast; | 5 | use chalk_ir::GoalData; |
6 | use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; | 6 | use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; |
7 | 7 | ||
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
@@ -10,7 +10,7 @@ use hir_def::{lang_item::LangItemTarget, TraitId}; | |||
10 | use stdx::panic_context; | 10 | use stdx::panic_context; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment, | 13 | db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, |
14 | Interner, Solution, TraitRefExt, Ty, TyKind, WhereClause, | 14 | Interner, Solution, TraitRefExt, Ty, TyKind, WhereClause, |
15 | }; | 15 | }; |
16 | 16 | ||
@@ -38,6 +38,7 @@ fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> { | |||
38 | /// we assume that `T: Default`. | 38 | /// we assume that `T: Default`. |
39 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 39 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
40 | pub struct TraitEnvironment { | 40 | pub struct TraitEnvironment { |
41 | pub krate: CrateId, | ||
41 | // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord, | 42 | // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord, |
42 | // but for now it's too annoying... | 43 | // but for now it's too annoying... |
43 | pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>, | 44 | pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>, |
@@ -45,6 +46,14 @@ pub struct TraitEnvironment { | |||
45 | } | 46 | } |
46 | 47 | ||
47 | impl TraitEnvironment { | 48 | impl TraitEnvironment { |
49 | pub fn empty(krate: CrateId) -> Self { | ||
50 | TraitEnvironment { | ||
51 | krate, | ||
52 | traits_from_clauses: Vec::new(), | ||
53 | env: chalk_ir::Environment::new(&Interner), | ||
54 | } | ||
55 | } | ||
56 | |||
48 | pub(crate) fn traits_in_scope_from_clauses<'a>( | 57 | pub(crate) fn traits_in_scope_from_clauses<'a>( |
49 | &'a self, | 58 | &'a self, |
50 | ty: &'a Ty, | 59 | ty: &'a Ty, |
@@ -59,34 +68,25 @@ impl TraitEnvironment { | |||
59 | } | 68 | } |
60 | } | 69 | } |
61 | 70 | ||
62 | impl Default for TraitEnvironment { | ||
63 | fn default() -> Self { | ||
64 | TraitEnvironment { | ||
65 | traits_from_clauses: Vec::new(), | ||
66 | env: chalk_ir::Environment::new(&Interner), | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | |||
71 | /// Solve a trait goal using Chalk. | 71 | /// Solve a trait goal using Chalk. |
72 | pub(crate) fn trait_solve_query( | 72 | pub(crate) fn trait_solve_query( |
73 | db: &dyn HirDatabase, | 73 | db: &dyn HirDatabase, |
74 | krate: CrateId, | 74 | krate: CrateId, |
75 | goal: Canonical<InEnvironment<DomainGoal>>, | 75 | goal: Canonical<InEnvironment<Goal>>, |
76 | ) -> Option<Solution> { | 76 | ) -> Option<Solution> { |
77 | let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal { | 77 | let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal.data(&Interner) { |
78 | DomainGoal::Holds(WhereClause::Implemented(it)) => { | 78 | GoalData::DomainGoal(DomainGoal::Holds(WhereClause::Implemented(it))) => { |
79 | db.trait_data(it.hir_trait_id()).name.to_string() | 79 | db.trait_data(it.hir_trait_id()).name.to_string() |
80 | } | 80 | } |
81 | DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(), | 81 | GoalData::DomainGoal(DomainGoal::Holds(WhereClause::AliasEq(_))) => "alias_eq".to_string(), |
82 | _ => "??".to_string(), | 82 | _ => "??".to_string(), |
83 | }); | 83 | }); |
84 | log::info!("trait_solve_query({})", goal.value.goal.display(db)); | 84 | log::info!("trait_solve_query({:?})", goal.value.goal); |
85 | 85 | ||
86 | if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq { | 86 | if let GoalData::DomainGoal(DomainGoal::Holds(WhereClause::AliasEq(AliasEq { |
87 | alias: AliasTy::Projection(projection_ty), | 87 | alias: AliasTy::Projection(projection_ty), |
88 | .. | 88 | .. |
89 | })) = &goal.value.goal | 89 | }))) = &goal.value.goal.data(&Interner) |
90 | { | 90 | { |
91 | if let TyKind::BoundVar(_) = projection_ty.self_type_parameter(&Interner).kind(&Interner) { | 91 | if let TyKind::BoundVar(_) = projection_ty.self_type_parameter(&Interner).kind(&Interner) { |
92 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible | 92 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible |
@@ -94,11 +94,9 @@ pub(crate) fn trait_solve_query( | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | let canonical = goal.cast(&Interner); | ||
98 | |||
99 | // We currently don't deal with universes (I think / hope they're not yet | 97 | // We currently don't deal with universes (I think / hope they're not yet |
100 | // relevant for our use cases?) | 98 | // relevant for our use cases?) |
101 | let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; | 99 | let u_canonical = chalk_ir::UCanonical { canonical: goal, universes: 1 }; |
102 | solve(db, krate, &u_canonical) | 100 | solve(db, krate, &u_canonical) |
103 | } | 101 | } |
104 | 102 | ||