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