aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-05-25 15:08:18 +0100
committerLukas Wirth <[email protected]>2021-05-25 15:16:29 +0100
commit28ca37175572403edeb92324d251fbceb4c2487f (patch)
tree047556acaa4ff4044d2900902810a3555c6eb2c1 /crates
parent35db5e99f6f982f4257e88d13cbecca250b05efe (diff)
Consider trait to be in scope for trait-impl
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_def/src/resolver.rs38
-rw-r--r--crates/hir_ty/src/infer.rs2
-rw-r--r--crates/hir_ty/src/tests/traits.rs30
3 files changed, 57 insertions, 13 deletions
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index 0391cc49b..fb8a6f260 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -337,22 +337,34 @@ impl Resolver {
337 pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> { 337 pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
338 let mut traits = FxHashSet::default(); 338 let mut traits = FxHashSet::default();
339 for scope in &self.scopes { 339 for scope in &self.scopes {
340 if let Scope::ModuleScope(m) = scope { 340 match scope {
341 if let Some(prelude) = m.def_map.prelude() { 341 Scope::ModuleScope(m) => {
342 let prelude_def_map = prelude.def_map(db); 342 if let Some(prelude) = m.def_map.prelude() {
343 traits.extend(prelude_def_map[prelude.local_id].scope.traits());
344 }
345 traits.extend(m.def_map[m.module_id].scope.traits());
346
347 // Add all traits that are in scope because of the containing DefMaps
348 m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| {
349 if let Some(prelude) = def_map.prelude() {
350 let prelude_def_map = prelude.def_map(db); 343 let prelude_def_map = prelude.def_map(db);
351 traits.extend(prelude_def_map[prelude.local_id].scope.traits()); 344 traits.extend(prelude_def_map[prelude.local_id].scope.traits());
352 } 345 }
353 traits.extend(def_map[module].scope.traits()); 346 traits.extend(m.def_map[m.module_id].scope.traits());
354 None::<()> 347
355 }); 348 // Add all traits that are in scope because of the containing DefMaps
349 m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| {
350 if let Some(prelude) = def_map.prelude() {
351 let prelude_def_map = prelude.def_map(db);
352 traits.extend(prelude_def_map[prelude.local_id].scope.traits());
353 }
354 traits.extend(def_map[module].scope.traits());
355 None::<()>
356 });
357 }
358 &Scope::ImplDefScope(impl_) => {
359 if let Some(target_trait) = &db.impl_data(impl_).target_trait {
360 if let Some(TypeNs::TraitId(trait_)) =
361 self.resolve_path_in_type_ns_fully(db, target_trait.path.mod_path())
362 {
363 traits.insert(trait_);
364 }
365 }
366 }
367 _ => (),
356 } 368 }
357 } 369 }
358 traits 370 traits
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index edb65622f..164e85050 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -578,10 +578,12 @@ impl<'a> InferenceContext<'a> {
578 } 578 }
579 579
580 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { 580 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
581 // FIXME resolve via lang_item once try v2 is stable
581 let path = path![core::ops::Try]; 582 let path = path![core::ops::Try];
582 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; 583 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
583 let trait_data = self.db.trait_data(trait_); 584 let trait_data = self.db.trait_data(trait_);
584 trait_data 585 trait_data
586 // FIXME remove once try v2 is stable
585 .associated_type_by_name(&name![Ok]) 587 .associated_type_by_name(&name![Ok])
586 .or_else(|| trait_data.associated_type_by_name(&name![Output])) 588 .or_else(|| trait_data.associated_type_by_name(&name![Output]))
587 } 589 }
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 6cd8786ea..6ad96bfe3 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -3630,3 +3630,33 @@ fn test<F: FnOnce()>(f: F) {
3630 "#]], 3630 "#]],
3631 ); 3631 );
3632} 3632}
3633
3634#[test]
3635fn trait_in_scope_of_trait_impl() {
3636 check_infer(
3637 r#"
3638mod foo {
3639 pub trait Foo {
3640 fn foo(self);
3641 fn bar(self) -> usize { 0 }
3642 }
3643}
3644impl foo::Foo for u32 {
3645 fn foo(self) {
3646 let _x = self.bar();
3647 }
3648}
3649 "#,
3650 expect![[r#"
3651 45..49 'self': Self
3652 67..71 'self': Self
3653 82..87 '{ 0 }': usize
3654 84..85 '0': usize
3655 131..135 'self': u32
3656 137..173 '{ ... }': ()
3657 151..153 '_x': usize
3658 156..160 'self': u32
3659 156..166 'self.bar()': usize
3660 "#]],
3661 );
3662}