11//! Error reporting machinery for lifetime errors.
22
3- use rustc:: infer:: {
4- error_reporting:: nice_region_error:: NiceRegionError , InferCtxt , NLLRegionVariableOrigin ,
5- } ;
3+ use rustc:: infer:: { error_reporting:: nice_region_error:: NiceRegionError , NLLRegionVariableOrigin } ;
64use rustc:: mir:: ConstraintCategory ;
75use rustc:: ty:: { self , RegionVid , Ty } ;
86use rustc_errors:: { Applicability , DiagnosticBuilder } ;
@@ -14,7 +12,7 @@ use crate::util::borrowck_errors;
1412
1513use crate :: borrow_check:: {
1614 nll:: ConstraintDescription ,
17- region_infer:: { values:: RegionElement , RegionInferenceContext , TypeTest } ,
15+ region_infer:: { values:: RegionElement , TypeTest } ,
1816 universal_regions:: DefiningTy ,
1917 MirBorrowckCtxt ,
2018} ;
@@ -104,26 +102,28 @@ pub struct ErrorConstraintInfo {
104102 pub ( super ) span : Span ,
105103}
106104
107- impl < ' tcx > RegionInferenceContext < ' tcx > {
105+ impl < ' a , ' tcx > MirBorrowckCtxt < ' a , ' tcx > {
108106 /// Converts a region inference variable into a `ty::Region` that
109107 /// we can use for error reporting. If `r` is universally bound,
110108 /// then we use the name that we have on record for it. If `r` is
111109 /// existentially bound, then we check its inferred value and try
112110 /// to find a good name from that. Returns `None` if we can't find
113111 /// one (e.g., this is just some random part of the CFG).
114- pub fn to_error_region ( & self , r : RegionVid ) -> Option < ty:: Region < ' tcx > > {
115- self . to_error_region_vid ( r) . and_then ( |r| self . definitions [ r] . external_name )
112+ // TODO(mark-i-m): make this private when we move report_region_errors here...
113+ crate fn to_error_region ( & self , r : RegionVid ) -> Option < ty:: Region < ' tcx > > {
114+ self . to_error_region_vid ( r)
115+ . and_then ( |r| self . nonlexical_regioncx . definitions [ r] . external_name )
116116 }
117117
118- /// Returns the [ RegionVid] corresponding to the region returned by
118+ /// Returns the ` RegionVid` corresponding to the region returned by
119119 /// `to_error_region`.
120- pub fn to_error_region_vid ( & self , r : RegionVid ) -> Option < RegionVid > {
121- if self . universal_regions . is_universal_region ( r) {
120+ pub ( super ) fn to_error_region_vid ( & self , r : RegionVid ) -> Option < RegionVid > {
121+ if self . nonlexical_regioncx . universal_regions . is_universal_region ( r) {
122122 Some ( r)
123123 } else {
124- let r_scc = self . constraint_sccs . scc ( r) ;
125- let upper_bound = self . universal_upper_bound ( r) ;
126- if self . scc_values . contains ( r_scc, upper_bound) {
124+ let r_scc = self . nonlexical_regioncx . constraint_sccs . scc ( r) ;
125+ let upper_bound = self . nonlexical_regioncx . universal_upper_bound ( r) ;
126+ if self . nonlexical_regioncx . scc_values . contains ( r_scc, upper_bound) {
127127 self . to_error_region_vid ( upper_bound)
128128 } else {
129129 None
@@ -132,11 +132,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
132132 }
133133
134134 /// Returns `true` if a closure is inferred to be an `FnMut` closure.
135- crate fn is_closure_fn_mut ( & self , infcx : & InferCtxt < ' _ , ' tcx > , fr : RegionVid ) -> bool {
135+ fn is_closure_fn_mut ( & self , fr : RegionVid ) -> bool {
136136 if let Some ( ty:: ReFree ( free_region) ) = self . to_error_region ( fr) {
137137 if let ty:: BoundRegion :: BrEnv = free_region. bound_region {
138- if let DefiningTy :: Closure ( def_id, substs) = self . universal_regions . defining_ty {
139- let closure_kind_ty = substs. as_closure ( ) . kind_ty ( def_id, infcx. tcx ) ;
138+ if let DefiningTy :: Closure ( def_id, substs) =
139+ self . nonlexical_regioncx . universal_regions . defining_ty
140+ {
141+ let closure_kind_ty = substs. as_closure ( ) . kind_ty ( def_id, self . infcx . tcx ) ;
140142 return Some ( ty:: ClosureKind :: FnMut ) == closure_kind_ty. to_opt_closure_kind ( ) ;
141143 }
142144 }
@@ -153,34 +155,35 @@ impl<'tcx> RegionInferenceContext<'tcx> {
153155 /// ```
154156 ///
155157 /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
156- pub ( in crate :: borrow_check) fn report_error < ' a > (
157- & ' a self ,
158- mbcx : & MirBorrowckCtxt < ' a , ' tcx > ,
158+ pub ( in crate :: borrow_check) fn report_error (
159+ & mut self ,
159160 fr : RegionVid ,
160161 fr_origin : NLLRegionVariableOrigin ,
161162 outlived_fr : RegionVid ,
162163 outlives_suggestion : & mut OutlivesSuggestionBuilder ,
163164 renctx : & mut RegionErrorNamingCtx ,
164- ) -> DiagnosticBuilder < ' a > {
165+ ) {
165166 debug ! ( "report_error(fr={:?}, outlived_fr={:?})" , fr, outlived_fr) ;
166167
167- let ( category, _, span) = self . best_blame_constraint ( & mbcx. body , fr, fr_origin, |r| {
168- self . provides_universal_region ( r, fr, outlived_fr)
169- } ) ;
168+ let ( category, _, span) =
169+ self . nonlexical_regioncx . best_blame_constraint ( & self . body , fr, fr_origin, |r| {
170+ self . nonlexical_regioncx . provides_universal_region ( r, fr, outlived_fr)
171+ } ) ;
170172
171173 debug ! ( "report_error: category={:?} {:?}" , category, span) ;
172174 // Check if we can use one of the "nice region errors".
173175 if let ( Some ( f) , Some ( o) ) = ( self . to_error_region ( fr) , self . to_error_region ( outlived_fr) ) {
174- let tables = mbcx . infcx . tcx . typeck_tables_of ( mbcx . mir_def_id ) ;
175- let nice = NiceRegionError :: new_from_span ( mbcx . infcx , span, o, f, Some ( tables) ) ;
176+ let tables = self . infcx . tcx . typeck_tables_of ( self . mir_def_id ) ;
177+ let nice = NiceRegionError :: new_from_span ( self . infcx , span, o, f, Some ( tables) ) ;
176178 if let Some ( diag) = nice. try_report_from_nll ( ) {
177- return diag;
179+ diag. buffer ( & mut self . errors_buffer ) ;
180+ return ;
178181 }
179182 }
180183
181184 let ( fr_is_local, outlived_fr_is_local) : ( bool , bool ) = (
182- self . universal_regions . is_local_free_region ( fr) ,
183- self . universal_regions . is_local_free_region ( outlived_fr) ,
185+ self . nonlexical_regioncx . universal_regions . is_local_free_region ( fr) ,
186+ self . nonlexical_regioncx . universal_regions . is_local_free_region ( outlived_fr) ,
184187 ) ;
185188
186189 debug ! (
@@ -197,28 +200,30 @@ impl<'tcx> RegionInferenceContext<'tcx> {
197200 span,
198201 } ;
199202
200- match ( category, fr_is_local, outlived_fr_is_local) {
201- ( ConstraintCategory :: Return , true , false ) if self . is_closure_fn_mut ( mbcx . infcx , fr) => {
202- self . report_fnmut_error ( mbcx , & errci, renctx)
203+ let diag = match ( category, fr_is_local, outlived_fr_is_local) {
204+ ( ConstraintCategory :: Return , true , false ) if self . is_closure_fn_mut ( fr) => {
205+ self . report_fnmut_error ( & errci, renctx)
203206 }
204207 ( ConstraintCategory :: Assignment , true , false )
205208 | ( ConstraintCategory :: CallArgument , true , false ) => {
206- let mut db = self . report_escaping_data_error ( mbcx , & errci, renctx) ;
209+ let mut db = self . report_escaping_data_error ( & errci, renctx) ;
207210
208- outlives_suggestion. intermediate_suggestion ( mbcx , & errci, renctx, & mut db) ;
211+ outlives_suggestion. intermediate_suggestion ( self , & errci, renctx, & mut db) ;
209212 outlives_suggestion. collect_constraint ( fr, outlived_fr) ;
210213
211214 db
212215 }
213216 _ => {
214- let mut db = self . report_general_error ( mbcx , & errci, renctx) ;
217+ let mut db = self . report_general_error ( & errci, renctx) ;
215218
216- outlives_suggestion. intermediate_suggestion ( mbcx , & errci, renctx, & mut db) ;
219+ outlives_suggestion. intermediate_suggestion ( self , & errci, renctx, & mut db) ;
217220 outlives_suggestion. collect_constraint ( fr, outlived_fr) ;
218221
219222 db
220223 }
221- }
224+ } ;
225+
226+ diag. buffer ( & mut self . errors_buffer ) ;
222227 }
223228
224229 /// Report a specialized error when `FnMut` closures return a reference to a captured variable.
@@ -239,21 +244,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
239244 /// ```
240245 fn report_fnmut_error (
241246 & self ,
242- mbcx : & MirBorrowckCtxt < ' _ , ' tcx > ,
243247 errci : & ErrorConstraintInfo ,
244248 renctx : & mut RegionErrorNamingCtx ,
245- ) -> DiagnosticBuilder < ' _ > {
249+ ) -> DiagnosticBuilder < ' tcx > {
246250 let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
247251
248- let mut diag = mbcx
252+ let mut diag = self
249253 . infcx
250254 . tcx
251255 . sess
252256 . struct_span_err ( * span, "captured variable cannot escape `FnMut` closure body" ) ;
253257
254258 // We should check if the return type of this closure is in fact a closure - in that
255259 // case, we can special case the error further.
256- let return_type_is_closure = self . universal_regions . unnormalized_output_ty . is_closure ( ) ;
260+ let return_type_is_closure =
261+ self . nonlexical_regioncx . universal_regions . unnormalized_output_ty . is_closure ( ) ;
257262 let message = if return_type_is_closure {
258263 "returns a closure that contains a reference to a captured variable, which then \
259264 escapes the closure body"
@@ -263,7 +268,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
263268
264269 diag. span_label ( * span, message) ;
265270
266- match self . give_region_a_name ( mbcx , renctx, * outlived_fr) . unwrap ( ) . source {
271+ match self . give_region_a_name ( renctx, * outlived_fr) . unwrap ( ) . source {
267272 RegionNameSource :: NamedEarlyBoundRegion ( fr_span)
268273 | RegionNameSource :: NamedFreeRegion ( fr_span)
269274 | RegionNameSource :: SynthesizedFreeEnvRegion ( fr_span, _)
@@ -300,28 +305,27 @@ impl<'tcx> RegionInferenceContext<'tcx> {
300305 /// ```
301306 fn report_escaping_data_error (
302307 & self ,
303- mbcx : & MirBorrowckCtxt < ' _ , ' tcx > ,
304308 errci : & ErrorConstraintInfo ,
305309 renctx : & mut RegionErrorNamingCtx ,
306- ) -> DiagnosticBuilder < ' _ > {
310+ ) -> DiagnosticBuilder < ' tcx > {
307311 let ErrorConstraintInfo { span, category, .. } = errci;
308312
309- let fr_name_and_span = self . get_var_name_and_span_for_region (
310- mbcx . infcx . tcx ,
311- & mbcx . body ,
312- & mbcx . local_names ,
313- & mbcx . upvars ,
313+ let fr_name_and_span = self . nonlexical_regioncx . get_var_name_and_span_for_region (
314+ self . infcx . tcx ,
315+ & self . body ,
316+ & self . local_names ,
317+ & self . upvars ,
314318 errci. fr ,
315319 ) ;
316- let outlived_fr_name_and_span = self . get_var_name_and_span_for_region (
317- mbcx . infcx . tcx ,
318- & mbcx . body ,
319- & mbcx . local_names ,
320- & mbcx . upvars ,
320+ let outlived_fr_name_and_span = self . nonlexical_regioncx . get_var_name_and_span_for_region (
321+ self . infcx . tcx ,
322+ & self . body ,
323+ & self . local_names ,
324+ & self . upvars ,
321325 errci. outlived_fr ,
322326 ) ;
323327
324- let escapes_from = match self . universal_regions . defining_ty {
328+ let escapes_from = match self . nonlexical_regioncx . universal_regions . defining_ty {
325329 DefiningTy :: Closure ( ..) => "closure" ,
326330 DefiningTy :: Generator ( ..) => "generator" ,
327331 DefiningTy :: FnDef ( ..) => "function" ,
@@ -335,14 +339,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
335339 || escapes_from == "const"
336340 {
337341 return self . report_general_error (
338- mbcx,
339342 & ErrorConstraintInfo { fr_is_local : true , outlived_fr_is_local : false , ..* errci } ,
340343 renctx,
341344 ) ;
342345 }
343346
344347 let mut diag =
345- borrowck_errors:: borrowed_data_escapes_closure ( mbcx . infcx . tcx , * span, escapes_from) ;
348+ borrowck_errors:: borrowed_data_escapes_closure ( self . infcx . tcx , * span, escapes_from) ;
346349
347350 if let Some ( ( Some ( outlived_fr_name) , outlived_fr_span) ) = outlived_fr_name_and_span {
348351 diag. span_label (
@@ -386,10 +389,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
386389 /// ```
387390 fn report_general_error (
388391 & self ,
389- mbcx : & MirBorrowckCtxt < ' _ , ' tcx > ,
390392 errci : & ErrorConstraintInfo ,
391393 renctx : & mut RegionErrorNamingCtx ,
392- ) -> DiagnosticBuilder < ' _ > {
394+ ) -> DiagnosticBuilder < ' tcx > {
393395 let ErrorConstraintInfo {
394396 fr,
395397 fr_is_local,
@@ -401,14 +403,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
401403 } = errci;
402404
403405 let mut diag =
404- mbcx . infcx . tcx . sess . struct_span_err ( * span, "lifetime may not live long enough" ) ;
406+ self . infcx . tcx . sess . struct_span_err ( * span, "lifetime may not live long enough" ) ;
405407
406408 let mir_def_name =
407- if mbcx . infcx . tcx . is_closure ( mbcx . mir_def_id ) { "closure" } else { "function" } ;
409+ if self . infcx . tcx . is_closure ( self . mir_def_id ) { "closure" } else { "function" } ;
408410
409- let fr_name = self . give_region_a_name ( mbcx , renctx, * fr) . unwrap ( ) ;
411+ let fr_name = self . give_region_a_name ( renctx, * fr) . unwrap ( ) ;
410412 fr_name. highlight_region_name ( & mut diag) ;
411- let outlived_fr_name = self . give_region_a_name ( mbcx , renctx, * outlived_fr) . unwrap ( ) ;
413+ let outlived_fr_name = self . give_region_a_name ( renctx, * outlived_fr) . unwrap ( ) ;
412414 outlived_fr_name. highlight_region_name ( & mut diag) ;
413415
414416 match ( category, outlived_fr_is_local, fr_is_local) {
@@ -435,7 +437,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
435437 }
436438 }
437439
438- self . add_static_impl_trait_suggestion ( mbcx . infcx , & mut diag, * fr, fr_name, * outlived_fr) ;
440+ self . add_static_impl_trait_suggestion ( & mut diag, * fr, fr_name, * outlived_fr) ;
439441
440442 diag
441443 }
@@ -451,8 +453,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
451453 /// ```
452454 fn add_static_impl_trait_suggestion (
453455 & self ,
454- infcx : & InferCtxt < ' _ , ' tcx > ,
455- diag : & mut DiagnosticBuilder < ' _ > ,
456+ diag : & mut DiagnosticBuilder < ' tcx > ,
456457 fr : RegionVid ,
457458 // We need to pass `fr_name` - computing it again will label it twice.
458459 fr_name : RegionName ,
@@ -461,20 +462,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
461462 if let ( Some ( f) , Some ( ty:: RegionKind :: ReStatic ) ) =
462463 ( self . to_error_region ( fr) , self . to_error_region ( outlived_fr) )
463464 {
464- if let Some ( ( ty:: TyS { kind : ty:: Opaque ( did, substs) , .. } , _) ) = infcx
465+ if let Some ( ( ty:: TyS { kind : ty:: Opaque ( did, substs) , .. } , _) ) = self
466+ . infcx
465467 . tcx
466468 . is_suitable_region ( f)
467469 . map ( |r| r. def_id )
468- . map ( |id| infcx. tcx . return_type_impl_trait ( id) )
470+ . map ( |id| self . infcx . tcx . return_type_impl_trait ( id) )
469471 . unwrap_or ( None )
470472 {
471473 // Check whether or not the impl trait return type is intended to capture
472474 // data with the static lifetime.
473475 //
474476 // eg. check for `impl Trait + 'static` instead of `impl Trait`.
475477 let has_static_predicate = {
476- let predicates_of = infcx. tcx . predicates_of ( * did) ;
477- let bounds = predicates_of. instantiate ( infcx. tcx , substs) ;
478+ let predicates_of = self . infcx . tcx . predicates_of ( * did) ;
479+ let bounds = predicates_of. instantiate ( self . infcx . tcx , substs) ;
478480
479481 let mut found = false ;
480482 for predicate in bounds. predicates {
@@ -502,8 +504,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
502504 diag. help ( & format ! ( "consider replacing `{}` with `{}`" , fr_name, static_str) ) ;
503505 } else {
504506 // Otherwise, we should suggest adding a constraint on the return type.
505- let span = infcx. tcx . def_span ( * did) ;
506- if let Ok ( snippet) = infcx. tcx . sess . source_map ( ) . span_to_snippet ( span) {
507+ let span = self . infcx . tcx . def_span ( * did) ;
508+ if let Ok ( snippet) = self . infcx . tcx . sess . source_map ( ) . span_to_snippet ( span) {
507509 let suggestable_fr_name = if fr_name. was_named ( ) {
508510 fr_name. to_string ( )
509511 } else {
0 commit comments