aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src
diff options
context:
space:
mode:
authorOmer Ben-Amram <[email protected]>2019-12-14 15:29:30 +0000
committerOmer Ben-Amram <[email protected]>2019-12-14 15:29:30 +0000
commit5e4e713fc9c201852fc5fbafd57e5b9243149a78 (patch)
tree996b679a9ae1d07be1edd9eb04e93d433c6524a3 /crates/ra_hir_ty/src
parent083010f6339e558184f06ce76a18e1ad0b0ee936 (diff)
parent77db6177658b32f69ad7ebfdef96c1b3b2893fdd (diff)
Merge branch 'refs/heads/master' into feature/granular-scopes
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r--crates/ra_hir_ty/src/autoderef.rs4
-rw-r--r--crates/ra_hir_ty/src/expr.rs4
-rw-r--r--crates/ra_hir_ty/src/infer.rs64
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs105
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs64
-rw-r--r--crates/ra_hir_ty/src/traits/builtin.rs6
-rw-r--r--crates/ra_hir_ty/src/utils.rs6
7 files changed, 155 insertions, 98 deletions
diff --git a/crates/ra_hir_ty/src/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs
index d557962b4..ee48fa537 100644
--- a/crates/ra_hir_ty/src/autoderef.rs
+++ b/crates/ra_hir_ty/src/autoderef.rs
@@ -6,7 +6,7 @@
6use std::iter::successors; 6use std::iter::successors;
7 7
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9use hir_expand::name; 9use hir_expand::name::name;
10use log::{info, warn}; 10use log::{info, warn};
11use ra_db::CrateId; 11use ra_db::CrateId;
12 12
@@ -52,7 +52,7 @@ fn deref_by_trait(
52 LangItemTarget::TraitId(it) => it, 52 LangItemTarget::TraitId(it) => it,
53 _ => return None, 53 _ => return None,
54 }; 54 };
55 let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?; 55 let target = db.trait_data(deref_trait).associated_type_by_name(&name![Target])?;
56 56
57 let generic_params = generics(db, target.into()); 57 let generic_params = generics(db, target.into());
58 if generic_params.len() != 1 { 58 if generic_params.len() != 1 {
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index d2bd64e5c..f752a9f09 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -3,7 +3,7 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{ 5use hir_def::{
6 path::{known, Path}, 6 path::{path, Path},
7 resolver::HasResolver, 7 resolver::HasResolver,
8 AdtId, FunctionId, 8 AdtId, FunctionId,
9}; 9};
@@ -124,7 +124,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
124 None => return, 124 None => return,
125 }; 125 };
126 126
127 let std_result_path = known::std_result_result(); 127 let std_result_path = path![std::result::Result];
128 128
129 let resolver = self.func.resolver(db); 129 let resolver = self.func.resolver(db);
130 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) { 130 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) {
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index d16f1eb46..f1b7e9442 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -24,20 +24,20 @@ use hir_def::{
24 body::Body, 24 body::Body,
25 data::{ConstData, FunctionData}, 25 data::{ConstData, FunctionData},
26 expr::{BindingAnnotation, ExprId, PatId}, 26 expr::{BindingAnnotation, ExprId, PatId},
27 path::{known, Path}, 27 path::{path, Path},
28 resolver::{HasResolver, Resolver, TypeNs}, 28 resolver::{HasResolver, Resolver, TypeNs},
29 type_ref::{Mutability, TypeRef}, 29 type_ref::{Mutability, TypeRef},
30 AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId, 30 AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId,
31}; 31};
32use hir_expand::{diagnostics::DiagnosticSink, name}; 32use hir_expand::{diagnostics::DiagnosticSink, name::name};
33use ra_arena::map::ArenaMap; 33use ra_arena::map::ArenaMap;
34use ra_prof::profile; 34use ra_prof::profile;
35 35
36use super::{ 36use super::{
37 primitive::{FloatTy, IntTy}, 37 primitive::{FloatTy, IntTy},
38 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 38 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
39 ApplicationTy, InEnvironment, ProjectionTy, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 39 ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor,
40 Uncertain, 40 TypeWalk, Uncertain,
41}; 41};
42use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic}; 42use crate::{db::HirDatabase, infer::diagnostics::InferenceDiagnostic};
43 43
@@ -338,6 +338,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
338 self.table.resolve_ty_shallow(ty) 338 self.table.resolve_ty_shallow(ty)
339 } 339 }
340 340
341 fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
342 match assoc_ty {
343 Some(res_assoc_ty) => {
344 let ty = self.table.new_type_var();
345 let projection = ProjectionPredicate {
346 ty: ty.clone(),
347 projection_ty: ProjectionTy {
348 associated_ty: res_assoc_ty,
349 parameters: Substs::single(inner_ty),
350 },
351 };
352 self.obligations.push(Obligation::Projection(projection));
353 self.resolve_ty_as_possible(ty)
354 }
355 None => Ty::Unknown,
356 }
357 }
358
341 /// Recurses through the given type, normalizing associated types mentioned 359 /// Recurses through the given type, normalizing associated types mentioned
342 /// in it by replacing them by type variables and registering obligations to 360 /// in it by replacing them by type variables and registering obligations to
343 /// resolve later. This should be done once for every type we get from some 361 /// resolve later. This should be done once for every type we get from some
@@ -404,61 +422,73 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
404 } 422 }
405 423
406 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { 424 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
407 let path = known::std_iter_into_iterator(); 425 let path = path![std::iter::IntoIterator];
408 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 426 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
409 self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE) 427 self.db.trait_data(trait_).associated_type_by_name(&name![Item])
410 } 428 }
411 429
412 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { 430 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
413 let path = known::std_ops_try(); 431 let path = path![std::ops::Try];
432 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
433 self.db.trait_data(trait_).associated_type_by_name(&name![Ok])
434 }
435
436 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
437 let path = path![std::ops::Neg];
438 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
439 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
440 }
441
442 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
443 let path = path![std::ops::Not];
414 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 444 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
415 self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE) 445 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
416 } 446 }
417 447
418 fn resolve_future_future_output(&self) -> Option<TypeAliasId> { 448 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
419 let path = known::std_future_future(); 449 let path = path![std::future::Future];
420 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; 450 let trait_ = self.resolver.resolve_known_trait(self.db, &path)?;
421 self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE) 451 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
422 } 452 }
423 453
424 fn resolve_boxed_box(&self) -> Option<AdtId> { 454 fn resolve_boxed_box(&self) -> Option<AdtId> {
425 let path = known::std_boxed_box(); 455 let path = path![std::boxed::Box];
426 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 456 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
427 Some(struct_.into()) 457 Some(struct_.into())
428 } 458 }
429 459
430 fn resolve_range_full(&self) -> Option<AdtId> { 460 fn resolve_range_full(&self) -> Option<AdtId> {
431 let path = known::std_ops_range_full(); 461 let path = path![std::ops::RangeFull];
432 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 462 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
433 Some(struct_.into()) 463 Some(struct_.into())
434 } 464 }
435 465
436 fn resolve_range(&self) -> Option<AdtId> { 466 fn resolve_range(&self) -> Option<AdtId> {
437 let path = known::std_ops_range(); 467 let path = path![std::ops::Range];
438 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 468 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
439 Some(struct_.into()) 469 Some(struct_.into())
440 } 470 }
441 471
442 fn resolve_range_inclusive(&self) -> Option<AdtId> { 472 fn resolve_range_inclusive(&self) -> Option<AdtId> {
443 let path = known::std_ops_range_inclusive(); 473 let path = path![std::ops::RangeInclusive];
444 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 474 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
445 Some(struct_.into()) 475 Some(struct_.into())
446 } 476 }
447 477
448 fn resolve_range_from(&self) -> Option<AdtId> { 478 fn resolve_range_from(&self) -> Option<AdtId> {
449 let path = known::std_ops_range_from(); 479 let path = path![std::ops::RangeFrom];
450 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 480 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
451 Some(struct_.into()) 481 Some(struct_.into())
452 } 482 }
453 483
454 fn resolve_range_to(&self) -> Option<AdtId> { 484 fn resolve_range_to(&self) -> Option<AdtId> {
455 let path = known::std_ops_range_to(); 485 let path = path![std::ops::RangeTo];
456 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 486 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
457 Some(struct_.into()) 487 Some(struct_.into())
458 } 488 }
459 489
460 fn resolve_range_to_inclusive(&self) -> Option<AdtId> { 490 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
461 let path = known::std_ops_range_to_inclusive(); 491 let path = path![std::ops::RangeToInclusive];
462 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; 492 let struct_ = self.resolver.resolve_known_struct(self.db, &path)?;
463 Some(struct_.into()) 493 Some(struct_.into())
464 } 494 }
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 2c296987c..2e3cdd53a 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -10,7 +10,7 @@ use hir_def::{
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
11 AdtId, ContainerId, Lookup, StructFieldId, 11 AdtId, ContainerId, Lookup, StructFieldId,
12}; 12};
13use hir_expand::name::{self, Name}; 13use hir_expand::name::{name, Name};
14use ra_syntax::ast::RangeOp; 14use ra_syntax::ast::RangeOp;
15 15
16use crate::{ 16use crate::{
@@ -19,8 +19,8 @@ use crate::{
19 method_resolution, op, 19 method_resolution, op,
20 traits::InEnvironment, 20 traits::InEnvironment,
21 utils::{generics, variant_data, Generics}, 21 utils::{generics, variant_data, Generics},
22 CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, 22 ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty,
23 TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, 23 TypeCtor, TypeWalk, Uncertain,
24}; 24};
25 25
26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 26use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch};
@@ -95,21 +95,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
95 Expr::For { iterable, body, pat } => { 95 Expr::For { iterable, body, pat } => {
96 let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); 96 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
97 97
98 let pat_ty = match self.resolve_into_iter_item() { 98 let pat_ty =
99 Some(into_iter_item_alias) => { 99 self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
100 let pat_ty = self.table.new_type_var();
101 let projection = ProjectionPredicate {
102 ty: pat_ty.clone(),
103 projection_ty: ProjectionTy {
104 associated_ty: into_iter_item_alias,
105 parameters: Substs::single(iterable_ty),
106 },
107 };
108 self.obligations.push(Obligation::Projection(projection));
109 self.resolve_ty_as_possible(pat_ty)
110 }
111 None => Ty::Unknown,
112 };
113 100
114 self.infer_pat(*pat, &pat_ty, BindingMode::default()); 101 self.infer_pat(*pat, &pat_ty, BindingMode::default());
115 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 102 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
@@ -284,40 +271,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
284 } 271 }
285 Expr::Await { expr } => { 272 Expr::Await { expr } => {
286 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 273 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
287 let ty = match self.resolve_future_future_output() { 274 let ty =
288 Some(future_future_output_alias) => { 275 self.resolve_associated_type(inner_ty, self.resolve_future_future_output());
289 let ty = self.table.new_type_var();
290 let projection = ProjectionPredicate {
291 ty: ty.clone(),
292 projection_ty: ProjectionTy {
293 associated_ty: future_future_output_alias,
294 parameters: Substs::single(inner_ty),
295 },
296 };
297 self.obligations.push(Obligation::Projection(projection));
298 self.resolve_ty_as_possible(ty)
299 }
300 None => Ty::Unknown,
301 };
302 ty 276 ty
303 } 277 }
304 Expr::Try { expr } => { 278 Expr::Try { expr } => {
305 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 279 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
306 let ty = match self.resolve_ops_try_ok() { 280 let ty = self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok());
307 Some(ops_try_ok_alias) => {
308 let ty = self.table.new_type_var();
309 let projection = ProjectionPredicate {
310 ty: ty.clone(),
311 projection_ty: ProjectionTy {
312 associated_ty: ops_try_ok_alias,
313 parameters: Substs::single(inner_ty),
314 },
315 };
316 self.obligations.push(Obligation::Projection(projection));
317 self.resolve_ty_as_possible(ty)
318 }
319 None => Ty::Unknown,
320 };
321 ty 281 ty
322 } 282 }
323 Expr::Cast { expr, type_ref } => { 283 Expr::Cast { expr, type_ref } => {
@@ -372,31 +332,36 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
372 }, 332 },
373 UnaryOp::Neg => { 333 UnaryOp::Neg => {
374 match &inner_ty { 334 match &inner_ty {
375 Ty::Apply(a_ty) => match a_ty.ctor { 335 // Fast path for builtins
376 TypeCtor::Int(Uncertain::Unknown) 336 Ty::Apply(ApplicationTy {
377 | TypeCtor::Int(Uncertain::Known(IntTy { 337 ctor:
378 signedness: Signedness::Signed, 338 TypeCtor::Int(Uncertain::Known(IntTy {
379 .. 339 signedness: Signedness::Signed,
380 })) 340 ..
381 | TypeCtor::Float(..) => inner_ty, 341 })),
382 _ => Ty::Unknown, 342 ..
383 }, 343 })
384 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => { 344 | Ty::Apply(ApplicationTy {
385 inner_ty 345 ctor: TypeCtor::Int(Uncertain::Unknown),
386 } 346 ..
387 // FIXME: resolve ops::Neg trait 347 })
388 _ => Ty::Unknown, 348 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. })
349 | Ty::Infer(InferTy::IntVar(..))
350 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
351 // Otherwise we resolve via the std::ops::Neg trait
352 _ => self
353 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
389 } 354 }
390 } 355 }
391 UnaryOp::Not => { 356 UnaryOp::Not => {
392 match &inner_ty { 357 match &inner_ty {
393 Ty::Apply(a_ty) => match a_ty.ctor { 358 // Fast path for builtins
394 TypeCtor::Bool | TypeCtor::Int(_) => inner_ty, 359 Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })
395 _ => Ty::Unknown, 360 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. })
396 }, 361 | Ty::Infer(InferTy::IntVar(..)) => inner_ty,
397 Ty::Infer(InferTy::IntVar(..)) => inner_ty, 362 // Otherwise we resolve via the std::ops::Not trait
398 // FIXME: resolve ops::Not trait for inner_ty 363 _ => self
399 _ => Ty::Unknown, 364 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
400 } 365 }
401 } 366 }
402 } 367 }
@@ -666,7 +631,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
666 // Parent arguments are unknown, except for the receiver type 631 // Parent arguments are unknown, except for the receiver type
667 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { 632 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) {
668 for (_id, param) in parent_generics { 633 for (_id, param) in parent_generics {
669 if param.name == name::SELF_TYPE { 634 if param.name == name![Self] {
670 substs.push(receiver_ty.clone()); 635 substs.push(receiver_ty.clone());
671 } else { 636 } else {
672 substs.push(Ty::Unknown); 637 substs.push(Ty::Unknown);
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 93c5f9a15..6139adb72 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -116,6 +116,70 @@ mod collections {
116} 116}
117 117
118#[test] 118#[test]
119fn infer_ops_neg() {
120 let (db, pos) = TestDB::with_position(
121 r#"
122//- /main.rs crate:main deps:std
123
124struct Bar;
125struct Foo;
126
127impl std::ops::Neg for Bar {
128 type Output = Foo;
129}
130
131fn test() {
132 let a = Bar;
133 let b = -a;
134 b<|>;
135}
136
137//- /std.rs crate:std
138
139#[prelude_import] use ops::*;
140mod ops {
141 pub trait Neg {
142 type Output;
143 }
144}
145"#,
146 );
147 assert_eq!("Foo", type_at_pos(&db, pos));
148}
149
150#[test]
151fn infer_ops_not() {
152 let (db, pos) = TestDB::with_position(
153 r#"
154//- /main.rs crate:main deps:std
155
156struct Bar;
157struct Foo;
158
159impl std::ops::Not for Bar {
160 type Output = Foo;
161}
162
163fn test() {
164 let a = Bar;
165 let b = !a;
166 b<|>;
167}
168
169//- /std.rs crate:std
170
171#[prelude_import] use ops::*;
172mod ops {
173 pub trait Not {
174 type Output;
175 }
176}
177"#,
178 );
179 assert_eq!("Foo", type_at_pos(&db, pos));
180}
181
182#[test]
119fn infer_from_bound_1() { 183fn infer_from_bound_1() {
120 assert_snapshot!( 184 assert_snapshot!(
121 infer(r#" 185 infer(r#"
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs
index 598fd81e3..cd587a338 100644
--- a/crates/ra_hir_ty/src/traits/builtin.rs
+++ b/crates/ra_hir_ty/src/traits/builtin.rs
@@ -1,7 +1,7 @@
1//! This module provides the built-in trait implementations, e.g. to make 1//! This module provides the built-in trait implementations, e.g. to make
2//! closures implement `Fn`. 2//! closures implement `Fn`.
3use hir_def::{expr::Expr, lang_item::LangItemTarget, TraitId, TypeAliasId}; 3use hir_def::{expr::Expr, lang_item::LangItemTarget, TraitId, TypeAliasId};
4use hir_expand::name; 4use hir_expand::name::name;
5use ra_db::CrateId; 5use ra_db::CrateId;
6 6
7use super::{AssocTyValue, Impl}; 7use super::{AssocTyValue, Impl};
@@ -79,7 +79,7 @@ fn closure_fn_trait_impl_datum(
79 // and don't want to return a valid value only to find out later that FnOnce 79 // and don't want to return a valid value only to find out later that FnOnce
80 // is broken 80 // is broken
81 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; 81 let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
82 let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name::OUTPUT_TYPE)?; 82 let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
83 83
84 let num_args: u16 = match &db.body(data.def.into())[data.expr] { 84 let num_args: u16 = match &db.body(data.def.into())[data.expr] {
85 Expr::Lambda { args, .. } => args.len() as u16, 85 Expr::Lambda { args, .. } => args.len() as u16,
@@ -137,7 +137,7 @@ fn closure_fn_trait_output_assoc_ty_value(
137 137
138 let output_ty_id = db 138 let output_ty_id = db
139 .trait_data(fn_once_trait) 139 .trait_data(fn_once_trait)
140 .associated_type_by_name(&name::OUTPUT_TYPE) 140 .associated_type_by_name(&name![Output])
141 .expect("assoc ty value should not exist"); 141 .expect("assoc ty value should not exist");
142 142
143 BuiltinImplAssocTyValueData { 143 BuiltinImplAssocTyValueData {
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs
index aeb211a91..0049d3c6f 100644
--- a/crates/ra_hir_ty/src/utils.rs
+++ b/crates/ra_hir_ty/src/utils.rs
@@ -10,10 +10,8 @@ use hir_def::{
10 type_ref::TypeRef, 10 type_ref::TypeRef,
11 ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId, 11 ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId, TypeParamId, VariantId,
12}; 12};
13use hir_expand::name::{self, Name}; 13use hir_expand::name::{name, Name};
14 14
15// FIXME: this is wrong, b/c it can't express `trait T: PartialEq<()>`.
16// We should return a `TraitREf` here.
17fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> { 15fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> {
18 let resolver = trait_.resolver(db); 16 let resolver = trait_.resolver(db);
19 // returning the iterator directly doesn't easily work because of 17 // returning the iterator directly doesn't easily work because of
@@ -24,7 +22,7 @@ fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> {
24 .where_predicates 22 .where_predicates
25 .iter() 23 .iter()
26 .filter_map(|pred| match &pred.type_ref { 24 .filter_map(|pred| match &pred.type_ref {
27 TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(), 25 TypeRef::Path(p) if p.as_ident() == Some(&name![Self]) => pred.bound.as_path(),
28 _ => None, 26 _ => None,
29 }) 27 })
30 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { 28 .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) {