@@ -27,8 +27,8 @@ use rustc_middle::traits::util::supertraits;
27
27
use rustc_middle:: ty:: fast_reject:: DeepRejectCtxt ;
28
28
use rustc_middle:: ty:: fast_reject:: { simplify_type, TreatParams } ;
29
29
use rustc_middle:: ty:: print:: { with_crate_prefix, with_forced_trimmed_paths} ;
30
+ use rustc_middle:: ty:: IsSuggestable ;
30
31
use rustc_middle:: ty:: { self , GenericArgKind , Ty , TyCtxt , TypeVisitableExt } ;
31
- use rustc_middle:: ty:: { IsSuggestable , ToPolyTraitRef } ;
32
32
use rustc_span:: symbol:: { kw, sym, Ident } ;
33
33
use rustc_span:: Symbol ;
34
34
use rustc_span:: { edit_distance, source_map, ExpnKind , FileName , MacroKind , Span } ;
@@ -2068,7 +2068,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2068
2068
let mut derives = Vec :: < ( String , Span , Symbol ) > :: new ( ) ;
2069
2069
let mut traits = Vec :: new ( ) ;
2070
2070
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
+ } ;
2072
2076
let adt = match trait_pred. self_ty ( ) . ty_adt_def ( ) {
2073
2077
Some ( adt) if adt. did ( ) . is_local ( ) => adt,
2074
2078
_ => continue ,
@@ -2085,22 +2089,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2085
2089
| sym:: Hash
2086
2090
| sym:: Debug => true ,
2087
2091
_ => 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 ,
2088
2106
} ;
2089
2107
if can_derive {
2090
2108
let self_name = trait_pred. self_ty ( ) . to_string ( ) ;
2091
2109
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 ( ) )
2094
2115
{
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) ) ;
2104
2117
}
2105
2118
}
2106
2119
derives. push ( ( self_name, self_span, diagnostic_name) ) ;
0 commit comments