diff options
Diffstat (limited to 'crates/ra_hir/src/ty/traits.rs')
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index c0c132809..d11dab294 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -9,7 +9,7 @@ use ra_prof::profile; | |||
9 | use rustc_hash::FxHashSet; | 9 | use rustc_hash::FxHashSet; |
10 | 10 | ||
11 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; | 11 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; |
12 | use crate::{db::HirDatabase, Crate, ImplBlock, Trait}; | 12 | use crate::{db::HirDatabase, expr::ExprId, Crate, DefWithBody, ImplBlock, Trait}; |
13 | 13 | ||
14 | use self::chalk::{from_chalk, ToChalk}; | 14 | use self::chalk::{from_chalk, ToChalk}; |
15 | 15 | ||
@@ -173,6 +173,14 @@ pub(crate) fn trait_solve_query( | |||
173 | ) -> Option<Solution> { | 173 | ) -> Option<Solution> { |
174 | let _p = profile("trait_solve_query"); | 174 | let _p = profile("trait_solve_query"); |
175 | debug!("trait_solve_query({})", goal.value.value.display(db)); | 175 | debug!("trait_solve_query({})", goal.value.value.display(db)); |
176 | |||
177 | if let Obligation::Projection(pred) = &goal.value.value { | ||
178 | if let Ty::Bound(_) = &pred.projection_ty.parameters[0] { | ||
179 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible | ||
180 | return Some(Solution::Ambig(Guidance::Unknown)); | ||
181 | } | ||
182 | } | ||
183 | |||
176 | let canonical = goal.to_chalk(db).cast(); | 184 | let canonical = goal.to_chalk(db).cast(); |
177 | // We currently don't deal with universes (I think / hope they're not yet | 185 | // We currently don't deal with universes (I think / hope they're not yet |
178 | // relevant for our use cases?) | 186 | // relevant for our use cases?) |
@@ -252,3 +260,37 @@ pub enum Guidance { | |||
252 | /// There's no useful information to feed back to type inference | 260 | /// There's no useful information to feed back to type inference |
253 | Unknown, | 261 | Unknown, |
254 | } | 262 | } |
263 | |||
264 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | ||
265 | pub enum FnTrait { | ||
266 | FnOnce, | ||
267 | FnMut, | ||
268 | Fn, | ||
269 | } | ||
270 | |||
271 | impl FnTrait { | ||
272 | fn lang_item_name(self) -> &'static str { | ||
273 | match self { | ||
274 | FnTrait::FnOnce => "fn_once", | ||
275 | FnTrait::FnMut => "fn_mut", | ||
276 | FnTrait::Fn => "fn", | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | |||
281 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
282 | pub struct ClosureFnTraitImplData { | ||
283 | def: DefWithBody, | ||
284 | expr: ExprId, | ||
285 | fn_trait: FnTrait, | ||
286 | } | ||
287 | |||
288 | /// An impl. Usually this comes from an impl block, but some built-in types get | ||
289 | /// synthetic impls. | ||
290 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
291 | pub enum Impl { | ||
292 | /// A normal impl from an impl block. | ||
293 | ImplBlock(ImplBlock), | ||
294 | /// Closure types implement the Fn traits synthetically. | ||
295 | ClosureFnTraitImpl(ClosureFnTraitImplData), | ||
296 | } | ||