Arbitrary self types v2: explain test. · rust-lang/rust@d898aa3 (original) (raw)

Original file line number Diff line number Diff line change
@@ -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)