1+ use errors:: DiagnosticBuilder ;
12use hir:: def_id:: DefId ;
23use infer:: error_reporting:: nice_region_error:: NiceRegionError ;
34use infer:: lexical_region_resolve:: RegionResolutionError ;
@@ -259,7 +260,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
259260 . tcx ( )
260261 . any_free_region_meets ( & expected_trait_ref. self_ty ( ) , |r| Some ( r) == vid) ;
261262
262- let self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
263+ let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
263264
264265 debug ! (
265266 "try_report_placeholders_trait: actual_has_vid={:?}" ,
@@ -280,6 +281,43 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
280281 expected_self_ty_has_vid
281282 ) ;
282283
284+ self . explain_actual_impl_that_was_found (
285+ & mut err,
286+ sub_placeholder,
287+ sup_placeholder,
288+ has_sub,
289+ has_sup,
290+ expected_trait_ref,
291+ actual_trait_ref,
292+ vid,
293+ expected_has_vid,
294+ actual_has_vid,
295+ any_self_ty_has_vid,
296+ ) ;
297+
298+ err. emit ( ) ;
299+ ErrorReported
300+ }
301+
302+ /// Add notes with details about the expected and actual trait refs, with attention to cases
303+ /// when placeholder regions are involved: either the trait or the self type containing
304+ /// them needs to be mentioned the closest to the placeholders.
305+ /// This makes the error messages read better, however at the cost of some complexity
306+ /// due to the number of combinations we have to deal with.
307+ fn explain_actual_impl_that_was_found (
308+ & self ,
309+ err : & mut DiagnosticBuilder < ' _ > ,
310+ sub_placeholder : Option < ty:: Region < ' tcx > > ,
311+ sup_placeholder : Option < ty:: Region < ' tcx > > ,
312+ has_sub : Option < usize > ,
313+ has_sup : Option < usize > ,
314+ expected_trait_ref : ty:: TraitRef < ' _ > ,
315+ actual_trait_ref : ty:: TraitRef < ' _ > ,
316+ vid : Option < ty:: Region < ' tcx > > ,
317+ expected_has_vid : Option < usize > ,
318+ actual_has_vid : Option < usize > ,
319+ any_self_ty_has_vid : bool ,
320+ ) {
283321 // The weird thing here with the `maybe_highlighting_region` calls and the
284322 // the match inside is meant to be like this:
285323 //
@@ -299,7 +337,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
299337 RegionHighlightMode :: maybe_highlighting_region ( sup_placeholder, has_sup, || {
300338 match ( has_sub, has_sup) {
301339 ( Some ( n1) , Some ( n2) ) => {
302- if self_ty_has_vid {
340+ if any_self_ty_has_vid {
303341 err. note ( & format ! (
304342 "`{}` would have to be implemented for the type `{}`, \
305343 for any two lifetimes `'{}` and `'{}`",
@@ -320,7 +358,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
320358 }
321359 }
322360 ( Some ( n) , _) | ( _, Some ( n) ) => {
323- if self_ty_has_vid {
361+ if any_self_ty_has_vid {
324362 err. note ( & format ! (
325363 "`{}` would have to be implemented for the type `{}`, \
326364 for any lifetime `'{}`",
@@ -350,7 +388,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
350388 n,
351389 ) ) ;
352390 } else {
353- if self_ty_has_vid {
391+ if any_self_ty_has_vid {
354392 err. note ( & format ! (
355393 "`{}` would have to be implemented for the type `{}`" ,
356394 expected_trait_ref,
@@ -375,7 +413,7 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
375413 actual_has_vid,
376414 || match actual_has_vid {
377415 Some ( n) => {
378- if self_ty_has_vid {
416+ if any_self_ty_has_vid {
379417 err. note ( & format ! (
380418 "but `{}` is actually implemented for the type `{}`, \
381419 for the specific lifetime `'{}`",
@@ -402,8 +440,5 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
402440 }
403441 } ,
404442 ) ;
405-
406- err. emit ( ) ;
407- ErrorReported
408443 }
409444}
0 commit comments