@@ -9,49 +9,56 @@ use rustc_middle::ty::{self, Binder, TypeFoldable};
99use std:: cell:: Cell ;
1010
1111impl < ' 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
1227 #[ instrument( skip( self ) , level = "debug" ) ]
1328 pub fn higher_ranked_sub < T > (
1429 & 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 , ( ) >
1934 where
2035 T : Relate < ' tcx > ,
2136 {
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-
3037 let span = self . trace . cause . span ;
3138
3239 self . infcx . commit_if_ok ( |_| {
3340 // 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) ;
3644
3745 // Next, we instantiate each bound region in the subtype
3846 // with a fresh region variable. These region variables --
3947 // but no other pre-existing region variables -- can name
4048 // 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) ;
4251
43- debug ! ( "a_prime={:?}" , a_prime ) ;
44- debug ! ( "b_prime={:?}" , b_prime ) ;
52+ debug ! ( "a_prime={:?}" , sub_prime ) ;
53+ debug ! ( "b_prime={:?}" , sup_prime ) ;
4554
4655 // 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) ?;
5057
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 ( ( ) )
5562 } )
5663 }
5764}
0 commit comments