@@ -66,71 +66,90 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6666 let def_id = obligation. predicate . def_id ( ) ;
6767 let tcx = self . tcx ( ) ;
6868
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) ;
11181 }
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 } ) ;
12585 }
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+ _ => {
143+ // FIXME: Put these into match arms above, since they're built-in.
144+ self . assemble_closure_candidates ( obligation, & mut candidates) ;
145+ self . assemble_async_closure_candidates ( obligation, & mut candidates) ;
146+ self . assemble_fn_pointer_candidates ( obligation, & mut candidates) ;
147+ }
148+ }
126149
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) ;
150+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
151+ self . assemble_candidates_from_object_ty ( obligation, & mut candidates) ;
152+ }
134153 }
135154
136155 self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
0 commit comments