Skip to content

Commit e61807c

Browse files
committed
update higher_ranked_sub docs
1 parent 54fac38 commit e61807c

File tree

3 files changed

+35
-27
lines changed

3 files changed

+35
-27
lines changed

compiler/rustc_infer/src/infer/equate.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,12 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
153153
{
154154
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
155155
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
156-
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
156+
self.fields.higher_ranked_sub(b, a, self.a_is_expected)?;
157157
} else {
158158
// Fast path for the common case.
159159
self.relate(a.skip_binder(), b.skip_binder())?;
160-
Ok(a)
161160
}
161+
Ok(a)
162162
}
163163
}
164164

compiler/rustc_infer/src/infer/higher_ranked/mod.rs

+31-24
Original file line numberDiff line numberDiff line change
@@ -9,49 +9,56 @@ use rustc_middle::ty::{self, Binder, TypeFoldable};
99
use std::cell::Cell;
1010

1111
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
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
}

compiler/rustc_infer/src/infer/sub.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
198198
where
199199
T: Relate<'tcx>,
200200
{
201-
self.fields.higher_ranked_sub(a, b, self.a_is_expected)
201+
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
202+
Ok(a)
202203
}
203204
}
204205

0 commit comments

Comments
 (0)