48 lines
1.2 KiB
Rust
48 lines
1.2 KiB
Rust
|
|
//@ revisions: current next
|
||
|
|
//@[next] compile-flags: -Znext-solver
|
||
|
|
//@[next] check-pass
|
||
|
|
|
||
|
|
// An annoying edge case of method selection. While computing the deref-chain
|
||
|
|
// constrains `T` to `u32`, the final method candidate does not and instead
|
||
|
|
// constrains to `i32`. In this case, we no longer check that the opaque
|
||
|
|
// remains unconstrained. Both method calls in this test constrain the opaque
|
||
|
|
// to `i32`.
|
||
|
|
use std::ops::Deref;
|
||
|
|
|
||
|
|
struct Foo<T, U>(T, U);
|
||
|
|
impl<U> Deref for Foo<u32, U> {
|
||
|
|
type Target = U;
|
||
|
|
fn deref(&self) -> &Self::Target {
|
||
|
|
&self.1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Foo<i32, i32> {
|
||
|
|
fn method(&self) {}
|
||
|
|
}
|
||
|
|
fn inherent_method() -> impl Sized {
|
||
|
|
if false {
|
||
|
|
let x = Foo(Default::default(), inherent_method());
|
||
|
|
x.method();
|
||
|
|
let _: Foo<i32, _> = x; // Test that we did not apply the deref step
|
||
|
|
}
|
||
|
|
1i32
|
||
|
|
}
|
||
|
|
|
||
|
|
trait Trait {
|
||
|
|
fn trait_method(&self) {}
|
||
|
|
}
|
||
|
|
impl Trait for Foo<i32, i32> {}
|
||
|
|
impl Trait for i32 {}
|
||
|
|
fn trait_method() -> impl Trait {
|
||
|
|
if false {
|
||
|
|
let x = Foo(Default::default(), trait_method());
|
||
|
|
x.trait_method();
|
||
|
|
let _: Foo<i32, _> = x; // Test that we did not apply the deref step
|
||
|
|
//[current]~^ ERROR mismatched types
|
||
|
|
}
|
||
|
|
1i32
|
||
|
|
}
|
||
|
|
|
||
|
|
fn main() {}
|