@@ -254,68 +254,72 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
254
254
255
255
let mut candidates = SelectionCandidateSet { vec : Vec :: new ( ) , ambiguous : false } ;
256
256
257
- self . assemble_candidates_for_trait_alias ( obligation, & mut candidates) ;
258
-
259
- // Other bounds. Consider both in-scope bounds from fn decl
260
- // and applicable impls. There is a certain set of precedence rules here.
261
- let def_id = obligation. predicate . def_id ( ) ;
262
- let lang_items = self . tcx ( ) . lang_items ( ) ;
263
-
264
- if lang_items. copy_trait ( ) == Some ( def_id) {
265
- debug ! ( obligation_self_ty = ?obligation. predicate. skip_binder( ) . self_ty( ) ) ;
266
-
267
- // User-defined copy impls are permitted, but only for
268
- // structs and enums.
257
+ if obligation. predicate . skip_binder ( ) . polarity == ty:: ImplPolarity :: Negative {
269
258
self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
270
-
271
- // For other types, we'll use the builtin rules.
272
- let copy_conditions = self . copy_clone_conditions ( obligation) ;
273
- self . assemble_builtin_bound_candidates ( copy_conditions, & mut candidates) ;
274
- } else if lang_items. discriminant_kind_trait ( ) == Some ( def_id) {
275
- // `DiscriminantKind` is automatically implemented for every type.
276
- candidates. vec . push ( DiscriminantKindCandidate ) ;
277
- } else if lang_items. pointee_trait ( ) == Some ( def_id) {
278
- // `Pointee` is automatically implemented for every type.
279
- candidates. vec . push ( PointeeCandidate ) ;
280
- } else if lang_items. sized_trait ( ) == Some ( def_id) {
281
- // Sized is never implementable by end-users, it is
282
- // always automatically computed.
283
- let sized_conditions = self . sized_conditions ( obligation) ;
284
- self . assemble_builtin_bound_candidates ( sized_conditions, & mut candidates) ;
285
- } else if lang_items. unsize_trait ( ) == Some ( def_id) {
286
- self . assemble_candidates_for_unsizing ( obligation, & mut candidates) ;
287
- } else if lang_items. drop_trait ( ) == Some ( def_id)
288
- && obligation. predicate . skip_binder ( ) . constness == ty:: BoundConstness :: ConstIfConst
289
- {
290
- if self . is_in_const_context {
291
- self . assemble_const_drop_candidates ( obligation, & mut candidates) ?;
292
- } else {
293
- debug ! ( "passing ~const Drop bound; in non-const context" ) ;
294
- // `~const Drop` when we are not in a const context has no effect.
295
- candidates. vec . push ( ConstDropCandidate )
296
- }
297
259
} else {
298
- if lang_items. clone_trait ( ) == Some ( def_id) {
299
- // Same builtin conditions as `Copy`, i.e., every type which has builtin support
300
- // for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
301
- // types have builtin support for `Clone`.
302
- let clone_conditions = self . copy_clone_conditions ( obligation) ;
303
- self . assemble_builtin_bound_candidates ( clone_conditions, & mut candidates) ;
304
- }
260
+ self . assemble_candidates_for_trait_alias ( obligation, & mut candidates) ;
261
+
262
+ // Other bounds. Consider both in-scope bounds from fn decl
263
+ // and applicable impls. There is a certain set of precedence rules here.
264
+ let def_id = obligation. predicate . def_id ( ) ;
265
+ let lang_items = self . tcx ( ) . lang_items ( ) ;
266
+
267
+ if lang_items. copy_trait ( ) == Some ( def_id) {
268
+ debug ! ( obligation_self_ty = ?obligation. predicate. skip_binder( ) . self_ty( ) ) ;
269
+
270
+ // User-defined copy impls are permitted, but only for
271
+ // structs and enums.
272
+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
273
+
274
+ // For other types, we'll use the builtin rules.
275
+ let copy_conditions = self . copy_clone_conditions ( obligation) ;
276
+ self . assemble_builtin_bound_candidates ( copy_conditions, & mut candidates) ;
277
+ } else if lang_items. discriminant_kind_trait ( ) == Some ( def_id) {
278
+ // `DiscriminantKind` is automatically implemented for every type.
279
+ candidates. vec . push ( DiscriminantKindCandidate ) ;
280
+ } else if lang_items. pointee_trait ( ) == Some ( def_id) {
281
+ // `Pointee` is automatically implemented for every type.
282
+ candidates. vec . push ( PointeeCandidate ) ;
283
+ } else if lang_items. sized_trait ( ) == Some ( def_id) {
284
+ // Sized is never implementable by end-users, it is
285
+ // always automatically computed.
286
+ let sized_conditions = self . sized_conditions ( obligation) ;
287
+ self . assemble_builtin_bound_candidates ( sized_conditions, & mut candidates) ;
288
+ } else if lang_items. unsize_trait ( ) == Some ( def_id) {
289
+ self . assemble_candidates_for_unsizing ( obligation, & mut candidates) ;
290
+ } else if lang_items. drop_trait ( ) == Some ( def_id)
291
+ && obligation. predicate . skip_binder ( ) . constness == ty:: BoundConstness :: ConstIfConst
292
+ {
293
+ if self . is_in_const_context {
294
+ self . assemble_const_drop_candidates ( obligation, & mut candidates) ?;
295
+ } else {
296
+ debug ! ( "passing ~const Drop bound; in non-const context" ) ;
297
+ // `~const Drop` when we are not in a const context has no effect.
298
+ candidates. vec . push ( ConstDropCandidate )
299
+ }
300
+ } else {
301
+ if lang_items. clone_trait ( ) == Some ( def_id) {
302
+ // Same builtin conditions as `Copy`, i.e., every type which has builtin support
303
+ // for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
304
+ // types have builtin support for `Clone`.
305
+ let clone_conditions = self . copy_clone_conditions ( obligation) ;
306
+ self . assemble_builtin_bound_candidates ( clone_conditions, & mut candidates) ;
307
+ }
305
308
306
- self . assemble_generator_candidates ( obligation, & mut candidates) ;
307
- self . assemble_closure_candidates ( obligation, & mut candidates) ;
308
- self . assemble_fn_pointer_candidates ( obligation, & mut candidates) ;
309
- self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
310
- self . assemble_candidates_from_object_ty ( obligation, & mut candidates) ;
311
- }
309
+ self . assemble_generator_candidates ( obligation, & mut candidates) ;
310
+ self . assemble_closure_candidates ( obligation, & mut candidates) ;
311
+ self . assemble_fn_pointer_candidates ( obligation, & mut candidates) ;
312
+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
313
+ self . assemble_candidates_from_object_ty ( obligation, & mut candidates) ;
314
+ }
312
315
313
- self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
314
- self . assemble_candidates_from_caller_bounds ( stack, & mut candidates) ?;
315
- // Auto implementations have lower priority, so we only
316
- // consider triggering a default if there is no other impl that can apply.
317
- if candidates. vec . is_empty ( ) {
318
- self . assemble_candidates_from_auto_impls ( obligation, & mut candidates) ;
316
+ self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
317
+ self . assemble_candidates_from_caller_bounds ( stack, & mut candidates) ?;
318
+ // Auto implementations have lower priority, so we only
319
+ // consider triggering a default if there is no other impl that can apply.
320
+ if candidates. vec . is_empty ( ) {
321
+ self . assemble_candidates_from_auto_impls ( obligation, & mut candidates) ;
322
+ }
319
323
}
320
324
debug ! ( "candidate list size: {}" , candidates. vec. len( ) ) ;
321
325
Ok ( candidates)
0 commit comments