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