@@ -9,10 +9,13 @@ use rustc_hir as hir;
99use rustc_hir:: def:: Res ;
1010use rustc_hir:: def_id:: DefId ;
1111use rustc_hir:: intravisit:: Visitor ;
12- use rustc_middle:: ty:: error:: ExpectedFound ;
13- use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
12+ use rustc_middle:: ty:: print:: RegionHighlightMode ;
13+ use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFoldable , TypeVisitor } ;
14+
1415use rustc_span:: { MultiSpan , Span , Symbol } ;
1516
17+ use std:: ops:: ControlFlow ;
18+
1619impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
1720 /// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
1821 pub ( super ) fn try_report_impl_not_conforming_to_trait ( & self ) -> Option < ErrorReported > {
@@ -69,6 +72,47 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
6972 . tcx ( )
7073 . sess
7174 . struct_span_err ( sp, "`impl` item signature doesn't match `trait` item signature" ) ;
75+
76+ // Mark all unnamed regions in the type with a number.
77+ // This diagnostic is called in response to lifetime errors, so be informative.
78+ struct HighlightBuilder < ' tcx > {
79+ highlight : RegionHighlightMode ,
80+ tcx : TyCtxt < ' tcx > ,
81+ counter : usize ,
82+ }
83+
84+ impl HighlightBuilder < ' tcx > {
85+ fn build ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> RegionHighlightMode {
86+ let mut builder =
87+ HighlightBuilder { highlight : RegionHighlightMode :: default ( ) , counter : 1 , tcx } ;
88+ builder. visit_ty ( ty) ;
89+ builder. highlight
90+ }
91+ }
92+
93+ impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for HighlightBuilder < ' tcx > {
94+ fn tcx_for_anon_const_substs ( & self ) -> Option < TyCtxt < ' tcx > > {
95+ Some ( self . tcx )
96+ }
97+
98+ fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
99+ if !r. has_name ( ) && self . counter <= 3 {
100+ self . highlight . highlighting_region ( r, self . counter ) ;
101+ self . counter += 1 ;
102+ }
103+ r. super_visit_with ( self )
104+ }
105+ }
106+
107+ let expected_highlight = HighlightBuilder :: build ( self . tcx ( ) , expected) ;
108+ let expected = self
109+ . infcx
110+ . extract_inference_diagnostics_data ( expected. into ( ) , Some ( expected_highlight) )
111+ . name ;
112+ let found_highlight = HighlightBuilder :: build ( self . tcx ( ) , found) ;
113+ let found =
114+ self . infcx . extract_inference_diagnostics_data ( found. into ( ) , Some ( found_highlight) ) . name ;
115+
72116 err. span_label ( sp, & format ! ( "found `{}`" , found) ) ;
73117 err. span_label ( trait_sp, & format ! ( "expected `{}`" , expected) ) ;
74118
@@ -96,15 +140,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
96140 ) ;
97141 }
98142
99- if let Some ( ( expected, found) ) =
100- self . infcx . expected_found_str_ty ( ExpectedFound { expected, found } )
101- {
102- // Highlighted the differences when showing the "expected/found" note.
103- err. note_expected_found ( & "" , expected, & "" , found) ;
104- } else {
105- // This fallback shouldn't be necessary, but let's keep it in just in case.
106- err. note ( & format ! ( "expected `{}`\n found `{}`" , expected, found) ) ;
107- }
143+ err. note ( & format ! ( "expected `{}`\n found `{}`" , expected, found) ) ;
144+
108145 err. span_help (
109146 type_param_span,
110147 "the lifetime requirements from the `impl` do not correspond to the requirements in \
0 commit comments