@@ -76,19 +76,19 @@ use crate::check::dropck;
76
76
use crate :: check:: FnCtxt ;
77
77
use crate :: mem_categorization as mc;
78
78
use crate :: middle:: region;
79
+ use crate :: outlives:: outlives_bounds:: InferCtxtExt as _;
79
80
use rustc_data_structures:: stable_set:: FxHashSet ;
80
81
use rustc_hir as hir;
81
82
use rustc_hir:: def_id:: LocalDefId ;
82
83
use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
83
84
use rustc_hir:: PatKind ;
84
85
use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
85
- use rustc_infer:: infer:: { self , RegionObligation , RegionckMode } ;
86
+ use rustc_infer:: infer:: { self , InferCtxt , RegionObligation , RegionckMode } ;
86
87
use rustc_middle:: hir:: place:: { PlaceBase , PlaceWithHirId } ;
87
88
use rustc_middle:: ty:: adjustment;
88
89
use rustc_middle:: ty:: { self , Ty } ;
89
90
use rustc_span:: Span ;
90
- use rustc_trait_selection:: infer:: OutlivesEnvironmentExt ;
91
- use rustc_trait_selection:: opaque_types:: InferCtxtExt ;
91
+ use rustc_trait_selection:: opaque_types:: InferCtxtExt as _;
92
92
use std:: ops:: Deref ;
93
93
94
94
// a variation on try that just returns unit
@@ -104,6 +104,51 @@ macro_rules! ignore_err {
104
104
} ;
105
105
}
106
106
107
+ trait OutlivesEnvironmentExt < ' tcx > {
108
+ fn add_implied_bounds (
109
+ & mut self ,
110
+ infcx : & InferCtxt < ' a , ' tcx > ,
111
+ fn_sig_tys : FxHashSet < Ty < ' tcx > > ,
112
+ body_id : hir:: HirId ,
113
+ span : Span ,
114
+ ) ;
115
+ }
116
+
117
+ impl < ' tcx > OutlivesEnvironmentExt < ' tcx > for OutlivesEnvironment < ' tcx > {
118
+ /// This method adds "implied bounds" into the outlives environment.
119
+ /// Implied bounds are outlives relationships that we can deduce
120
+ /// on the basis that certain types must be well-formed -- these are
121
+ /// either the types that appear in the function signature or else
122
+ /// the input types to an impl. For example, if you have a function
123
+ /// like
124
+ ///
125
+ /// ```
126
+ /// fn foo<'a, 'b, T>(x: &'a &'b [T]) { }
127
+ /// ```
128
+ ///
129
+ /// we can assume in the caller's body that `'b: 'a` and that `T:
130
+ /// 'b` (and hence, transitively, that `T: 'a`). This method would
131
+ /// add those assumptions into the outlives-environment.
132
+ ///
133
+ /// Tests: `src/test/ui/regions/regions-free-region-ordering-*.rs`
134
+ fn add_implied_bounds (
135
+ & mut self ,
136
+ infcx : & InferCtxt < ' a , ' tcx > ,
137
+ fn_sig_tys : FxHashSet < Ty < ' tcx > > ,
138
+ body_id : hir:: HirId ,
139
+ span : Span ,
140
+ ) {
141
+ debug ! ( "add_implied_bounds()" ) ;
142
+
143
+ for ty in fn_sig_tys {
144
+ let ty = infcx. resolve_vars_if_possible ( ty) ;
145
+ debug ! ( "add_implied_bounds: ty = {}" , ty) ;
146
+ let implied_bounds = infcx. implied_outlives_bounds ( self . param_env , body_id, ty, span) ;
147
+ self . add_outlives_bounds ( Some ( infcx) , implied_bounds)
148
+ }
149
+ }
150
+ }
151
+
107
152
///////////////////////////////////////////////////////////////////////////
108
153
// PUBLIC ENTRY POINTS
109
154
0 commit comments