diff options
Diffstat (limited to 'crates/ra_hir/src/ty/traits.rs')
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 63 |
1 files changed, 28 insertions, 35 deletions
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 3e28852b6..d99843319 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -67,10 +67,33 @@ fn solve( | |||
67 | solution | 67 | solution |
68 | } | 68 | } |
69 | 69 | ||
70 | /// A set of clauses that we assume to be true. E.g. if we are inside this function: | ||
71 | /// ```rust | ||
72 | /// fn foo<T: Default>(t: T) {} | ||
73 | /// ``` | ||
74 | /// we assume that `T: Default`. | ||
75 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
76 | pub struct Environment { | ||
77 | pub predicates: Vec<GenericPredicate>, | ||
78 | } | ||
79 | |||
80 | /// Something (usually a goal), along with an environment. | ||
81 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
82 | pub struct InEnvironment<T> { | ||
83 | pub environment: Arc<Environment>, | ||
84 | pub value: T, | ||
85 | } | ||
86 | |||
87 | impl<T> InEnvironment<T> { | ||
88 | pub fn new(environment: Arc<Environment>, value: T) -> InEnvironment<T> { | ||
89 | InEnvironment { environment, value } | ||
90 | } | ||
91 | } | ||
92 | |||
70 | /// Something that needs to be proven (by Chalk) during type checking, e.g. that | 93 | /// Something that needs to be proven (by Chalk) during type checking, e.g. that |
71 | /// a certain type implements a certain trait. Proving the Obligation might | 94 | /// a certain type implements a certain trait. Proving the Obligation might |
72 | /// result in additional information about inference variables. | 95 | /// result in additional information about inference variables. |
73 | #[derive(Clone, Debug, PartialEq, Eq)] | 96 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
74 | pub enum Obligation { | 97 | pub enum Obligation { |
75 | /// Prove that a certain type implements a trait (the type is the `Self` type | 98 | /// Prove that a certain type implements a trait (the type is the `Self` type |
76 | /// parameter to the `TraitRef`). | 99 | /// parameter to the `TraitRef`). |
@@ -93,44 +116,14 @@ pub struct ProjectionPredicate { | |||
93 | pub ty: Ty, | 116 | pub ty: Ty, |
94 | } | 117 | } |
95 | 118 | ||
96 | /// Check using Chalk whether trait is implemented for given parameters including `Self` type. | 119 | /// Solve a trait goal using Chalk. |
97 | pub(crate) fn implements_query( | 120 | pub(crate) fn solve_query( |
98 | db: &impl HirDatabase, | 121 | db: &impl HirDatabase, |
99 | krate: Crate, | 122 | krate: Crate, |
100 | trait_ref: Canonical<TraitRef>, | 123 | trait_ref: Canonical<InEnvironment<Obligation>>, |
101 | ) -> Option<Solution> { | 124 | ) -> Option<Solution> { |
102 | let _p = profile("implements_query"); | 125 | let _p = profile("implements_query"); |
103 | let goal: chalk_ir::Goal = trait_ref.value.to_chalk(db).cast(); | 126 | let canonical = trait_ref.to_chalk(db).cast(); |
104 | debug!("goal: {:?}", goal); | ||
105 | let env = chalk_ir::Environment::new(); | ||
106 | let in_env = chalk_ir::InEnvironment::new(&env, goal); | ||
107 | let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT); | ||
108 | let canonical = | ||
109 | chalk_ir::Canonical { value: in_env, binders: vec![parameter; trait_ref.num_vars] }; | ||
110 | // We currently don't deal with universes (I think / hope they're not yet | ||
111 | // relevant for our use cases?) | ||
112 | let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; | ||
113 | let solution = solve(db, krate, &u_canonical); | ||
114 | solution.map(|solution| solution_from_chalk(db, solution)) | ||
115 | } | ||
116 | |||
117 | pub(crate) fn normalize_query( | ||
118 | db: &impl HirDatabase, | ||
119 | krate: Crate, | ||
120 | projection: Canonical<ProjectionPredicate>, | ||
121 | ) -> Option<Solution> { | ||
122 | let goal: chalk_ir::Goal = chalk_ir::Normalize { | ||
123 | projection: projection.value.projection_ty.to_chalk(db), | ||
124 | ty: projection.value.ty.to_chalk(db), | ||
125 | } | ||
126 | .cast(); | ||
127 | debug!("goal: {:?}", goal); | ||
128 | // FIXME unify with `implements` | ||
129 | let env = chalk_ir::Environment::new(); | ||
130 | let in_env = chalk_ir::InEnvironment::new(&env, goal); | ||
131 | let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT); | ||
132 | let canonical = | ||
133 | chalk_ir::Canonical { value: in_env, binders: vec![parameter; projection.num_vars] }; | ||
134 | // We currently don't deal with universes (I think / hope they're not yet | 127 | // We currently don't deal with universes (I think / hope they're not yet |
135 | // relevant for our use cases?) | 128 | // relevant for our use cases?) |
136 | let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; | 129 | let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; |