3
3
//! [`rustc_trait_selection::traits::query::type_op::implied_outlives_bounds`].
4
4
5
5
use rustc_infer:: infer:: canonical:: { self , Canonical } ;
6
+ use rustc_infer:: infer:: canonical:: { CanonicalVarInfo , CanonicalVarKind } ;
6
7
use rustc_infer:: infer:: outlives:: components:: { push_outlives_components, Component } ;
7
8
use rustc_infer:: infer:: TyCtxtInferExt ;
8
9
use rustc_infer:: traits:: query:: OutlivesBound ;
@@ -20,17 +21,63 @@ pub(crate) fn provide(p: &mut Providers) {
20
21
* p = Providers { implied_outlives_bounds, ..* p } ;
21
22
}
22
23
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
+
23
68
fn implied_outlives_bounds < ' tcx > (
24
69
tcx : TyCtxt < ' tcx > ,
25
70
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| {
31
75
let ( param_env, ty) = key. into_parts ( ) ;
32
76
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) )
34
81
}
35
82
36
83
fn compute_implied_outlives_bounds < ' tcx > (
0 commit comments