Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5072b65

Browse files
Rebase fallout from TypeRelating::binders, inline higher_ranked_sub
1 parent b153656 commit 5072b65

File tree

2 files changed

+51
-66
lines changed

2 files changed

+51
-66
lines changed

‎compiler/rustc_infer/src/infer/relate/higher_ranked.rs‎

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,11 @@
11
//! Helper routines for higher-ranked things. See the `doc` module at
22
//! the end of the file for details.
33
4-
use super::combine::CombineFields;
54
use crate::infer::CombinedSnapshot;
6-
use crate::infer::{HigherRankedType,InferCtxt};
5+
use crate::infer::InferCtxt;
76
use rustc_middle::ty::fold::FnMutDelegate;
8-
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
9-
use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable};
10-
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 `sub` 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
27-
#[instrument(skip(self), level = "debug")]
28-
pub fn higher_ranked_sub<T>(
29-
&mut self,
30-
sub: Binder<'tcx, T>,
31-
sup: Binder<'tcx, T>,
32-
sub_is_expected: bool,
33-
) -> RelateResult<'tcx, ()>
34-
where
35-
T: Relate<'tcx>,
36-
{
37-
let span = self.trace.cause.span;
38-
// First, we instantiate each bound region in the supertype with a
39-
// fresh placeholder region. Note that this automatically creates
40-
// a new universe if needed.
41-
self.infcx.enter_forall(sup, |sup_prime| {
42-
// Next, we instantiate each bound region in the subtype
43-
// with a fresh region variable. These region variables --
44-
// but no other preexisting region variables -- can name
45-
// the placeholders.
46-
let sub_prime =
47-
self.infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, sub);
48-
debug!("a_prime={:?}", sub_prime);
49-
debug!("b_prime={:?}", sup_prime);
50-
51-
// Compare types now that bound regions have been replaced.
52-
// Reorder the inputs so that the expected is passed first.
53-
let result = if sub_is_expected {
54-
self.sub().relate(sub_prime, sup_prime)
55-
} else {
56-
self.sup().relate(sup_prime, sub_prime)
57-
};
58-
59-
if result.is_ok() {
60-
debug!("OK result={result:?}");
61-
}
62-
// NOTE: returning the result here would be dangerous as it contains
63-
// placeholders which **must not** be named afterwards.
64-
result.map(|_| ())
65-
})
66-
}
67-
}
7+
use rustc_middle::ty::relate::RelateResult;
8+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
689

6910
impl<'tcx> InferCtxt<'tcx> {
7011
/// Replaces all bound variables (lifetimes, types, and constants) bound by

‎compiler/rustc_infer/src/infer/relate/type_relating.rs‎

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::combine::CombineFields;
2+
use crate::infer::BoundRegionConversionTime::HigherRankedType;
23
use crate::infer::{
34
DefineOpaqueTypes, ObligationEmittingRelation, StructurallyRelateAliases, SubregionOrigin,
45
};
@@ -214,16 +215,59 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
214215
{
215216
self.relate(a, b)?;
216217
} else {
218+
let span = self.fields.trace.cause.span;
219+
let infcx = self.fields.infcx;
220+
217221
match self.ambient_variance {
222+
// Checks whether `for<..> sub <: for<..> sup` holds.
223+
//
224+
// For this to hold, **all** instantiations of the super type
225+
// have to be a super type of **at least one** instantiation of
226+
// the subtype.
227+
//
228+
// This is implemented by first entering a new universe.
229+
// We then replace all bound variables in `sup` with placeholders,
230+
// and all bound variables in `sub` with inference vars.
231+
// We can then just relate the two resulting types as normal.
232+
//
233+
// Note: this is a subtle algorithm. For a full explanation, please see
234+
// the [rustc dev guide][rd]
235+
//
236+
// [rd]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/placeholders_and_universes.html
218237
ty::Covariant => {
219-
self.fields.higher_ranked_sub(a, b, true)?;
238+
infcx.enter_forall(b, |b| {
239+
let a = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, a);
240+
self.relate(a, b)
241+
})?;
220242
}
221243
ty::Contravariant => {
222-
self.fields.higher_ranked_sub(b, a, false)?;
244+
infcx.enter_forall(a, |a| {
245+
let b = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, b);
246+
self.relate(a, b)
247+
})?;
223248
}
249+
250+
// When **equating** binders, we check that there is a 1-to-1
251+
// correspondence between the bound vars in both types.
252+
//
253+
// We do so by separately instantiating one of the binders with
254+
// placeholders and the other with inference variables and then
255+
// equating the instantiated types.
256+
//
257+
// We want `for<..> A == for<..> B` -- therefore we want
258+
// `exists<..> A == for<..> B` and `exists<..> B == for<..> A`.
259+
// Check if `exists<..> A == for<..> B`
224260
ty::Invariant => {
225-
self.fields.higher_ranked_sub(a, b, true)?;
226-
self.fields.higher_ranked_sub(b, a, false)?;
261+
infcx.enter_forall(b, |b| {
262+
let a = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, a);
263+
self.relate(a, b)
264+
})?;
265+
266+
// Check if `exists<..> B == for<..> A`.
267+
infcx.enter_forall(a, |a| {
268+
let b = infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, b);
269+
self.relate(a, b)
270+
})?;
227271
}
228272
ty::Bivariant => {
229273
unreachable!("Expected bivariance to be handled in relate_with_variance")

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /