@@ -27,8 +27,8 @@ use rustc_middle::traits::util::supertraits;
2727use rustc_middle:: ty:: fast_reject:: DeepRejectCtxt ;
2828use rustc_middle:: ty:: fast_reject:: { simplify_type, TreatParams } ;
2929use rustc_middle:: ty:: print:: { with_crate_prefix, with_forced_trimmed_paths} ;
30+ use rustc_middle:: ty:: IsSuggestable ;
3031use rustc_middle:: ty:: { self , GenericArgKind , Ty , TyCtxt , TypeVisitableExt } ;
31- use rustc_middle:: ty:: { IsSuggestable , ToPolyTraitRef } ;
3232use rustc_span:: symbol:: { kw, sym, Ident } ;
3333use rustc_span:: Symbol ;
3434use rustc_span:: { edit_distance, source_map, ExpnKind , FileName , MacroKind , Span } ;
@@ -2068,7 +2068,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20682068 let mut derives = Vec :: < ( String , Span , Symbol ) > :: new ( ) ;
20692069 let mut traits = Vec :: new ( ) ;
20702070 for ( pred, _, _) in unsatisfied_predicates {
2071- let ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( trait_pred) ) = pred. kind ( ) . skip_binder ( ) else { continue } ;
2071+ let Some ( ty:: PredicateKind :: Clause ( ty:: Clause :: Trait ( trait_pred) ) ) =
2072+ pred. kind ( ) . no_bound_vars ( )
2073+ else {
2074+ continue
2075+ } ;
20722076 let adt = match trait_pred. self_ty ( ) . ty_adt_def ( ) {
20732077 Some ( adt) if adt. did ( ) . is_local ( ) => adt,
20742078 _ => continue ,
@@ -2085,22 +2089,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20852089 | sym:: Hash
20862090 | sym:: Debug => true ,
20872091 _ => false ,
2092+ } && match trait_pred. trait_ref . substs . as_slice ( ) {
2093+ // Only suggest deriving if lhs == rhs...
2094+ [ lhs, rhs] => {
2095+ if let Some ( lhs) = lhs. as_type ( )
2096+ && let Some ( rhs) = rhs. as_type ( )
2097+ {
2098+ self . can_eq ( self . param_env , lhs, rhs)
2099+ } else {
2100+ false
2101+ }
2102+ } ,
2103+ // Unary ops can always be derived
2104+ [ _] => true ,
2105+ _ => false ,
20882106 } ;
20892107 if can_derive {
20902108 let self_name = trait_pred. self_ty ( ) . to_string ( ) ;
20912109 let self_span = self . tcx . def_span ( adt. did ( ) ) ;
2092- if let Some ( poly_trait_ref) = pred. to_opt_poly_trait_pred ( ) {
2093- for super_trait in supertraits ( self . tcx , poly_trait_ref. to_poly_trait_ref ( ) )
2110+ for super_trait in
2111+ supertraits ( self . tcx , ty:: Binder :: dummy ( trait_pred. trait_ref ) )
2112+ {
2113+ if let Some ( parent_diagnostic_name) =
2114+ self . tcx . get_diagnostic_name ( super_trait. def_id ( ) )
20942115 {
2095- if let Some ( parent_diagnostic_name) =
2096- self . tcx . get_diagnostic_name ( super_trait. def_id ( ) )
2097- {
2098- derives. push ( (
2099- self_name. clone ( ) ,
2100- self_span,
2101- parent_diagnostic_name,
2102- ) ) ;
2103- }
2116+ derives. push ( ( self_name. clone ( ) , self_span, parent_diagnostic_name) ) ;
21042117 }
21052118 }
21062119 derives. push ( ( self_name, self_span, diagnostic_name) ) ;
0 commit comments