33//! [`rustc_trait_selection::traits::query::type_op::implied_outlives_bounds`].
44
55use rustc_infer:: infer:: canonical:: { self , Canonical } ;
6+ use rustc_infer:: infer:: canonical:: { CanonicalVarInfo , CanonicalVarKind } ;
67use rustc_infer:: infer:: outlives:: components:: { push_outlives_components, Component } ;
78use rustc_infer:: infer:: TyCtxtInferExt ;
89use 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+
2368fn 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
3683fn compute_implied_outlives_bounds < ' tcx > (
0 commit comments