@@ -116,7 +116,7 @@ pub(super) fn note_and_explain_region(
116116 emit_msg_span ( err, prefix, description, span, suffix) ;
117117}
118118
119- pub ( super ) fn note_and_explain_free_region (
119+ fn explain_free_region (
120120 tcx : TyCtxt < ' tcx > ,
121121 err : & mut DiagnosticBuilder < ' _ > ,
122122 prefix : & str ,
@@ -125,7 +125,7 @@ pub(super) fn note_and_explain_free_region(
125125) {
126126 let ( description, span) = msg_span_from_free_region ( tcx, region, None ) ;
127127
128- emit_msg_span ( err, prefix, description, span, suffix) ;
128+ label_msg_span ( err, prefix, description, span, suffix) ;
129129}
130130
131131fn msg_span_from_free_region (
@@ -135,7 +135,8 @@ fn msg_span_from_free_region(
135135) -> ( String , Option < Span > ) {
136136 match * region {
137137 ty:: ReEarlyBound ( _) | ty:: ReFree ( _) => {
138- msg_span_from_early_bound_and_free_regions ( tcx, region)
138+ let ( msg, span) = msg_span_from_early_bound_and_free_regions ( tcx, region) ;
139+ ( msg, Some ( span) )
139140 }
140141 ty:: ReStatic => ( "the static lifetime" . to_owned ( ) , alt_span) ,
141142 ty:: ReEmpty ( ty:: UniverseIndex :: ROOT ) => ( "an empty lifetime" . to_owned ( ) , alt_span) ,
@@ -147,28 +148,20 @@ fn msg_span_from_free_region(
147148fn msg_span_from_early_bound_and_free_regions (
148149 tcx : TyCtxt < ' tcx > ,
149150 region : ty:: Region < ' tcx > ,
150- ) -> ( String , Option < Span > ) {
151+ ) -> ( String , Span ) {
151152 let sm = tcx. sess . source_map ( ) ;
152153
153154 let scope = region. free_region_binding_scope ( tcx) ;
154155 let node = tcx. hir ( ) . local_def_id_to_hir_id ( scope. expect_local ( ) ) ;
155- let tag = match tcx. hir ( ) . find ( node) {
156- Some ( Node :: Block ( _) | Node :: Expr ( _) ) => "body" ,
157- Some ( Node :: Item ( it) ) => item_scope_tag ( & it) ,
158- Some ( Node :: TraitItem ( it) ) => trait_item_scope_tag ( & it) ,
159- Some ( Node :: ImplItem ( it) ) => impl_item_scope_tag ( & it) ,
160- Some ( Node :: ForeignItem ( it) ) => foreign_item_scope_tag ( & it) ,
161- _ => unreachable ! ( ) ,
162- } ;
163- let ( prefix, span) = match * region {
156+ match * region {
164157 ty:: ReEarlyBound ( ref br) => {
165158 let mut sp = sm. guess_head_span ( tcx. hir ( ) . span ( node) ) ;
166159 if let Some ( param) =
167160 tcx. hir ( ) . get_generics ( scope) . and_then ( |generics| generics. get_named ( br. name ) )
168161 {
169162 sp = param. span ;
170163 }
171- ( format ! ( "the lifetime `{}` as defined on " , br. name) , sp)
164+ ( format ! ( "the lifetime `{}` as defined here " , br. name) , sp)
172165 }
173166 ty:: ReFree ( ty:: FreeRegion {
174167 bound_region : ty:: BoundRegionKind :: BrNamed ( _, name) , ..
@@ -179,28 +172,26 @@ fn msg_span_from_early_bound_and_free_regions(
179172 {
180173 sp = param. span ;
181174 }
182- ( format ! ( "the lifetime `{}` as defined on " , name) , sp)
175+ ( format ! ( "the lifetime `{}` as defined here " , name) , sp)
183176 }
184177 ty:: ReFree ( ref fr) => match fr. bound_region {
185178 ty:: BrAnon ( idx) => {
186179 if let Some ( ( ty, _) ) = find_anon_type ( tcx, region, & fr. bound_region ) {
187- ( "the anonymous lifetime defined on " . to_string ( ) , ty. span )
180+ ( "the anonymous lifetime defined here " . to_string ( ) , ty. span )
188181 } else {
189182 (
190- format ! ( "the anonymous lifetime #{} defined on " , idx + 1 ) ,
183+ format ! ( "the anonymous lifetime #{} defined here " , idx + 1 ) ,
191184 tcx. hir ( ) . span ( node) ,
192185 )
193186 }
194187 }
195188 _ => (
196- format ! ( "the lifetime `{}` as defined on " , region) ,
189+ format ! ( "the lifetime `{}` as defined here " , region) ,
197190 sm. guess_head_span ( tcx. hir ( ) . span ( node) ) ,
198191 ) ,
199192 } ,
200193 _ => bug ! ( ) ,
201- } ;
202- let ( msg, opt_span) = explain_span ( tcx, tag, span) ;
203- ( format ! ( "{} {}" , prefix, msg) , opt_span)
194+ }
204195}
205196
206197fn emit_msg_span (
@@ -219,44 +210,22 @@ fn emit_msg_span(
219210 }
220211}
221212
222- fn item_scope_tag ( item : & hir:: Item < ' _ > ) -> & ' static str {
223- match item. kind {
224- hir:: ItemKind :: Impl { .. } => "impl" ,
225- hir:: ItemKind :: Struct ( ..) => "struct" ,
226- hir:: ItemKind :: Union ( ..) => "union" ,
227- hir:: ItemKind :: Enum ( ..) => "enum" ,
228- hir:: ItemKind :: Trait ( ..) => "trait" ,
229- hir:: ItemKind :: Fn ( ..) => "function body" ,
230- _ => "item" ,
231- }
232- }
233-
234- fn trait_item_scope_tag ( item : & hir:: TraitItem < ' _ > ) -> & ' static str {
235- match item. kind {
236- hir:: TraitItemKind :: Fn ( ..) => "method body" ,
237- hir:: TraitItemKind :: Const ( ..) | hir:: TraitItemKind :: Type ( ..) => "associated item" ,
238- }
239- }
240-
241- fn impl_item_scope_tag ( item : & hir:: ImplItem < ' _ > ) -> & ' static str {
242- match item. kind {
243- hir:: ImplItemKind :: Fn ( ..) => "method body" ,
244- hir:: ImplItemKind :: Const ( ..) | hir:: ImplItemKind :: TyAlias ( ..) => "associated item" ,
245- }
246- }
213+ fn label_msg_span (
214+ err : & mut DiagnosticBuilder < ' _ > ,
215+ prefix : & str ,
216+ description : String ,
217+ span : Option < Span > ,
218+ suffix : & str ,
219+ ) {
220+ let message = format ! ( "{}{}{}" , prefix, description, suffix) ;
247221
248- fn foreign_item_scope_tag ( item : & hir :: ForeignItem < ' _ > ) -> & ' static str {
249- match item . kind {
250- hir :: ForeignItemKind :: Fn ( .. ) => "method body" ,
251- hir :: ForeignItemKind :: Static ( .. ) | hir :: ForeignItemKind :: Type => "associated item" ,
222+ if let Some ( span ) = span {
223+ err . span_label ( span , & message ) ;
224+ } else {
225+ err . note ( & message ) ;
252226 }
253227}
254228
255- fn explain_span ( tcx : TyCtxt < ' tcx > , heading : & str , span : Span ) -> ( String , Option < Span > ) {
256- let lo = tcx. sess . source_map ( ) . lookup_char_pos ( span. lo ( ) ) ;
257- ( format ! ( "the {} at {}:{}" , heading, lo. line, lo. col. to_usize( ) + 1 ) , Some ( span) )
258- }
259-
260229pub fn unexpected_hidden_region_diagnostic (
261230 tcx : TyCtxt < ' tcx > ,
262231 span : Span ,
@@ -291,13 +260,25 @@ pub fn unexpected_hidden_region_diagnostic(
291260 //
292261 // (*) if not, the `tainted_by_errors` field would be set to
293262 // `Some(ErrorReported)` in any case, so we wouldn't be here at all.
294- note_and_explain_free_region (
263+ explain_free_region (
295264 tcx,
296265 & mut err,
297266 & format ! ( "hidden type `{}` captures " , hidden_ty) ,
298267 hidden_region,
299268 "" ,
300269 ) ;
270+ if let Some ( reg_info) = tcx. is_suitable_region ( hidden_region) {
271+ let fn_returns = tcx. return_type_impl_or_dyn_traits ( reg_info. def_id ) ;
272+ nice_region_error:: suggest_new_region_bound (
273+ tcx,
274+ & mut err,
275+ fn_returns,
276+ hidden_region. to_string ( ) ,
277+ None ,
278+ format ! ( "captures {}" , hidden_region) ,
279+ None ,
280+ )
281+ }
301282 }
302283 _ => {
303284 // Ugh. This is a painful case: the hidden region is not one
0 commit comments