@@ -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