Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

method resolution can use yet undefined opaques #131

Open
lcnr opened this issue Oct 7, 2024 · 3 comments
Open

method resolution can use yet undefined opaques #131

lcnr opened this issue Oct 7, 2024 · 3 comments

Comments

@lcnr
Copy link
Contributor

lcnr commented Oct 7, 2024

to get methods from alias bounds

fn foo<T: Clone>(x: T, choose: bool) -> impl Clone {
    if choose {
        foo(x, false).clone()
    } else {
        x
    }
}

https://rust.godbolt.org/z/vecjoaYzK

People rely on this behavior, see rust-lang/rust#117866, or more specifically, the crater run in rust-lang/rust#120798 (comment)

@lcnr
Copy link
Contributor Author

lcnr commented Oct 7, 2024

to get to nested receivers while computing auto deref steps

use std::ops::Deref;

fn foo(x: Box<u32>, choose: bool) -> impl Deref<Target = u32> {
    if choose {
        let value = foo(x, false).leading_zeros();
        Box::new(value)
    } else {
        x
    }
}

https://rust.godbolt.org/z/6Tf18YnPq

this can then be used ot define the opaque

use std::ops::Deref;
#[derive(Default)]
struct Foo;
impl Foo {
    fn method(self: Box<Foo>) {}
}

fn foo(choose: bool) -> impl Deref<Target = Foo> {
    if choose {
        foo(false).method();
    }

    Default::default()
}

https://rust.godbolt.org/z/1eoed4Tq7

and can very frequently be undesirable

use std::ops::Deref;
struct Foo;
impl Foo {
    fn method(&self) {}
}

struct Bar;
impl Deref for Bar {
    type Target = Foo;
    fn deref(&self) -> &Foo {
        &Foo
    }
}

fn deref_to_foo(choose: bool) -> impl Deref<Target = Foo> {
    if choose {
        deref_to_foo(false).method();
    }

    Bar
}

https://rust.godbolt.org/z/3hYs9TYhv

@lcnr
Copy link
Contributor Author

lcnr commented Oct 7, 2024

to discard candidates for which an item bound does not hold

#[derive(Default)]
struct MyType<T>(T);
impl MyType<u32> {
    fn method(self) {}
}

impl MyType<String> {
    fn method(self) {}
}

fn foo(choose: bool) -> MyType<impl Copy> {
    if choose {
        foo(false).method();
    }

    Default::default()
}

https://rust.godbolt.org/z/MYEEzfvj9

@lcnr
Copy link
Contributor Author

lcnr commented Jan 21, 2025

non-trivial affected tests and additional issues, even with #135445 and https://github.com/lcnr/rust/tree/opaque-type-method-call

  • subtyping, thx boxy
    • tests/ui/impl-trait/call_method_ambiguous.rs
    • tests/ui/impl-trait/call_method_without_import.rs
    • tests/ui/impl-trait/method-resolution2.rs
  • should be ambig?!?!11
    • tests/ui/impl-trait/method-resolution2.rs
  • god knows, sadness and sorrow
    • tests/ui/impl-trait/recursive-parent-trait-method-call.rs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant