@@ -16,7 +16,7 @@ use std::fmt::{self, Write};
1616impl NiceRegionError < ' me , ' tcx > {
1717 /// When given a `ConcreteFailure` for a function with arguments containing a named region and
1818 /// an anonymous region, emit a descriptive diagnostic error.
19- pub ( super ) fn try_report_placeholder_conflict ( & self ) -> Option < DiagnosticBuilder < ' me > > {
19+ pub ( super ) fn try_report_placeholder_conflict ( & self ) -> Option < DiagnosticBuilder < ' tcx > > {
2020 match & self . error {
2121 ///////////////////////////////////////////////////////////////////////////
2222 // NB. The ordering of cases in this match is very
@@ -30,157 +30,153 @@ impl NiceRegionError<'me, 'tcx> {
3030 Some ( RegionResolutionError :: SubSupConflict (
3131 vid,
3232 _,
33- SubregionOrigin :: Subtype ( box TypeTrace {
34- cause,
35- values : ValuePairs :: TraitRefs ( ExpectedFound { expected, found } ) ,
36- } ) ,
33+ SubregionOrigin :: Subtype ( box TypeTrace { cause, values } ) ,
3734 sub_placeholder @ ty:: RePlaceholder ( _) ,
3835 _,
3936 sup_placeholder @ ty:: RePlaceholder ( _) ,
40- ) ) if expected . def_id == found . def_id => Some ( self . try_report_placeholders_trait (
37+ ) ) => self . try_report_trait_placeholder_mismatch (
4138 Some ( self . tcx ( ) . mk_region ( ty:: ReVar ( * vid) ) ) ,
4239 cause,
4340 Some ( sub_placeholder) ,
4441 Some ( sup_placeholder) ,
45- expected. def_id ,
46- expected. substs ,
47- found. substs ,
48- ) ) ,
42+ values,
43+ ) ,
4944
5045 Some ( RegionResolutionError :: SubSupConflict (
5146 vid,
5247 _,
53- SubregionOrigin :: Subtype ( box TypeTrace {
54- cause,
55- values : ValuePairs :: TraitRefs ( ExpectedFound { expected, found } ) ,
56- } ) ,
48+ SubregionOrigin :: Subtype ( box TypeTrace { cause, values } ) ,
5749 sub_placeholder @ ty:: RePlaceholder ( _) ,
5850 _,
5951 _,
60- ) ) if expected . def_id == found . def_id => Some ( self . try_report_placeholders_trait (
52+ ) ) => self . try_report_trait_placeholder_mismatch (
6153 Some ( self . tcx ( ) . mk_region ( ty:: ReVar ( * vid) ) ) ,
6254 cause,
6355 Some ( sub_placeholder) ,
6456 None ,
65- expected. def_id ,
66- expected. substs ,
67- found. substs ,
68- ) ) ,
57+ values,
58+ ) ,
6959
7060 Some ( RegionResolutionError :: SubSupConflict (
7161 vid,
7262 _,
73- SubregionOrigin :: Subtype ( box TypeTrace {
74- cause,
75- values : ValuePairs :: TraitRefs ( ExpectedFound { expected, found } ) ,
76- } ) ,
63+ SubregionOrigin :: Subtype ( box TypeTrace { cause, values } ) ,
7764 _,
7865 _,
7966 sup_placeholder @ ty:: RePlaceholder ( _) ,
80- ) ) if expected . def_id == found . def_id => Some ( self . try_report_placeholders_trait (
67+ ) ) => self . try_report_trait_placeholder_mismatch (
8168 Some ( self . tcx ( ) . mk_region ( ty:: ReVar ( * vid) ) ) ,
8269 cause,
8370 None ,
8471 Some ( * sup_placeholder) ,
85- expected. def_id ,
86- expected. substs ,
87- found. substs ,
88- ) ) ,
72+ values,
73+ ) ,
8974
9075 Some ( RegionResolutionError :: SubSupConflict (
9176 vid,
9277 _,
9378 _,
9479 _,
95- SubregionOrigin :: Subtype ( box TypeTrace {
96- cause,
97- values : ValuePairs :: TraitRefs ( ExpectedFound { expected, found } ) ,
98- } ) ,
80+ SubregionOrigin :: Subtype ( box TypeTrace { cause, values } ) ,
9981 sup_placeholder @ ty:: RePlaceholder ( _) ,
100- ) ) if expected . def_id == found . def_id => Some ( self . try_report_placeholders_trait (
82+ ) ) => self . try_report_trait_placeholder_mismatch (
10183 Some ( self . tcx ( ) . mk_region ( ty:: ReVar ( * vid) ) ) ,
10284 cause,
10385 None ,
10486 Some ( * sup_placeholder) ,
105- expected. def_id ,
106- expected. substs ,
107- found. substs ,
108- ) ) ,
87+ values,
88+ ) ,
10989
11090 Some ( RegionResolutionError :: UpperBoundUniverseConflict (
11191 vid,
11292 _,
11393 _,
114- SubregionOrigin :: Subtype ( box TypeTrace {
115- cause,
116- values : ValuePairs :: TraitRefs ( ExpectedFound { expected, found } ) ,
117- } ) ,
94+ SubregionOrigin :: Subtype ( box TypeTrace { cause, values } ) ,
11895 sup_placeholder @ ty:: RePlaceholder ( _) ,
119- ) ) if expected . def_id == found . def_id => Some ( self . try_report_placeholders_trait (
96+ ) ) => self . try_report_trait_placeholder_mismatch (
12097 Some ( self . tcx ( ) . mk_region ( ty:: ReVar ( * vid) ) ) ,
12198 cause,
12299 None ,
123100 Some ( * sup_placeholder) ,
124- expected. def_id ,
125- expected. substs ,
126- found. substs ,
127- ) ) ,
101+ values,
102+ ) ,
128103
129104 Some ( RegionResolutionError :: ConcreteFailure (
130- SubregionOrigin :: Subtype ( box TypeTrace {
131- cause,
132- values : ValuePairs :: TraitRefs ( ExpectedFound { expected, found } ) ,
133- } ) ,
105+ SubregionOrigin :: Subtype ( box TypeTrace { cause, values } ) ,
134106 sub_region @ ty:: RePlaceholder ( _) ,
135107 sup_region @ ty:: RePlaceholder ( _) ,
136- ) ) if expected . def_id == found . def_id => Some ( self . try_report_placeholders_trait (
108+ ) ) => self . try_report_trait_placeholder_mismatch (
137109 None ,
138110 cause,
139111 Some ( * sub_region) ,
140112 Some ( * sup_region) ,
141- expected. def_id ,
142- expected. substs ,
143- found. substs ,
144- ) ) ,
113+ values,
114+ ) ,
145115
146116 Some ( RegionResolutionError :: ConcreteFailure (
147- SubregionOrigin :: Subtype ( box TypeTrace {
148- cause,
149- values : ValuePairs :: TraitRefs ( ExpectedFound { expected, found } ) ,
150- } ) ,
117+ SubregionOrigin :: Subtype ( box TypeTrace { cause, values } ) ,
151118 sub_region @ ty:: RePlaceholder ( _) ,
152119 sup_region,
153- ) ) if expected . def_id == found . def_id => Some ( self . try_report_placeholders_trait (
154- Some ( sup_region) ,
120+ ) ) => self . try_report_trait_placeholder_mismatch (
121+ ( !sup_region . has_name ( ) ) . then_some ( sup_region) ,
155122 cause,
156- Some ( * sub_region) ,
123+ Some ( sub_region) ,
157124 None ,
158- expected. def_id ,
159- expected. substs ,
160- found. substs ,
161- ) ) ,
125+ values,
126+ ) ,
162127
163128 Some ( RegionResolutionError :: ConcreteFailure (
164- SubregionOrigin :: Subtype ( box TypeTrace {
165- cause,
166- values : ValuePairs :: TraitRefs ( ExpectedFound { expected, found } ) ,
167- } ) ,
129+ SubregionOrigin :: Subtype ( box TypeTrace { cause, values } ) ,
168130 sub_region,
169131 sup_region @ ty:: RePlaceholder ( _) ,
170- ) ) if expected . def_id == found . def_id => Some ( self . try_report_placeholders_trait (
171- Some ( sub_region) ,
132+ ) ) => self . try_report_trait_placeholder_mismatch (
133+ ( !sub_region . has_name ( ) ) . then_some ( sub_region) ,
172134 cause,
173135 None ,
174- Some ( * sup_region) ,
175- expected. def_id ,
176- expected. substs ,
177- found. substs ,
178- ) ) ,
136+ Some ( sup_region) ,
137+ values,
138+ ) ,
179139
180140 _ => None ,
181141 }
182142 }
183143
144+ fn try_report_trait_placeholder_mismatch (
145+ & self ,
146+ vid : Option < ty:: Region < ' tcx > > ,
147+ cause : & ObligationCause < ' tcx > ,
148+ sub_placeholder : Option < ty:: Region < ' tcx > > ,
149+ sup_placeholder : Option < ty:: Region < ' tcx > > ,
150+ value_pairs : & ValuePairs < ' tcx > ,
151+ ) -> Option < DiagnosticBuilder < ' tcx > > {
152+ let ( expected_substs, found_substs, trait_def_id) = match value_pairs {
153+ ValuePairs :: TraitRefs ( ExpectedFound { expected, found } )
154+ if expected. def_id == found. def_id =>
155+ {
156+ ( expected. substs , found. substs , expected. def_id )
157+ }
158+ ValuePairs :: PolyTraitRefs ( ExpectedFound { expected, found } )
159+ if expected. def_id ( ) == found. def_id ( ) =>
160+ {
161+ // It's possible that the placeholders come from a binder
162+ // outside of this value pair. Use `no_bound_vars` as a
163+ // simple heuristic for that.
164+ ( expected. no_bound_vars ( ) ?. substs , found. no_bound_vars ( ) ?. substs , expected. def_id ( ) )
165+ }
166+ _ => return None ,
167+ } ;
168+
169+ Some ( self . report_trait_placeholder_mismatch (
170+ vid,
171+ cause,
172+ sub_placeholder,
173+ sup_placeholder,
174+ trait_def_id,
175+ expected_substs,
176+ found_substs,
177+ ) )
178+ }
179+
184180 // error[E0308]: implementation of `Foo` does not apply to enough lifetimes
185181 // --> /home/nmatsakis/tmp/foo.rs:12:5
186182 // |
@@ -190,7 +186,8 @@ impl NiceRegionError<'me, 'tcx> {
190186 // = note: Due to a where-clause on the function `all`,
191187 // = note: `T` must implement `...` for any two lifetimes `'1` and `'2`.
192188 // = note: However, the type `T` only implements `...` for some specific lifetime `'2`.
193- fn try_report_placeholders_trait (
189+ #[ instrument( level = "debug" , skip( self ) ) ]
190+ fn report_trait_placeholder_mismatch (
194191 & self ,
195192 vid : Option < ty:: Region < ' tcx > > ,
196193 cause : & ObligationCause < ' tcx > ,
@@ -199,28 +196,13 @@ impl NiceRegionError<'me, 'tcx> {
199196 trait_def_id : DefId ,
200197 expected_substs : SubstsRef < ' tcx > ,
201198 actual_substs : SubstsRef < ' tcx > ,
202- ) -> DiagnosticBuilder < ' me > {
203- debug ! (
204- "try_report_placeholders_trait(\
205- vid={:?}, \
206- sub_placeholder={:?}, \
207- sup_placeholder={:?}, \
208- trait_def_id={:?}, \
209- expected_substs={:?}, \
210- actual_substs={:?})",
211- vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs
212- ) ;
213-
199+ ) -> DiagnosticBuilder < ' tcx > {
214200 let span = cause. span ( self . tcx ( ) ) ;
215201 let msg = format ! (
216202 "implementation of `{}` is not general enough" ,
217203 self . tcx( ) . def_path_str( trait_def_id) ,
218204 ) ;
219205 let mut err = self . tcx ( ) . sess . struct_span_err ( span, & msg) ;
220- err. span_label (
221- self . tcx ( ) . def_span ( trait_def_id) ,
222- format ! ( "trait `{}` defined here" , self . tcx( ) . def_path_str( trait_def_id) ) ,
223- ) ;
224206
225207 let leading_ellipsis = if let ObligationCauseCode :: ItemObligation ( def_id) = cause. code {
226208 err. span_label ( span, "doesn't satisfy where-clause" ) ;
@@ -285,17 +267,13 @@ impl NiceRegionError<'me, 'tcx> {
285267
286268 let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
287269
288- debug ! ( "try_report_placeholders_trait: actual_has_vid={:?}" , actual_has_vid) ;
289- debug ! ( "try_report_placeholders_trait: expected_has_vid={:?}" , expected_has_vid) ;
290- debug ! ( "try_report_placeholders_trait: has_sub={:?}" , has_sub) ;
291- debug ! ( "try_report_placeholders_trait: has_sup={:?}" , has_sup) ;
292270 debug ! (
293- "try_report_placeholders_trait: actual_self_ty_has_vid={:?}" ,
294- actual_self_ty_has_vid
295- ) ;
296- debug ! (
297- "try_report_placeholders_trait: expected_self_ty_has_vid={:?}" ,
298- expected_self_ty_has_vid
271+ ?actual_has_vid ,
272+ ?expected_has_vid ,
273+ ?has_sub ,
274+ ?has_sup ,
275+ ?actual_self_ty_has_vid ,
276+ ? expected_self_ty_has_vid,
299277 ) ;
300278
301279 self . explain_actual_impl_that_was_found (
@@ -388,6 +366,8 @@ impl NiceRegionError<'me, 'tcx> {
388366 value : trait_ref,
389367 } ;
390368
369+ let same_self_type = actual_trait_ref. self_ty ( ) == expected_trait_ref. self_ty ( ) ;
370+
391371 let mut expected_trait_ref = highlight_trait_ref ( expected_trait_ref) ;
392372 expected_trait_ref. highlight . maybe_highlighting_region ( sub_placeholder, has_sub) ;
393373 expected_trait_ref. highlight . maybe_highlighting_region ( sup_placeholder, has_sup) ;
@@ -403,7 +383,42 @@ impl NiceRegionError<'me, 'tcx> {
403383 }
404384 } ;
405385
406- let mut note = if passive_voice {
386+ let mut note = if same_self_type {
387+ let mut self_ty = expected_trait_ref. map ( |tr| tr. self_ty ( ) ) ;
388+ self_ty. highlight . maybe_highlighting_region ( vid, actual_has_vid) ;
389+
390+ if self_ty. value . is_closure ( )
391+ && self
392+ . tcx ( )
393+ . fn_trait_kind_from_lang_item ( expected_trait_ref. value . def_id )
394+ . is_some ( )
395+ {
396+ let closure_sig = self_ty. map ( |closure| {
397+ if let ty:: Closure ( _, substs) = closure. kind ( ) {
398+ self . tcx ( ) . signature_unclosure (
399+ substs. as_closure ( ) . sig ( ) ,
400+ rustc_hir:: Unsafety :: Normal ,
401+ )
402+ } else {
403+ bug ! ( "type is not longer closure" ) ;
404+ }
405+ } ) ;
406+
407+ format ! (
408+ "{}closure with signature `{}` must implement `{}`" ,
409+ if leading_ellipsis { "..." } else { "" } ,
410+ closure_sig,
411+ expected_trait_ref. map( |tr| tr. print_only_trait_path( ) ) ,
412+ )
413+ } else {
414+ format ! (
415+ "{}`{}` must implement `{}`" ,
416+ if leading_ellipsis { "..." } else { "" } ,
417+ self_ty,
418+ expected_trait_ref. map( |tr| tr. print_only_trait_path( ) ) ,
419+ )
420+ }
421+ } else if passive_voice {
407422 format ! (
408423 "{}`{}` would have to be implemented for the type `{}`" ,
409424 if leading_ellipsis { "..." } else { "" } ,
@@ -449,7 +464,12 @@ impl NiceRegionError<'me, 'tcx> {
449464 None => true ,
450465 } ;
451466
452- let mut note = if passive_voice {
467+ let mut note = if same_self_type {
468+ format ! (
469+ "...but it actually implements `{}`" ,
470+ actual_trait_ref. map( |tr| tr. print_only_trait_path( ) ) ,
471+ )
472+ } else if passive_voice {
453473 format ! (
454474 "...but `{}` is actually implemented for the type `{}`" ,
455475 actual_trait_ref. map( |tr| tr. print_only_trait_path( ) ) ,
0 commit comments