@@ -65,22 +65,19 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
65
65
// borrows are safe.
66
66
let blanket_impls = trait_def. blanket_impls . borrow ( ) ;
67
67
let nonblanket_impls = trait_def. nonblanket_impls . borrow ( ) ;
68
- let trait_def_id = trait_def. trait_ref . def_id ;
69
68
70
69
// Conflicts can only occur between a blanket impl and another impl,
71
70
// or between 2 non-blanket impls of the same kind.
72
71
73
72
for ( i, & impl1_def_id) in blanket_impls. iter ( ) . enumerate ( ) {
74
73
for & impl2_def_id in & blanket_impls[ ( i+1 ) ..] {
75
- self . check_if_impls_overlap ( trait_def_id,
76
- impl1_def_id,
74
+ self . check_if_impls_overlap ( impl1_def_id,
77
75
impl2_def_id) ;
78
76
}
79
77
80
78
for v in nonblanket_impls. values ( ) {
81
79
for & impl2_def_id in v {
82
- self . check_if_impls_overlap ( trait_def_id,
83
- impl1_def_id,
80
+ self . check_if_impls_overlap ( impl1_def_id,
84
81
impl2_def_id) ;
85
82
}
86
83
}
@@ -89,8 +86,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
89
86
for impl_group in nonblanket_impls. values ( ) {
90
87
for ( i, & impl1_def_id) in impl_group. iter ( ) . enumerate ( ) {
91
88
for & impl2_def_id in & impl_group[ ( i+1 ) ..] {
92
- self . check_if_impls_overlap ( trait_def_id,
93
- impl1_def_id,
89
+ self . check_if_impls_overlap ( impl1_def_id,
94
90
impl2_def_id) ;
95
91
}
96
92
}
@@ -121,40 +117,47 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
121
117
122
118
123
119
fn check_if_impls_overlap ( & self ,
124
- trait_def_id : DefId ,
125
120
impl1_def_id : DefId ,
126
121
impl2_def_id : DefId )
127
122
{
128
123
if let Some ( ( impl1_def_id, impl2_def_id) ) = self . order_impls (
129
124
impl1_def_id, impl2_def_id)
130
125
{
131
- debug ! ( "check_if_impls_overlap({:?}, {:?}, {:?})" ,
132
- trait_def_id,
126
+ debug ! ( "check_if_impls_overlap({:?}, {:?})" ,
133
127
impl1_def_id,
134
128
impl2_def_id) ;
135
129
136
130
let infcx = infer:: new_infer_ctxt ( self . tcx , & self . tcx . tables , None , false ) ;
137
- if traits:: overlapping_impls ( & infcx, impl1_def_id, impl2_def_id) {
138
- self . report_overlap_error ( trait_def_id , impl1_def_id, impl2_def_id) ;
131
+ if let Some ( trait_ref ) = traits:: overlapping_impls ( & infcx, impl1_def_id, impl2_def_id) {
132
+ self . report_overlap_error ( impl1_def_id, impl2_def_id, trait_ref ) ;
139
133
}
140
134
}
141
135
}
142
136
143
- fn report_overlap_error ( & self , trait_def_id : DefId ,
144
- impl1 : DefId , impl2 : DefId ) {
137
+ fn report_overlap_error ( & self ,
138
+ impl1 : DefId ,
139
+ impl2 : DefId ,
140
+ trait_ref : ty:: TraitRef )
141
+ {
142
+ // only print the Self type if it's concrete; otherwise, it's not adding much information.
143
+ let self_type = {
144
+ trait_ref. substs . self_ty ( ) . and_then ( |ty| {
145
+ if let ty:: TyInfer ( _) = ty. sty {
146
+ None
147
+ } else {
148
+ Some ( format ! ( " for type `{}`" , ty) )
149
+ }
150
+ } ) . unwrap_or ( String :: new ( ) )
151
+ } ;
145
152
146
153
span_err ! ( self . tcx. sess, self . span_of_impl( impl1) , E0119 ,
147
- "conflicting implementations for trait `{}`" ,
148
- self . tcx. item_path_str( trait_def_id) ) ;
149
-
150
- self . report_overlap_note ( impl2) ;
151
- }
152
-
153
- fn report_overlap_note ( & self , impl2 : DefId ) {
154
+ "conflicting implementations of trait `{}`{}:" ,
155
+ trait_ref,
156
+ self_type) ;
154
157
155
158
if impl2. is_local ( ) {
156
159
span_note ! ( self . tcx. sess, self . span_of_impl( impl2) ,
157
- "note conflicting implementation here" ) ;
160
+ "conflicting implementation is here: " ) ;
158
161
} else {
159
162
let cname = self . tcx . sess . cstore . crate_name ( impl2. krate ) ;
160
163
self . tcx . sess . note ( & format ! ( "conflicting implementation in crate `{}`" , cname) ) ;
@@ -180,9 +183,9 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
180
183
let prev_default_impl = self . default_impls . insert ( trait_ref. def_id , item. id ) ;
181
184
match prev_default_impl {
182
185
Some ( prev_id) => {
183
- self . report_overlap_error ( trait_ref . def_id ,
184
- impl_def_id ,
185
- self . tcx . map . local_def_id ( prev_id ) ) ;
186
+ self . report_overlap_error ( impl_def_id ,
187
+ self . tcx . map . local_def_id ( prev_id ) ,
188
+ trait_ref ) ;
186
189
}
187
190
None => { }
188
191
}
0 commit comments