@@ -66,71 +66,92 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
66
66
let def_id = obligation. predicate . def_id ( ) ;
67
67
let tcx = self . tcx ( ) ;
68
68
69
- if tcx. is_lang_item ( def_id, LangItem :: Copy ) {
70
- debug ! ( obligation_self_ty = ?obligation. predicate. skip_binder( ) . self_ty( ) ) ;
71
-
72
- // User-defined copy impls are permitted, but only for
73
- // structs and enums.
74
- self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
75
-
76
- // For other types, we'll use the builtin rules.
77
- let copy_conditions = self . copy_clone_conditions ( obligation) ;
78
- self . assemble_builtin_bound_candidates ( copy_conditions, & mut candidates) ;
79
- } else if tcx. is_lang_item ( def_id, LangItem :: DiscriminantKind ) {
80
- // `DiscriminantKind` is automatically implemented for every type.
81
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
82
- } else if tcx. is_lang_item ( def_id, LangItem :: PointeeTrait ) {
83
- // `Pointee` is automatically implemented for every type.
84
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
85
- } else if tcx. is_lang_item ( def_id, LangItem :: Sized ) {
86
- self . assemble_builtin_sized_candidate ( obligation, & mut candidates) ;
87
- } else if tcx. is_lang_item ( def_id, LangItem :: Unsize ) {
88
- self . assemble_candidates_for_unsizing ( obligation, & mut candidates) ;
89
- } else if tcx. is_lang_item ( def_id, LangItem :: Destruct ) {
90
- self . assemble_const_destruct_candidates ( obligation, & mut candidates) ;
91
- } else if tcx. is_lang_item ( def_id, LangItem :: TransmuteTrait ) {
92
- // User-defined transmutability impls are permitted.
93
- self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
94
- self . assemble_candidates_for_transmutability ( obligation, & mut candidates) ;
95
- } else if tcx. is_lang_item ( def_id, LangItem :: Tuple ) {
96
- self . assemble_candidate_for_tuple ( obligation, & mut candidates) ;
97
- } else if tcx. is_lang_item ( def_id, LangItem :: FnPtrTrait ) {
98
- self . assemble_candidates_for_fn_ptr_trait ( obligation, & mut candidates) ;
99
- } else if tcx. is_lang_item ( def_id, LangItem :: BikeshedGuaranteedNoDrop ) {
100
- self . assemble_candidates_for_bikeshed_guaranteed_no_drop_trait (
101
- obligation,
102
- & mut candidates,
103
- ) ;
104
- } else {
105
- if tcx. is_lang_item ( def_id, LangItem :: Clone ) {
106
- // Same builtin conditions as `Copy`, i.e., every type which has builtin support
107
- // for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
108
- // types have builtin support for `Clone`.
109
- let clone_conditions = self . copy_clone_conditions ( obligation) ;
110
- self . assemble_builtin_bound_candidates ( clone_conditions, & mut candidates) ;
69
+ let lang_item = tcx. as_lang_item ( def_id) ;
70
+ match lang_item {
71
+ Some ( LangItem :: Copy | LangItem :: Clone ) => {
72
+ debug ! ( obligation_self_ty = ?obligation. predicate. skip_binder( ) . self_ty( ) ) ;
73
+
74
+ // User-defined copy impls are permitted, but only for
75
+ // structs and enums.
76
+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
77
+
78
+ // For other types, we'll use the builtin rules.
79
+ let copy_conditions = self . copy_clone_conditions ( obligation) ;
80
+ self . assemble_builtin_bound_candidates ( copy_conditions, & mut candidates) ;
111
81
}
112
-
113
- if tcx. is_lang_item ( def_id, LangItem :: Coroutine ) {
114
- self . assemble_coroutine_candidates ( obligation, & mut candidates) ;
115
- } else if tcx. is_lang_item ( def_id, LangItem :: Future ) {
116
- self . assemble_future_candidates ( obligation, & mut candidates) ;
117
- } else if tcx. is_lang_item ( def_id, LangItem :: Iterator ) {
118
- self . assemble_iterator_candidates ( obligation, & mut candidates) ;
119
- } else if tcx. is_lang_item ( def_id, LangItem :: FusedIterator ) {
120
- self . assemble_fused_iterator_candidates ( obligation, & mut candidates) ;
121
- } else if tcx. is_lang_item ( def_id, LangItem :: AsyncIterator ) {
122
- self . assemble_async_iterator_candidates ( obligation, & mut candidates) ;
123
- } else if tcx. is_lang_item ( def_id, LangItem :: AsyncFnKindHelper ) {
124
- self . assemble_async_fn_kind_helper_candidates ( obligation, & mut candidates) ;
82
+ Some ( LangItem :: DiscriminantKind ) => {
83
+ // `DiscriminantKind` is automatically implemented for every type.
84
+ candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
125
85
}
86
+ Some ( LangItem :: PointeeTrait ) => {
87
+ // `Pointee` is automatically implemented for every type.
88
+ candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
89
+ }
90
+ Some ( LangItem :: Sized ) => {
91
+ self . assemble_builtin_sized_candidate ( obligation, & mut candidates) ;
92
+ }
93
+ Some ( LangItem :: Unsize ) => {
94
+ self . assemble_candidates_for_unsizing ( obligation, & mut candidates) ;
95
+ }
96
+ Some ( LangItem :: Destruct ) => {
97
+ self . assemble_const_destruct_candidates ( obligation, & mut candidates) ;
98
+ }
99
+ Some ( LangItem :: TransmuteTrait ) => {
100
+ // User-defined transmutability impls are permitted.
101
+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
102
+ self . assemble_candidates_for_transmutability ( obligation, & mut candidates) ;
103
+ }
104
+ Some ( LangItem :: Tuple ) => {
105
+ self . assemble_candidate_for_tuple ( obligation, & mut candidates) ;
106
+ }
107
+ Some ( LangItem :: FnPtrTrait ) => {
108
+ self . assemble_candidates_for_fn_ptr_trait ( obligation, & mut candidates) ;
109
+ }
110
+ Some ( LangItem :: BikeshedGuaranteedNoDrop ) => {
111
+ self . assemble_candidates_for_bikeshed_guaranteed_no_drop_trait (
112
+ obligation,
113
+ & mut candidates,
114
+ ) ;
115
+ }
116
+ _ => {
117
+ // We re-match here for traits that can have both builtin impls and user written impls.
118
+ // After the builtin impls we need to also add user written impls, which we do not want to
119
+ // do in general because just checking if there are any is expensive.
120
+ match lang_item {
121
+ Some ( LangItem :: Coroutine ) => {
122
+ self . assemble_coroutine_candidates ( obligation, & mut candidates) ;
123
+ }
124
+ Some ( LangItem :: Future ) => {
125
+ self . assemble_future_candidates ( obligation, & mut candidates) ;
126
+ }
127
+ Some ( LangItem :: Iterator ) => {
128
+ self . assemble_iterator_candidates ( obligation, & mut candidates) ;
129
+ }
130
+ Some ( LangItem :: FusedIterator ) => {
131
+ self . assemble_fused_iterator_candidates ( obligation, & mut candidates) ;
132
+ }
133
+ Some ( LangItem :: AsyncIterator ) => {
134
+ self . assemble_async_iterator_candidates ( obligation, & mut candidates) ;
135
+ }
136
+ Some ( LangItem :: AsyncFnKindHelper ) => {
137
+ self . assemble_async_fn_kind_helper_candidates (
138
+ obligation,
139
+ & mut candidates,
140
+ ) ;
141
+ }
142
+ Some ( LangItem :: AsyncFn | LangItem :: AsyncFnMut | LangItem :: AsyncFnOnce ) => {
143
+ self . assemble_async_closure_candidates ( obligation, & mut candidates) ;
144
+ }
145
+ Some ( LangItem :: Fn | LangItem :: FnMut | LangItem :: FnOnce ) => {
146
+ self . assemble_closure_candidates ( obligation, & mut candidates) ;
147
+ self . assemble_fn_pointer_candidates ( obligation, & mut candidates) ;
148
+ }
149
+ _ => { }
150
+ }
126
151
127
- // FIXME: Put these into `else if` blocks above, since they're built-in.
128
- self . assemble_closure_candidates ( obligation, & mut candidates) ;
129
- self . assemble_async_closure_candidates ( obligation, & mut candidates) ;
130
- self . assemble_fn_pointer_candidates ( obligation, & mut candidates) ;
131
-
132
- self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
133
- self . assemble_candidates_from_object_ty ( obligation, & mut candidates) ;
152
+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
153
+ self . assemble_candidates_from_object_ty ( obligation, & mut candidates) ;
154
+ }
134
155
}
135
156
136
157
self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
@@ -361,9 +382,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
361
382
obligation : & PolyTraitObligation < ' tcx > ,
362
383
candidates : & mut SelectionCandidateSet < ' tcx > ,
363
384
) {
364
- let Some ( kind) = self . tcx ( ) . fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) else {
365
- return ;
366
- } ;
385
+ let kind = self . tcx ( ) . fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
367
386
368
387
// Okay to skip binder because the args on closure types never
369
388
// touch bound regions, they just capture the in-scope
@@ -425,11 +444,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
425
444
obligation : & PolyTraitObligation < ' tcx > ,
426
445
candidates : & mut SelectionCandidateSet < ' tcx > ,
427
446
) {
428
- let Some ( goal_kind) =
429
- self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) )
430
- else {
431
- return ;
432
- } ;
447
+ let goal_kind =
448
+ self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
433
449
434
450
match * obligation. self_ty ( ) . skip_binder ( ) . kind ( ) {
435
451
ty:: CoroutineClosure ( _, args) => {
@@ -502,11 +518,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
502
518
obligation : & PolyTraitObligation < ' tcx > ,
503
519
candidates : & mut SelectionCandidateSet < ' tcx > ,
504
520
) {
505
- // We provide impl of all fn traits for fn pointers.
506
- if !self . tcx ( ) . is_fn_trait ( obligation. predicate . def_id ( ) ) {
507
- return ;
508
- }
509
-
510
521
// Keep this function in sync with extract_tupled_inputs_and_output_from_callable
511
522
// until the old solver (and thus this function) is removed.
512
523
0 commit comments