@@ -66,74 +66,103 @@ 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 :: AsyncDestruct ) {
83
- // `AsyncDestruct` is automatically implemented for every type.
84
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
85
- } else if tcx. is_lang_item ( def_id, LangItem :: PointeeTrait ) {
86
- // `Pointee` is automatically implemented for every type.
87
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
88
- } else if tcx. is_lang_item ( def_id, LangItem :: Sized ) {
89
- self . assemble_builtin_sized_candidate ( obligation, & mut candidates) ;
90
- } else if tcx. is_lang_item ( def_id, LangItem :: Unsize ) {
91
- self . assemble_candidates_for_unsizing ( obligation, & mut candidates) ;
92
- } else if tcx. is_lang_item ( def_id, LangItem :: Destruct ) {
93
- self . assemble_const_destruct_candidates ( obligation, & mut candidates) ;
94
- } else if tcx. is_lang_item ( def_id, LangItem :: TransmuteTrait ) {
95
- // User-defined transmutability impls are permitted.
96
- self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
97
- self . assemble_candidates_for_transmutability ( obligation, & mut candidates) ;
98
- } else if tcx. is_lang_item ( def_id, LangItem :: Tuple ) {
99
- self . assemble_candidate_for_tuple ( obligation, & mut candidates) ;
100
- } else if tcx. is_lang_item ( def_id, LangItem :: FnPtrTrait ) {
101
- self . assemble_candidates_for_fn_ptr_trait ( obligation, & mut candidates) ;
102
- } else if tcx. is_lang_item ( def_id, LangItem :: BikeshedGuaranteedNoDrop ) {
103
- self . assemble_candidates_for_bikeshed_guaranteed_no_drop_trait (
104
- obligation,
105
- & mut candidates,
106
- ) ;
107
- } else {
108
- if tcx. is_lang_item ( def_id, LangItem :: Clone ) {
109
- // Same builtin conditions as `Copy`, i.e., every type which has builtin support
110
- // for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
111
- // types have builtin support for `Clone`.
112
- let clone_conditions = self . copy_clone_conditions ( obligation) ;
113
- 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 ) => {
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) ;
114
81
}
115
-
116
- if tcx. is_lang_item ( def_id, LangItem :: Coroutine ) {
117
- self . assemble_coroutine_candidates ( obligation, & mut candidates) ;
118
- } else if tcx. is_lang_item ( def_id, LangItem :: Future ) {
119
- self . assemble_future_candidates ( obligation, & mut candidates) ;
120
- } else if tcx. is_lang_item ( def_id, LangItem :: Iterator ) {
121
- self . assemble_iterator_candidates ( obligation, & mut candidates) ;
122
- } else if tcx. is_lang_item ( def_id, LangItem :: FusedIterator ) {
123
- self . assemble_fused_iterator_candidates ( obligation, & mut candidates) ;
124
- } else if tcx. is_lang_item ( def_id, LangItem :: AsyncIterator ) {
125
- self . assemble_async_iterator_candidates ( obligation, & mut candidates) ;
126
- } else if tcx. is_lang_item ( def_id, LangItem :: AsyncFnKindHelper ) {
127
- 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 } ) ;
128
85
}
86
+ Some ( LangItem :: AsyncDestruct ) => {
87
+ // `AsyncDestruct` is automatically implemented for every type.
88
+ candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
89
+ }
90
+ Some ( LangItem :: PointeeTrait ) => {
91
+ // `Pointee` is automatically implemented for every type.
92
+ candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
93
+ }
94
+ Some ( LangItem :: Sized ) => {
95
+ self . assemble_builtin_sized_candidate ( obligation, & mut candidates) ;
96
+ }
97
+ Some ( LangItem :: Unsize ) => {
98
+ self . assemble_candidates_for_unsizing ( obligation, & mut candidates) ;
99
+ }
100
+ Some ( LangItem :: Destruct ) => {
101
+ self . assemble_const_destruct_candidates ( obligation, & mut candidates) ;
102
+ }
103
+ Some ( LangItem :: TransmuteTrait ) => {
104
+ // User-defined transmutability impls are permitted.
105
+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
106
+ self . assemble_candidates_for_transmutability ( obligation, & mut candidates) ;
107
+ }
108
+ Some ( LangItem :: Tuple ) => {
109
+ self . assemble_candidate_for_tuple ( obligation, & mut candidates) ;
110
+ }
111
+ Some ( LangItem :: FnPtrTrait ) => {
112
+ self . assemble_candidates_for_fn_ptr_trait ( obligation, & mut candidates) ;
113
+ }
114
+ Some ( LangItem :: BikeshedGuaranteedNoDrop ) => {
115
+ self . assemble_candidates_for_bikeshed_guaranteed_no_drop_trait (
116
+ obligation,
117
+ & mut candidates,
118
+ ) ;
119
+ }
120
+ _ => {
121
+ match lang_item {
122
+ Some ( LangItem :: Clone ) => {
123
+ // Same builtin conditions as `Copy`, i.e., every type which has builtin support
124
+ // for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
125
+ // types have builtin support for `Clone`.
126
+ let clone_conditions = self . copy_clone_conditions ( obligation) ;
127
+ self . assemble_builtin_bound_candidates (
128
+ clone_conditions,
129
+ & mut candidates,
130
+ ) ;
131
+ }
132
+ Some ( LangItem :: Coroutine ) => {
133
+ self . assemble_coroutine_candidates ( obligation, & mut candidates) ;
134
+ }
135
+ Some ( LangItem :: Future ) => {
136
+ self . assemble_future_candidates ( obligation, & mut candidates) ;
137
+ }
138
+ Some ( LangItem :: Iterator ) => {
139
+ self . assemble_iterator_candidates ( obligation, & mut candidates) ;
140
+ }
141
+ Some ( LangItem :: FusedIterator ) => {
142
+ self . assemble_fused_iterator_candidates ( obligation, & mut candidates) ;
143
+ }
144
+ Some ( LangItem :: AsyncIterator ) => {
145
+ self . assemble_async_iterator_candidates ( obligation, & mut candidates) ;
146
+ }
147
+ Some ( LangItem :: AsyncFnKindHelper ) => {
148
+ self . assemble_async_fn_kind_helper_candidates (
149
+ obligation,
150
+ & mut candidates,
151
+ ) ;
152
+ }
153
+ Some ( LangItem :: AsyncFn | LangItem :: AsyncFnMut | LangItem :: AsyncFnOnce ) => {
154
+ self . assemble_async_closure_candidates ( obligation, & mut candidates) ;
155
+ }
156
+ Some ( LangItem :: Fn | LangItem :: FnMut | LangItem :: FnOnce ) => {
157
+ self . assemble_closure_candidates ( obligation, & mut candidates) ;
158
+ self . assemble_fn_pointer_candidates ( obligation, & mut candidates) ;
159
+ }
160
+ _ => { }
161
+ }
129
162
130
- // FIXME: Put these into `else if` blocks above, since they're built-in.
131
- self . assemble_closure_candidates ( obligation, & mut candidates) ;
132
- self . assemble_async_closure_candidates ( obligation, & mut candidates) ;
133
- self . assemble_fn_pointer_candidates ( obligation, & mut candidates) ;
134
-
135
- self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
136
- self . assemble_candidates_from_object_ty ( obligation, & mut candidates) ;
163
+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
164
+ self . assemble_candidates_from_object_ty ( obligation, & mut candidates) ;
165
+ }
137
166
}
138
167
139
168
self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
@@ -364,9 +393,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
364
393
obligation : & PolyTraitObligation < ' tcx > ,
365
394
candidates : & mut SelectionCandidateSet < ' tcx > ,
366
395
) {
367
- let Some ( kind) = self . tcx ( ) . fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) else {
368
- return ;
369
- } ;
396
+ let kind = self . tcx ( ) . fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
370
397
371
398
// Okay to skip binder because the args on closure types never
372
399
// touch bound regions, they just capture the in-scope
@@ -428,11 +455,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
428
455
obligation : & PolyTraitObligation < ' tcx > ,
429
456
candidates : & mut SelectionCandidateSet < ' tcx > ,
430
457
) {
431
- let Some ( goal_kind) =
432
- self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) )
433
- else {
434
- return ;
435
- } ;
458
+ let goal_kind =
459
+ self . tcx ( ) . async_fn_trait_kind_from_def_id ( obligation. predicate . def_id ( ) ) . unwrap ( ) ;
436
460
437
461
match * obligation. self_ty ( ) . skip_binder ( ) . kind ( ) {
438
462
ty:: CoroutineClosure ( _, args) => {
@@ -505,11 +529,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
505
529
obligation : & PolyTraitObligation < ' tcx > ,
506
530
candidates : & mut SelectionCandidateSet < ' tcx > ,
507
531
) {
508
- // We provide impl of all fn traits for fn pointers.
509
- if !self . tcx ( ) . is_fn_trait ( obligation. predicate . def_id ( ) ) {
510
- return ;
511
- }
512
-
513
532
// Keep this function in sync with extract_tupled_inputs_and_output_from_callable
514
533
// until the old solver (and thus this function) is removed.
515
534
0 commit comments