22
33use crate :: infer:: error_reporting:: nice_region_error:: NiceRegionError ;
44use crate :: infer:: lexical_region_resolve:: RegionResolutionError ;
5- use crate :: infer:: { Subtype , ValuePairs } ;
5+ use crate :: infer:: { SubregionOrigin , Subtype , ValuePairs } ;
66use crate :: traits:: ObligationCauseCode :: CompareImplMethodObligation ;
77use rustc_errors:: ErrorReported ;
88use rustc_hir as hir;
@@ -11,44 +11,53 @@ use rustc_hir::def_id::DefId;
1111use rustc_hir:: intravisit:: Visitor ;
1212use rustc_middle:: ty:: error:: ExpectedFound ;
1313use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
14- use rustc_span:: { MultiSpan , Span } ;
14+ use rustc_span:: { MultiSpan , Span , Symbol } ;
1515
1616impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
1717 /// Print the error message for lifetime errors when the `impl` doesn't conform to the `trait`.
1818 pub ( super ) fn try_report_impl_not_conforming_to_trait ( & self ) -> Option < ErrorReported > {
19- if let Some ( ref error) = self . error {
20- debug ! ( "try_report_impl_not_conforming_to_trait {:?}" , error) ;
21- if let RegionResolutionError :: SubSupConflict (
22- _,
23- var_origin,
24- sub_origin,
25- _sub,
26- sup_origin,
27- _sup,
28- ) = error. clone ( )
29- {
30- if let ( & Subtype ( ref sup_trace) , & Subtype ( ref sub_trace) ) =
31- ( & sup_origin, & sub_origin)
19+ let error = self . error . as_ref ( ) ?;
20+ debug ! ( "try_report_impl_not_conforming_to_trait {:?}" , error) ;
21+ if let RegionResolutionError :: SubSupConflict (
22+ _,
23+ var_origin,
24+ sub_origin,
25+ _sub,
26+ sup_origin,
27+ _sup,
28+ ) = error. clone ( )
29+ {
30+ if let ( & Subtype ( ref sup_trace) , & Subtype ( ref sub_trace) ) = ( & sup_origin, & sub_origin) {
31+ if let (
32+ ValuePairs :: Types ( sub_expected_found) ,
33+ ValuePairs :: Types ( sup_expected_found) ,
34+ CompareImplMethodObligation { trait_item_def_id, .. } ,
35+ ) = ( & sub_trace. values , & sup_trace. values , & sub_trace. cause . code )
3236 {
33- if let (
34- ValuePairs :: Types ( sub_expected_found) ,
35- ValuePairs :: Types ( sup_expected_found) ,
36- CompareImplMethodObligation { trait_item_def_id, .. } ,
37- ) = ( & sub_trace. values , & sup_trace. values , & sub_trace. cause . code )
38- {
39- if sup_expected_found == sub_expected_found {
40- self . emit_err (
41- var_origin. span ( ) ,
42- sub_expected_found. expected ,
43- sub_expected_found. found ,
44- * trait_item_def_id,
45- ) ;
46- return Some ( ErrorReported ) ;
47- }
37+ if sup_expected_found == sub_expected_found {
38+ self . emit_err (
39+ var_origin. span ( ) ,
40+ sub_expected_found. expected ,
41+ sub_expected_found. found ,
42+ * trait_item_def_id,
43+ ) ;
44+ return Some ( ErrorReported ) ;
4845 }
4946 }
5047 }
5148 }
49+ if let RegionResolutionError :: ConcreteFailure ( origin, _, _) = error. clone ( ) {
50+ if let SubregionOrigin :: CompareImplTypeObligation {
51+ span,
52+ item_name,
53+ impl_item_def_id,
54+ trait_item_def_id,
55+ } = origin
56+ {
57+ self . emit_associated_type_err ( span, item_name, impl_item_def_id, trait_item_def_id) ;
58+ return Some ( ErrorReported ) ;
59+ }
60+ }
5261 None
5362 }
5463
@@ -107,6 +116,25 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
107116 }
108117 err. emit ( ) ;
109118 }
119+
120+ fn emit_associated_type_err (
121+ & self ,
122+ span : Span ,
123+ item_name : Symbol ,
124+ impl_item_def_id : DefId ,
125+ trait_item_def_id : DefId ,
126+ ) {
127+ let impl_sp = self . tcx ( ) . def_span ( impl_item_def_id) ;
128+ let trait_sp = self . tcx ( ) . def_span ( trait_item_def_id) ;
129+ let mut err = self
130+ . tcx ( )
131+ . sess
132+ . struct_span_err ( span, & format ! ( "`impl` associated type signature for `{}` doesn't match `trait` associated type signature" , item_name) ) ;
133+ err. span_label ( impl_sp, & format ! ( "found" ) ) ;
134+ err. span_label ( trait_sp, & format ! ( "expected" ) ) ;
135+
136+ err. emit ( ) ;
137+ }
110138}
111139
112140struct TypeParamSpanVisitor < ' tcx > {
0 commit comments