@@ -9,49 +9,56 @@ use rustc_middle::ty::{self, Binder, TypeFoldable};
9
9
use std:: cell:: Cell ;
10
10
11
11
impl < ' a , ' tcx > CombineFields < ' a , ' tcx > {
12
+ /// Checks whether `for<..> sub <: for<..> sup` holds.
13
+ ///
14
+ /// For this to hold, **all** instantiations of the super type
15
+ /// have to be a super type of **at least one** instantiation of
16
+ /// the subtype.
17
+ ///
18
+ /// This is implemented by first entering a new universe.
19
+ /// We then replace all bound variables in `sup` with placeholders,
20
+ /// and all bound variables in `sup` with inference vars.
21
+ /// We can then just relate the two resulting types as normal.
22
+ ///
23
+ /// Note: this is a subtle algorithm. For a full explanation, please see
24
+ /// the [rustc dev guide][rd]
25
+ ///
26
+ /// [rd]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html
12
27
#[ instrument( skip( self ) , level = "debug" ) ]
13
28
pub fn higher_ranked_sub < T > (
14
29
& mut self ,
15
- a : Binder < ' tcx , T > ,
16
- b : Binder < ' tcx , T > ,
17
- a_is_expected : bool ,
18
- ) -> RelateResult < ' tcx , Binder < ' tcx , T > >
30
+ sub : Binder < ' tcx , T > ,
31
+ sup : Binder < ' tcx , T > ,
32
+ sub_is_expected : bool ,
33
+ ) -> RelateResult < ' tcx , ( ) >
19
34
where
20
35
T : Relate < ' tcx > ,
21
36
{
22
- // Rather than checking the subtype relationship between `a` and `b`
23
- // as-is, we need to do some extra work here in order to make sure
24
- // that function subtyping works correctly with respect to regions
25
- //
26
- // Note: this is a subtle algorithm. For a full explanation, please see
27
- // the rustc dev guide:
28
- // <https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html>
29
-
30
37
let span = self . trace . cause . span ;
31
38
32
39
self . infcx . commit_if_ok ( |_| {
33
40
// First, we instantiate each bound region in the supertype with a
34
- // fresh placeholder region.
35
- let b_prime = self . infcx . replace_bound_vars_with_placeholders ( b) ;
41
+ // fresh placeholder region. Note that this automatically creates
42
+ // a new universe if needed.
43
+ let sup_prime = self . infcx . replace_bound_vars_with_placeholders ( sup) ;
36
44
37
45
// Next, we instantiate each bound region in the subtype
38
46
// with a fresh region variable. These region variables --
39
47
// but no other pre-existing region variables -- can name
40
48
// the placeholders.
41
- let a_prime = self . infcx . replace_bound_vars_with_fresh_vars ( span, HigherRankedType , a) ;
49
+ let sub_prime =
50
+ self . infcx . replace_bound_vars_with_fresh_vars ( span, HigherRankedType , sub) ;
42
51
43
- debug ! ( "a_prime={:?}" , a_prime ) ;
44
- debug ! ( "b_prime={:?}" , b_prime ) ;
52
+ debug ! ( "a_prime={:?}" , sub_prime ) ;
53
+ debug ! ( "b_prime={:?}" , sup_prime ) ;
45
54
46
55
// Compare types now that bound regions have been replaced.
47
- let result = self . sub ( a_is_expected) . relate ( a_prime, b_prime) ?;
48
-
49
- debug ! ( "higher_ranked_sub: OK result={:?}" , result) ;
56
+ let result = self . sub ( sub_is_expected) . relate ( sub_prime, sup_prime) ?;
50
57
51
- // We related `a_prime` and `b_prime`, which just had any bound vars
52
- // replaced with placeholders or infer vars, respectively. Relating
53
- // them should not introduce new bound vars .
54
- Ok ( ty :: Binder :: dummy ( result ) )
58
+ debug ! ( "higher_ranked_sub: OK result={result:?}" ) ;
59
+ // NOTE: returning the result here would be dangerous as it contains
60
+ // placeholders which **must not** be named after wards .
61
+ Ok ( ( ) )
55
62
} )
56
63
}
57
64
}
0 commit comments