@@ -93,10 +93,46 @@ fn implicit_dereference() {
9393 let _y = x. is_positive ( ) ; // $ MISSING: target=is_positive type=_y:bool
9494}
9595
96+ mod implicit_deref_coercion_cycle {
97+ use std:: collections:: HashMap ;
98+
99+ #[ derive( Hash , PartialEq , Eq , PartialOrd , Ord , Debug , Clone , Copy ) ]
100+ pub struct Key { }
101+
102+ // This example can trigger a cycle in type inference due to an implicit
103+ // dereference if we are not careful and accurate enough.
104+ //
105+ // To explain how a cycle might happen, we let `[V]` denote the type of the
106+ // type parameter `V` of `key_to_key` (i.e., the type of the values in the
107+ // map) and `[key]` denote the type of `key`.
108+ //
109+ // 1. From the first two lines we infer `[V] = &Key` and `[key] = &Key`
110+ // 2. At the 3. line we infer the type of `ref_key` to be `&[V]`.
111+ // 3. At the 4. line we impose the equality `[key] = &[V]`, not accounting
112+ // for the implicit deref caused by a coercion.
113+ // 4. At the last line we infer `[key] = [V]`.
114+ //
115+ // Putting the above together we have `[V] = [key] = &[V]` which is a cycle.
116+ // This means that `[key]` is both `&Key`, `&&Key`, `&&&Key`, and so on ad
117+ // infinitum.
118+
119+ #[ rustfmt:: skip]
120+ pub fn test ( ) {
121+ let mut key_to_key = HashMap :: < & Key , & Key > :: new ( ) ; // $ target=new
122+ let mut key = & Key { } ; // Initialize key2 to a reference
123+ if let Some ( ref_key) = key_to_key. get ( key) { // $ target=get
124+ // Below `ref_key` is implicitly dereferenced from `&&Key` to `&Key`
125+ key = ref_key;
126+ }
127+ key_to_key. insert ( key, key) ; // $ target=insert
128+ }
129+ }
130+
96131pub fn test ( ) {
97132 explicit_monomorphic_dereference ( ) ; // $ target=explicit_monomorphic_dereference
98133 explicit_polymorphic_dereference ( ) ; // $ target=explicit_polymorphic_dereference
99134 explicit_ref_dereference ( ) ; // $ target=explicit_ref_dereference
100135 explicit_box_dereference ( ) ; // $ target=explicit_box_dereference
101136 implicit_dereference ( ) ; // $ target=implicit_dereference
137+ implicit_deref_coercion_cycle:: test ( ) ; // $ target=test
102138}
0 commit comments