@@ -65,71 +65,92 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6565            let  def_id = obligation. predicate . def_id ( ) ; 
6666            let  tcx = self . tcx ( ) ; 
6767
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) ; 
11080                } 
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  } ) ; 
12484                } 
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+                     } 
125150
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+                 } 
133154            } 
134155
135156            self . assemble_candidates_from_projected_tys ( obligation,  & mut  candidates) ; 
@@ -360,9 +381,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
360381        obligation :  & PolyTraitObligation < ' tcx > , 
361382        candidates :  & mut  SelectionCandidateSet < ' tcx > , 
362383    )  { 
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 ( ) ; 
366385
367386        // Okay to skip binder because the args on closure types never 
368387        // touch bound regions, they just capture the in-scope 
@@ -424,11 +443,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
424443        obligation :  & PolyTraitObligation < ' tcx > , 
425444        candidates :  & mut  SelectionCandidateSet < ' tcx > , 
426445    )  { 
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 ( ) ; 
432448
433449        match  * obligation. self_ty ( ) . skip_binder ( ) . kind ( )  { 
434450            ty:: CoroutineClosure ( _,  args)  => { 
@@ -501,11 +517,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
501517        obligation :  & PolyTraitObligation < ' tcx > , 
502518        candidates :  & mut  SelectionCandidateSet < ' tcx > , 
503519    )  { 
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- 
509520        // Keep this function in sync with extract_tupled_inputs_and_output_from_callable 
510521        // until the old solver (and thus this function) is removed. 
511522
0 commit comments