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<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
+
4
20
struct MyNonNull < T > ( * const T ) ;
5
21
6
22
impl < T > std:: ops:: Receiver for MyNonNull < T > {
@@ -10,7 +26,13 @@ impl<T> std::ops::Receiver for MyNonNull<T> {
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 )
0 commit comments