Skip to content

Commit d898aa3

Browse files
committed
Arbitrary self types v2: explain test.
The purpose of this test wasn't obvious. Add a comment.
1 parent 633a3fe commit d898aa3

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

Diff for: tests/ui/self/arbitrary_self_types_recursive_receiver.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
//@ run-pass
22
#![feature(arbitrary_self_types)]
33

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<E>>>>
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+
420
struct MyNonNull<T>(*const T);
521

622
impl<T> std::ops::Receiver for MyNonNull<T> {
@@ -10,7 +26,13 @@ impl<T> std::ops::Receiver for MyNonNull<T> {
1026
#[allow(dead_code)]
1127
impl<T> MyNonNull<T> {
1228
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()
1436
}
1537
fn cast<U>(&self) -> MyNonNull<U> {
1638
MyNonNull(self.0 as *const U)

0 commit comments

Comments
 (0)