Skip to content

Commit 4be4829

Browse files
committed
interpret region vars as universals ...
in implied bounds query
1 parent 7c306f6 commit 4be4829

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

compiler/rustc_traits/src/implied_outlives_bounds.rs

+53-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! [`rustc_trait_selection::traits::query::type_op::implied_outlives_bounds`].
44
55
use rustc_infer::infer::canonical::{self, Canonical};
6+
use rustc_infer::infer::canonical::{CanonicalVarInfo, CanonicalVarKind};
67
use rustc_infer::infer::outlives::components::{push_outlives_components, Component};
78
use rustc_infer::infer::TyCtxtInferExt;
89
use rustc_infer::traits::query::OutlivesBound;
@@ -20,17 +21,63 @@ pub(crate) fn provide(p: &mut Providers) {
2021
*p = Providers { implied_outlives_bounds, ..*p };
2122
}
2223

24+
struct MapRegionsToUniversals<'tcx> {
25+
tcx: TyCtxt<'tcx>,
26+
query_max_universe: ty::UniverseIndex,
27+
}
28+
29+
impl<'tcx> MapRegionsToUniversals<'tcx> {
30+
fn map<K>(tcx: TyCtxt<'tcx>, value: Canonical<'tcx, K>) -> (Canonical<'tcx, K>, Self) {
31+
let variables = value.variables.iter().zip(0u32..).map(|(var, idx)| match var.kind {
32+
CanonicalVarKind::Region(universe) => {
33+
let name = ty::BoundRegionKind::BrAnon(idx, None);
34+
let placeholder = ty::Placeholder { universe, name };
35+
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderRegion(placeholder) }
36+
}
37+
CanonicalVarKind::PlaceholderRegion(_) => bug!("unimplemented: placeholder region"),
38+
39+
CanonicalVarKind::Ty(_) => bug!("unexpected ty var"),
40+
CanonicalVarKind::PlaceholderTy(_) => var,
41+
42+
CanonicalVarKind::Const(..) => bug!("unexpected const var"),
43+
CanonicalVarKind::PlaceholderConst(..) => var,
44+
});
45+
let variables = tcx.mk_canonical_var_infos_from_iter(variables);
46+
let query_max_universe = value.max_universe;
47+
48+
(Canonical { variables, ..value }, Self { tcx, query_max_universe })
49+
}
50+
51+
fn reverse_map<K>(&self, value: Canonical<'tcx, K>) -> Canonical<'tcx, K> {
52+
let variables = value.variables.iter().map(|var| match var.kind {
53+
CanonicalVarKind::PlaceholderRegion(ty::Placeholder { universe, .. })
54+
if self.query_max_universe.can_name(universe) =>
55+
{
56+
CanonicalVarInfo { kind: CanonicalVarKind::Region(universe) }
57+
}
58+
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => var,
59+
60+
CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => var,
61+
CanonicalVarKind::Const(..) | CanonicalVarKind::PlaceholderConst(..) => var,
62+
});
63+
let variables = self.tcx.mk_canonical_var_infos_from_iter(variables);
64+
Canonical { variables, ..value }
65+
}
66+
}
67+
2368
fn implied_outlives_bounds<'tcx>(
2469
tcx: TyCtxt<'tcx>,
2570
goal: CanonicalTyGoal<'tcx>,
26-
) -> Result<
27-
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
28-
NoSolution,
29-
> {
30-
tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
71+
) -> Fallible<&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>> {
72+
let (goal, map) = MapRegionsToUniversals::map(tcx, goal);
73+
74+
let result = tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
3175
let (param_env, ty) = key.into_parts();
3276
compute_implied_outlives_bounds(ocx, param_env, ty)
33-
})
77+
})?;
78+
79+
let result = MapRegionsToUniversals::reverse_map(&map, result.clone());
80+
Ok(tcx.arena.alloc(result))
3481
}
3582

3683
fn compute_implied_outlives_bounds<'tcx>(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// check-pass
2+
// issue: #106569
3+
4+
struct Equal<'a, 'b>(&'a &'b (), &'b &'a ()); // implies 'a == 'b
5+
6+
trait Trait { type Ty; }
7+
8+
impl<'x> Trait for Equal<'x, 'x> { type Ty = (); }
9+
10+
fn test1<'a, 'b>(_: (<Equal<'a, 'b> as Trait>::Ty, Equal<'a, 'b>)) {
11+
let _ = None::<Equal<'a, 'b>>;
12+
}
13+
14+
fn test2<'a, 'b>(_: <Equal<'a, 'b> as Trait>::Ty, _: Equal<'a, 'b>) {
15+
let _ = None::<Equal<'a, 'b>>;
16+
}
17+
18+
fn main() {}

0 commit comments

Comments
 (0)