aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/traits.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/traits.rs')
-rw-r--r--crates/ra_hir/src/ty/traits.rs44
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;
9use rustc_hash::FxHashSet; 9use rustc_hash::FxHashSet;
10 10
11use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 11use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk};
12use crate::{db::HirDatabase, Crate, ImplBlock, Trait}; 12use crate::{db::HirDatabase, expr::ExprId, Crate, DefWithBody, ImplBlock, Trait};
13 13
14use self::chalk::{from_chalk, ToChalk}; 14use 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)]
265pub enum FnTrait {
266 FnOnce,
267 FnMut,
268 Fn,
269}
270
271impl 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)]
282pub 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)]
291pub 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}