Skip to content

Commit 3a13699

Browse files
bors[bot]Veykril
andauthored
8991: Consider trait to be in scope for trait-impls r=Veykril a=Veykril Fixes rust-lang#8912 bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents 35db5e9 + 28ca371 commit 3a13699

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

crates/hir_def/src/resolver.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -337,22 +337,34 @@ impl Resolver {
337337
pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
338338
let mut traits = FxHashSet::default();
339339
for scope in &self.scopes {
340-
if let Scope::ModuleScope(m) = scope {
341-
if let Some(prelude) = m.def_map.prelude() {
342-
let prelude_def_map = prelude.def_map(db);
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() {
340+
match scope {
341+
Scope::ModuleScope(m) => {
342+
if let Some(prelude) = m.def_map.prelude() {
350343
let prelude_def_map = prelude.def_map(db);
351344
traits.extend(prelude_def_map[prelude.local_id].scope.traits());
352345
}
353-
traits.extend(def_map[module].scope.traits());
354-
None::<()>
355-
});
346+
traits.extend(m.def_map[m.module_id].scope.traits());
347+
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+
_ => (),
356368
}
357369
}
358370
traits

crates/hir_ty/src/infer.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,10 +578,12 @@ impl<'a> InferenceContext<'a> {
578578
}
579579

580580
fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
581+
// FIXME resolve via lang_item once try v2 is stable
581582
let path = path![core::ops::Try];
582583
let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
583584
let trait_data = self.db.trait_data(trait_);
584585
trait_data
586+
// FIXME remove once try v2 is stable
585587
.associated_type_by_name(&name![Ok])
586588
.or_else(|| trait_data.associated_type_by_name(&name![Output]))
587589
}

crates/hir_ty/src/tests/traits.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3630,3 +3630,33 @@ fn test<F: FnOnce()>(f: F) {
36303630
"#]],
36313631
);
36323632
}
3633+
3634+
#[test]
3635+
fn trait_in_scope_of_trait_impl() {
3636+
check_infer(
3637+
r#"
3638+
mod foo {
3639+
pub trait Foo {
3640+
fn foo(self);
3641+
fn bar(self) -> usize { 0 }
3642+
}
3643+
}
3644+
impl 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+
}

0 commit comments

Comments
 (0)