@@ -137,6 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
137
137
let is_automatically_derived = is_automatically_derived ( & * item. attrs ) ;
138
138
139
139
check_hash_peq ( cx, item. span , trait_ref, ty, is_automatically_derived) ;
140
+ check_ord_pord ( cx, item. span , trait_ref, ty, is_automatically_derived) ;
140
141
141
142
if is_automatically_derived {
142
143
check_unsafe_derive_deserialize ( cx, item, trait_ref, ty) ;
@@ -201,6 +202,60 @@ fn check_hash_peq<'tcx>(
201
202
}
202
203
}
203
204
205
+ /// Implementation of the `DERIVE_ORD_XOR_PARTIAL_ORD` lint.
206
+ fn check_ord_pord < ' tcx > (
207
+ cx : & LateContext < ' tcx > ,
208
+ span : Span ,
209
+ trait_ref : & TraitRef < ' _ > ,
210
+ ty : Ty < ' tcx > ,
211
+ ord_is_automatically_derived : bool ,
212
+ ) {
213
+ if_chain ! {
214
+ if match_path( & trait_ref. path, & paths:: ORD ) ;
215
+ if let Some ( pord_trait_def_id) = cx. tcx. lang_items( ) . partial_ord_trait( ) ;
216
+ if let Some ( def_id) = & trait_ref. trait_def_id( ) ;
217
+ if !def_id. is_local( ) ;
218
+ then {
219
+ // Look for the PartialOrd implementations for `ty`
220
+ cx. tcx. for_each_relevant_impl( pord_trait_def_id, ty, |impl_id| {
221
+ let pord_is_automatically_derived = is_automatically_derived( & cx. tcx. get_attrs( impl_id) ) ;
222
+
223
+ if pord_is_automatically_derived == ord_is_automatically_derived {
224
+ return ;
225
+ }
226
+
227
+ let trait_ref = cx. tcx. impl_trait_ref( impl_id) . expect( "must be a trait implementation" ) ;
228
+
229
+ // Only care about `impl PartialOrd<Foo> for Foo`
230
+ // For `impl PartialOrd<B> for A, input_types is [A, B]
231
+ if trait_ref. substs. type_at( 1 ) == ty {
232
+ let mess = if pord_is_automatically_derived {
233
+ "you are implementing `Ord` explicitly but have derived `PartialOrd`"
234
+ } else {
235
+ "you are deriving `Ord` but have implemented `PartialOrd` explicitly"
236
+ } ;
237
+
238
+ span_lint_and_then(
239
+ cx,
240
+ DERIVE_ORD_XOR_PARTIAL_ORD ,
241
+ span,
242
+ mess,
243
+ |diag| {
244
+ if let Some ( local_def_id) = impl_id. as_local( ) {
245
+ let hir_id = cx. tcx. hir( ) . as_local_hir_id( local_def_id) ;
246
+ diag. span_note(
247
+ cx. tcx. hir( ) . span( hir_id) ,
248
+ "`PartialOrd` implemented here"
249
+ ) ;
250
+ }
251
+ }
252
+ ) ;
253
+ }
254
+ } ) ;
255
+ }
256
+ }
257
+ }
258
+
204
259
/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.
205
260
fn check_copy_clone < ' tcx > ( cx : & LateContext < ' tcx > , item : & Item < ' _ > , trait_ref : & TraitRef < ' _ > , ty : Ty < ' tcx > ) {
206
261
if match_path ( & trait_ref. path , & paths:: CLONE_TRAIT ) {
0 commit comments