@@ -1,6 +1,22 @@ |
|
|
1 |
1 |
//@ run-pass |
2 |
2 |
#![feature(arbitrary_self_types)] |
3 |
3 |
|
|
4 |
+// When probing for methods, we step forward through a chain of types. The first |
|
5 |
+// few of those steps can be reached by jumping through the chain of Derefs or the |
|
6 |
+// chain of Receivers. Later steps can only be reached by following the chain of |
|
7 |
+// Receivers. For instance, supposing A and B implement both Receiver and Deref, |
|
8 |
+// while C and D implement only Receiver: |
|
9 |
+// |
|
10 |
+// Type A<B<C<D>>> |
|
11 |
+// |
|
12 |
+// Deref chain: A -> B -> C |
|
13 |
+// Receiver chain: A -> B -> C -> D -> E |
|
14 |
+// |
|
15 |
+// We report bad type errors from the end of the chain. But at the end of which |
|
16 |
+// chain? We never morph the type as far as E so the correct behavior is to |
|
17 |
+// report errors from point C, i.e. the end of the Deref chain. This test case |
|
18 |
+// ensures we do that. |
|
19 |
+ |
4 |
20 |
struct MyNonNull<T>(*const T); |
5 |
21 |
|
6 |
22 |
impl<T> std::ops::Receiver for MyNonNull<T> { |
@@ -10,7 +26,13 @@ impl std::ops::Receiver for MyNonNull { |
|
|
10 |
26 |
#[allow(dead_code)] |
11 |
27 |
impl<T> MyNonNull<T> { |
12 |
28 |
fn foo<U>(&self) -> *const U { |
13 |
|
-self.cast::<U>().bar() |
|
29 |
+let mnn = self.cast::<U>(); |
|
30 |
+// The following method call is the point of this test. |
|
31 |
+// If probe.rs reported errors from the last type discovered |
|
32 |
+// in the Receiver chain, it would be sad here because U is just |
|
33 |
+// a type variable. But this is a valid call so it ensures |
|
34 |
+// probe.rs doesn't make that mistake. |
|
35 |
+ mnn.bar() |
14 |
36 |
} |
15 |
37 |
fn cast<U>(&self) -> MyNonNull<U> { |
16 |
38 |
MyNonNull(self.0 as *const U) |