Open lcnr opened 1 month ago
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
}
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()
}
to get methods from alias bounds
https://rust.godbolt.org/z/vecjoaYzK
People rely on this behavior, see https://github.com/rust-lang/rust/issues/117866, or more specifically, the crater run in https://github.com/rust-lang/rust/pull/120798#issuecomment-1938414794