@@ -137,6 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
137137 let is_automatically_derived = is_automatically_derived ( & * item. attrs ) ;
138138
139139 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) ;
140141
141142 if is_automatically_derived {
142143 check_unsafe_derive_deserialize ( cx, item, trait_ref, ty) ;
@@ -201,6 +202,60 @@ fn check_hash_peq<'tcx>(
201202 }
202203}
203204
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+
204259/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.
205260fn check_copy_clone < ' tcx > ( cx : & LateContext < ' tcx > , item : & Item < ' _ > , trait_ref : & TraitRef < ' _ > , ty : Ty < ' tcx > ) {
206261 if match_path ( & trait_ref. path , & paths:: CLONE_TRAIT ) {
0 commit comments