Skip to content

Commit

Permalink
Merge #6685
Browse files Browse the repository at this point in the history
6685: RES: prefer trait methods before private inherent methods r=vlad20012 a=vlad20012

Improves the #5661 fix: now resolve it to visible trait impl instead of private inherent impl:

```rust
use foo::{Foo, Trait};

mod foo {
    pub struct Foo;
    impl Foo {
        // Private
        fn get(&self) { println!("struct"); }
    }

    pub trait Trait {
        fn get(&self);
    }
    impl Trait for Foo {
        fn get(&self) { println!("trait"); }
    }    //X
}

fn main() {
    let f = foo::Foo;
    f.get();
    //^
}
```

c.c. @Kobzol 


Co-authored-by: vlad20012 <beskvlad@gmail.com>
  • Loading branch information
bors[bot] and vlad20012 committed Jan 24, 2021
2 parents 81fee56 + 2153480 commit 6c3905a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,8 @@ class RsTypeInferenceWalker(
return methodType.retType
}

private fun <T : AssocItemScopeEntryBase<E>, E> filterAssocItems(variants: List<T>, context: RsElement): List<T> {
private fun <T : AssocItemScopeEntryBase<*>> filterAssocItems(variants: List<T>, context: RsElement): List<T> {
val containingMod = context.containingMod
return variants.singleOrLet { list ->
// 1. filter traits that are not imported
TypeInferenceMarks.methodPickTraitScope.hit()
Expand All @@ -694,7 +695,12 @@ class RsTypeInferenceWalker(
list
}
}.singleOrFilter { callee ->
// 2. Filter methods by trait bounds (try to select all obligations for each impl)
// 2. filter non-visible (private) items
val source = callee.source
source !is TraitImplSource.ExplicitImpl || !source.isInherent
|| callee.element.isVisibleFrom(containingMod)
}.singleOrFilter { callee ->
// 3. Filter methods by trait bounds (try to select all obligations for each impl)
TypeInferenceMarks.methodPickCheckBounds.hit()
ctx.canEvaluateBounds(callee.source, callee.selfTy)
}
Expand All @@ -706,7 +712,7 @@ class RsTypeInferenceWalker(
methodCall: RsMethodCall
): MethodResolveVariant? {
val filtered = filterAssocItems(variants, methodCall).singleOrLet { list ->
// 3. Pick results matching receiver type
// 4. Pick results matching receiver type
TypeInferenceMarks.methodPickDerefOrder.hit()

fun pick(ty: Ty): List<MethodResolveVariant> =
Expand All @@ -726,7 +732,7 @@ class RsTypeInferenceWalker(
0 -> null
1 -> filtered.single()
else -> {
// 4. Try to collapse multiple resolved methods of the same trait, e.g.
// 5. Try to collapse multiple resolved methods of the same trait, e.g.
// ```rust
// trait Foo<T> { fn foo(&self, _: T) {} }
// impl Foo<Bar> for S { fn foo(&self, _: Bar) {} }
Expand Down
24 changes: 0 additions & 24 deletions src/test/kotlin/org/rust/lang/core/resolve/RsMultiResolveTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -110,30 +110,6 @@ class RsMultiResolveTest : RsResolveTestBase() {
} //^
""")

fun `test trait method and private inherent method`() = doTest("""
use foo::{Foo, Trait};
mod foo {
pub struct Foo;
impl Foo {
fn get(&self) { println!("struct"); }
}
pub trait Trait {
fn get(&self);
}
impl Trait for Foo {
fn get(&self) { println!("trait"); }
}
}
fn main() {
let f = foo::Foo;
f.get();
//^
}
""")

private fun doTest(@Language("Rust") code: String) {
InlineFile(code)
val element = findElementInEditor<RsReferenceElement>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -554,4 +554,29 @@ class RsPreciseTraitMatchingTest : RsResolveTestBase() {
S.foo();
} //^
""")

fun `test trait method and private inherent method`() = checkByCode("""
use foo::{Foo, Trait};
mod foo {
pub struct Foo;
impl Foo {
// Private
fn get(&self) { println!("struct"); }
}
pub trait Trait {
fn get(&self);
}
impl Trait for Foo {
fn get(&self) { println!("trait"); }
} //X
}
fn main() {
let f = foo::Foo;
f.get();
//^
}
""")
}

0 comments on commit 6c3905a

Please sign in to comment.