1 #![feature(arbitrary_self_types, coerce_unsized, dispatch_from_dyn, unsize)]
2 #![feature(unsized_locals, unsized_fn_params)]
3 //~^ WARN the feature `unsized_locals` is incomplete
5 // This tests a few edge-cases around `arbitrary_self_types`. Most specifically,
6 // it checks that the `ObjectCandidate` you get from method matching can't
7 // match a trait with the same DefId as a supertrait but a bad type parameter.
9 use std::marker::PhantomData;
12 use std::ops::{CoerceUnsized, Deref, DispatchFromDyn};
13 use std::marker::{PhantomData, Unsize};
15 pub struct Smaht<T: ?Sized, MISC>(pub Box<T>, pub PhantomData<MISC>);
17 impl<T: ?Sized, MISC> Deref for Smaht<T, MISC> {
20 fn deref(&self) -> &Self::Target {
24 impl<T: ?Sized + Unsize<U>, U: ?Sized, MISC> CoerceUnsized<Smaht<U, MISC>>
27 impl<T: ?Sized + Unsize<U>, U: ?Sized, MISC> DispatchFromDyn<Smaht<U, MISC>>
31 pub trait Foo: X<u32> {}
33 fn foo(self: Smaht<Self, T>) -> T;
37 fn foo(self: Smaht<Self, u32>) -> u32 {
43 impl Marker for dyn Foo {}
44 impl<T: Marker + ?Sized> X<u64> for T {
45 fn foo(self: Smaht<Self, u64>) -> u64 {
50 impl Deref for dyn Foo {
52 fn deref(&self) -> &() { &() }
62 impl FinalFoo for () {
63 fn foo(&self) -> u8 { 0 }
67 pub trait NuisanceFoo {
71 impl<T: ?Sized> NuisanceFoo for T {
77 fn objectcandidate_impl() {
78 let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData);
79 let x: internal::Smaht<dyn internal::Foo, u32> = x;
81 // This picks `<dyn internal::Foo as X<u32>>::foo` via `ObjectCandidate`.
83 // The `TraitCandidate` is not relevant because `X` is not in scope.
86 // Observe the type of `z` is `u32`
87 let _seetype: () = z; //~ ERROR mismatched types
88 //~| expected `()`, found `u32`
91 fn traitcandidate_impl() {
94 let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData);
95 let x: internal::Smaht<dyn internal::Foo, u64> = x;
97 // This picks `<dyn internal::Foo as X<u64>>::foo` via `TraitCandidate`.
99 // The `ObjectCandidate` does not apply, as it only applies to
100 // `X<u32>` (and not `X<u64>`).
103 // Observe the type of `z` is `u64`
104 let _seetype: () = z; //~ ERROR mismatched types
105 //~| expected `()`, found `u64`
108 fn traitcandidate_impl_with_nuisance() {
110 use nuisance_foo::NuisanceFoo;
112 let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData);
113 let x: internal::Smaht<dyn internal::Foo, u64> = x;
115 // This picks `<dyn internal::Foo as X<u64>>::foo` via `TraitCandidate`.
117 // The `ObjectCandidate` does not apply, as it only applies to
118 // `X<u32>` (and not `X<u64>`).
120 // The NuisanceFoo impl has the same priority as the `X` impl,
121 // so we get a conflict.
122 let z = x.foo(); //~ ERROR multiple applicable items in scope
127 let x: internal::Smaht<(), u64> = internal::Smaht(Box::new(()), PhantomData);
128 let x: internal::Smaht<dyn internal::Foo, u64> = x;
130 // This can't pick the `TraitCandidate` impl, because `Foo` is not
131 // imported. However, this also can't pick the `ObjectCandidate`
132 // impl, because it only applies to `X<u32>` (and not `X<u64>`).
134 // Therefore, neither of the candidates is applicable, and we pick
135 // the `FinalFoo` impl after another deref, which will return `u8`.
138 // Observe the type of `z` is `u8`
139 let _seetype: () = z; //~ ERROR mismatched types
140 //~| expected `()`, found `u8`
146 let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData);
147 let x: internal::Smaht<dyn internal::Foo, u32> = x;
149 // This can pick both the `TraitCandidate` and the `ObjectCandidate` impl.
151 // However, the `ObjectCandidate` is considered an "inherent candidate",
152 // and therefore has priority over both the `TraitCandidate` as well as
153 // any other "nuisance" candidate" (if present).
156 // Observe the type of `z` is `u32`
157 let _seetype: () = z; //~ ERROR mismatched types
158 //~| expected `()`, found `u32`
162 fn both_impls_with_nuisance() {
163 // Similar to the `both_impls` example, except with a nuisance impl to
164 // make sure the `ObjectCandidate` indeed has a higher priority.
167 use nuisance_foo::NuisanceFoo;
169 let x: internal::Smaht<(), u32> = internal::Smaht(Box::new(()), PhantomData);
170 let x: internal::Smaht<dyn internal::Foo, u32> = x;
173 // Observe the type of `z` is `u32`
174 let _seetype: () = z; //~ ERROR mismatched types
175 //~| expected `()`, found `u32`