@@ -159,34 +159,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
159
159
}
160
160
} ) ;
161
161
162
- // double-check there even *is* a semantic `PartialEq` to dispatch to.
163
- //
164
- // (If there isn't, then we can safely issue a hard
165
- // error, because that's never worked, due to compiler
166
- // using `PartialEq::eq` in this scenario in the past.)
167
- //
168
- // Note: To fix rust-lang/rust#65466, one could lift this check
169
- // *before* any structural-match checking, and unconditionally error
170
- // if `PartialEq` is not implemented. However, that breaks stable
171
- // code at the moment, because types like `for <'a> fn(&'a ())` do
172
- // not *yet* implement `PartialEq`. So for now we leave this here.
173
- let ty_is_partial_eq: bool = {
174
- let partial_eq_trait_id =
175
- self . tcx ( ) . require_lang_item ( hir:: LangItem :: PartialEq , Some ( self . span ) ) ;
176
- let obligation: PredicateObligation < ' _ > = predicate_for_trait_def (
177
- self . tcx ( ) ,
178
- self . param_env ,
179
- ObligationCause :: misc ( self . span , self . id ) ,
180
- partial_eq_trait_id,
181
- 0 ,
182
- cv. ty ,
183
- & [ ] ,
184
- ) ;
185
- // FIXME: should this call a `predicate_must_hold` variant instead?
186
- self . infcx . predicate_may_hold ( & obligation)
187
- } ;
188
-
189
- if !ty_is_partial_eq {
162
+ if !self . type_has_partial_eq_impl ( cv. ty ) {
190
163
// span_fatal avoids ICE from resolution of non-existent method (rare case).
191
164
self . tcx ( ) . sess . span_fatal ( self . span , & msg) ;
192
165
} else if mir_structural_match_violation {
@@ -208,6 +181,40 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
208
181
inlined_const_as_pat
209
182
}
210
183
184
+ fn type_has_partial_eq_impl ( & self , ty : Ty < ' tcx > ) -> bool {
185
+ // double-check there even *is* a semantic `PartialEq` to dispatch to.
186
+ //
187
+ // (If there isn't, then we can safely issue a hard
188
+ // error, because that's never worked, due to compiler
189
+ // using `PartialEq::eq` in this scenario in the past.)
190
+ let partial_eq_trait_id =
191
+ self . tcx ( ) . require_lang_item ( hir:: LangItem :: PartialEq , Some ( self . span ) ) ;
192
+ let obligation: PredicateObligation < ' _ > = predicate_for_trait_def (
193
+ self . tcx ( ) ,
194
+ self . param_env ,
195
+ ObligationCause :: misc ( self . span , self . id ) ,
196
+ partial_eq_trait_id,
197
+ 0 ,
198
+ ty,
199
+ & [ ] ,
200
+ ) ;
201
+ // FIXME: should this call a `predicate_must_hold` variant instead?
202
+
203
+ let has_impl = self . infcx . predicate_may_hold ( & obligation) ;
204
+
205
+ // Note: To fix rust-lang/rust#65466, we could just remove this type
206
+ // walk hack for function pointers, and unconditionally error
207
+ // if `PartialEq` is not implemented. However, that breaks stable
208
+ // code at the moment, because types like `for <'a> fn(&'a ())` do
209
+ // not *yet* implement `PartialEq`. So for now we leave this here.
210
+ has_impl
211
+ || ty. walk ( ) . any ( |t| match t. unpack ( ) {
212
+ ty:: subst:: GenericArgKind :: Lifetime ( _) => false ,
213
+ ty:: subst:: GenericArgKind :: Type ( t) => t. is_fn_ptr ( ) ,
214
+ ty:: subst:: GenericArgKind :: Const ( _) => false ,
215
+ } )
216
+ }
217
+
211
218
// Recursive helper for `to_pat`; invoke that (instead of calling this directly).
212
219
fn recur ( & self , cv : & ' tcx ty:: Const < ' tcx > ) -> Pat < ' tcx > {
213
220
let id = self . id ;
0 commit comments