@@ -161,66 +161,80 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
161161
162162 note_obligation_cause ( infcx, obligation) ;
163163 }
164- SelectionError :: Unimplemented => {
165- match obligation. predicate {
166- ty:: Predicate :: Trait ( ref trait_predicate) => {
167- let trait_predicate =
168- infcx. resolve_type_vars_if_possible ( trait_predicate) ;
169- if !trait_predicate. references_error ( ) {
170- let trait_ref = trait_predicate. to_poly_trait_ref ( ) ;
171- infcx. tcx . sess . span_err (
172- obligation. cause . span ,
173- format ! (
174- "the trait `{}` is not implemented for the type `{}`" ,
175- trait_ref. user_string( infcx. tcx) ,
176- trait_ref. self_ty( ) . user_string( infcx. tcx) ) . as_slice ( ) ) ;
177- // Check if it has a custom "#[rustc_on_unimplemented]" error message,
178- // report with that message if it does
179- let custom_note = report_on_unimplemented ( infcx, & * trait_ref. 0 ,
180- obligation. cause . span ) ;
181- if let Some ( s) = custom_note {
182- infcx. tcx . sess . span_note ( obligation. cause . span ,
183- s. as_slice ( ) ) ;
184- }
185- }
186- }
187164
188- ty:: Predicate :: Equate ( ref predicate) => {
189- let predicate = infcx. resolve_type_vars_if_possible ( predicate) ;
190- let err = infcx. equality_predicate ( obligation. cause . span ,
191- & predicate) . unwrap_err ( ) ;
165+ SelectionError :: Unimplemented => {
166+ match & obligation. cause . code {
167+ & ObligationCauseCode :: CompareImplMethodObligation => {
192168 infcx. tcx . sess . span_err (
193169 obligation. cause . span ,
194170 format ! (
195- "the requirement `{}` is not satisfied (`{}`)" ,
196- predicate . user_string ( infcx . tcx ) ,
197- ty :: type_err_to_str ( infcx. tcx, & err ) ) . as_slice ( ) ) ;
171+ "the requirement `{}` appears on the impl \
172+ method but not on the corresponding trait method" ,
173+ obligation . predicate . user_string ( infcx. tcx) ) . as_slice ( ) ) ;
198174 }
175+ _ => {
176+ match obligation. predicate {
177+ ty:: Predicate :: Trait ( ref trait_predicate) => {
178+ let trait_predicate =
179+ infcx. resolve_type_vars_if_possible ( trait_predicate) ;
199180
200- ty:: Predicate :: RegionOutlives ( ref predicate) => {
201- let predicate = infcx. resolve_type_vars_if_possible ( predicate) ;
202- let err = infcx. region_outlives_predicate ( obligation. cause . span ,
203- & predicate) . unwrap_err ( ) ;
204- infcx. tcx . sess . span_err (
205- obligation. cause . span ,
206- format ! (
207- "the requirement `{}` is not satisfied (`{}`)" ,
208- predicate. user_string( infcx. tcx) ,
209- ty:: type_err_to_str( infcx. tcx, & err) ) . as_slice ( ) ) ;
210- }
181+ if !trait_predicate. references_error ( ) {
182+ let trait_ref = trait_predicate. to_poly_trait_ref ( ) ;
183+ infcx. tcx . sess . span_err (
184+ obligation. cause . span ,
185+ format ! (
186+ "the trait `{}` is not implemented for the type `{}`" ,
187+ trait_ref. user_string( infcx. tcx) ,
188+ trait_ref. self_ty( ) . user_string( infcx. tcx) ) . as_slice ( ) ) ;
189+ // Check if it has a custom "#[rustc_on_unimplemented]"
190+ // error message, report with that message if it does
191+ let custom_note = report_on_unimplemented ( infcx, & * trait_ref. 0 ,
192+ obligation. cause . span ) ;
193+ if let Some ( s) = custom_note {
194+ infcx. tcx . sess . span_note ( obligation. cause . span ,
195+ s. as_slice ( ) ) ;
196+ }
197+ }
198+ }
211199
212- ty:: Predicate :: Projection ( ..) |
213- ty:: Predicate :: TypeOutlives ( ..) => {
214- let predicate =
215- infcx. resolve_type_vars_if_possible ( & obligation. predicate ) ;
216- infcx. tcx . sess . span_err (
217- obligation. cause . span ,
218- format ! (
219- "the requirement `{}` is not satisfied" ,
220- predicate. user_string( infcx. tcx) ) . as_slice ( ) ) ;
200+ ty:: Predicate :: Equate ( ref predicate) => {
201+ let predicate = infcx. resolve_type_vars_if_possible ( predicate) ;
202+ let err = infcx. equality_predicate ( obligation. cause . span ,
203+ & predicate) . unwrap_err ( ) ;
204+ infcx. tcx . sess . span_err (
205+ obligation. cause . span ,
206+ format ! (
207+ "the requirement `{}` is not satisfied (`{}`)" ,
208+ predicate. user_string( infcx. tcx) ,
209+ ty:: type_err_to_str( infcx. tcx, & err) ) . as_slice ( ) ) ;
210+ }
211+
212+ ty:: Predicate :: RegionOutlives ( ref predicate) => {
213+ let predicate = infcx. resolve_type_vars_if_possible ( predicate) ;
214+ let err = infcx. region_outlives_predicate ( obligation. cause . span ,
215+ & predicate) . unwrap_err ( ) ;
216+ infcx. tcx . sess . span_err (
217+ obligation. cause . span ,
218+ format ! (
219+ "the requirement `{}` is not satisfied (`{}`)" ,
220+ predicate. user_string( infcx. tcx) ,
221+ ty:: type_err_to_str( infcx. tcx, & err) ) . as_slice ( ) ) ;
222+ }
223+
224+ ty:: Predicate :: Projection ( ..) | ty:: Predicate :: TypeOutlives ( ..) => {
225+ let predicate =
226+ infcx. resolve_type_vars_if_possible ( & obligation. predicate ) ;
227+ infcx. tcx . sess . span_err (
228+ obligation. cause . span ,
229+ format ! (
230+ "the requirement `{}` is not satisfied" ,
231+ predicate. user_string( infcx. tcx) ) . as_slice ( ) ) ;
232+ }
233+ }
221234 }
222235 }
223236 }
237+
224238 OutputTypeParameterMismatch ( ref expected_trait_ref, ref actual_trait_ref, ref e) => {
225239 let expected_trait_ref = infcx. resolve_type_vars_if_possible ( & * expected_trait_ref) ;
226240 let actual_trait_ref = infcx. resolve_type_vars_if_possible ( & * actual_trait_ref) ;
@@ -229,12 +243,12 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
229243 obligation. cause . span ,
230244 format ! (
231245 "type mismatch: the type `{}` implements the trait `{}`, \
232- but the trait `{}` is required ({})",
246+ but the trait `{}` is required ({})",
233247 expected_trait_ref. self_ty( ) . user_string( infcx. tcx) ,
234248 expected_trait_ref. user_string( infcx. tcx) ,
235249 actual_trait_ref. user_string( infcx. tcx) ,
236250 ty:: type_err_to_str( infcx. tcx, e) ) . as_slice ( ) ) ;
237- note_obligation_cause ( infcx, obligation) ;
251+ note_obligation_cause ( infcx, obligation) ;
238252 }
239253 }
240254 }
@@ -330,7 +344,7 @@ fn note_obligation_cause<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
330344}
331345
332346fn note_obligation_cause_code < ' a , ' tcx > ( infcx : & InferCtxt < ' a , ' tcx > ,
333- _predicate : & ty:: Predicate < ' tcx > ,
347+ predicate : & ty:: Predicate < ' tcx > ,
334348 cause_span : Span ,
335349 cause_code : & ObligationCauseCode < ' tcx > )
336350{
@@ -417,6 +431,12 @@ fn note_obligation_cause_code<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
417431 let parent_predicate = parent_trait_ref. as_predicate ( ) ;
418432 note_obligation_cause_code ( infcx, & parent_predicate, cause_span, & * data. parent_code ) ;
419433 }
434+ ObligationCauseCode :: CompareImplMethodObligation => {
435+ span_note ! ( tcx. sess, cause_span,
436+ "the requirement `{}` appears on the impl method\
437+ but not on the corresponding trait method",
438+ predicate. user_string( infcx. tcx) ) ;
439+ }
420440 }
421441}
422442
0 commit comments