Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
bors[bot] and Veykril committed May 25, 2021
2 parents 35db5e9 + 28ca371 commit 3a13699
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 13 deletions.
38 changes: 25 additions & 13 deletions crates/hir_def/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,22 +337,34 @@ impl Resolver {
pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
let mut traits = FxHashSet::default();
for scope in &self.scopes {
if let Scope::ModuleScope(m) = scope {
if let Some(prelude) = m.def_map.prelude() {
let prelude_def_map = prelude.def_map(db);
traits.extend(prelude_def_map[prelude.local_id].scope.traits());
}
traits.extend(m.def_map[m.module_id].scope.traits());

// Add all traits that are in scope because of the containing DefMaps
m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| {
if let Some(prelude) = def_map.prelude() {
match scope {
Scope::ModuleScope(m) => {
if let Some(prelude) = m.def_map.prelude() {
let prelude_def_map = prelude.def_map(db);
traits.extend(prelude_def_map[prelude.local_id].scope.traits());
}
traits.extend(def_map[module].scope.traits());
None::<()>
});
traits.extend(m.def_map[m.module_id].scope.traits());

// Add all traits that are in scope because of the containing DefMaps
m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| {
if let Some(prelude) = def_map.prelude() {
let prelude_def_map = prelude.def_map(db);
traits.extend(prelude_def_map[prelude.local_id].scope.traits());
}
traits.extend(def_map[module].scope.traits());
None::<()>
});
}
&Scope::ImplDefScope(impl_) => {
if let Some(target_trait) = &db.impl_data(impl_).target_trait {
if let Some(TypeNs::TraitId(trait_)) =
self.resolve_path_in_type_ns_fully(db, target_trait.path.mod_path())
{
traits.insert(trait_);
}
}
}
_ => (),
}
}
traits
Expand Down
2 changes: 2 additions & 0 deletions crates/hir_ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -578,10 +578,12 @@ impl<'a> InferenceContext<'a> {
}

fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
// FIXME resolve via lang_item once try v2 is stable
let path = path![core::ops::Try];
let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
let trait_data = self.db.trait_data(trait_);
trait_data
// FIXME remove once try v2 is stable
.associated_type_by_name(&name![Ok])
.or_else(|| trait_data.associated_type_by_name(&name![Output]))
}
Expand Down
30 changes: 30 additions & 0 deletions crates/hir_ty/src/tests/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3630,3 +3630,33 @@ fn test<F: FnOnce()>(f: F) {
"#]],
);
}

#[test]
fn trait_in_scope_of_trait_impl() {
check_infer(
r#"
mod foo {
pub trait Foo {
fn foo(self);
fn bar(self) -> usize { 0 }
}
}
impl foo::Foo for u32 {
fn foo(self) {
let _x = self.bar();
}
}
"#,
expect![[r#"
45..49 'self': Self
67..71 'self': Self
82..87 '{ 0 }': usize
84..85 '0': usize
131..135 'self': u32
137..173 '{ ... }': ()
151..153 '_x': usize
156..160 'self': u32
156..166 'self.bar()': usize
"#]],
);
}

0 comments on commit 3a13699

Please sign in to comment.