@@ -19,7 +19,7 @@ use rustc_middle::{bug, span_bug};
19
19
use tracing:: { debug, instrument, trace} ;
20
20
21
21
use super :: SelectionCandidate :: * ;
22
- use super :: { BuiltinImplConditions , SelectionCandidateSet , SelectionContext , TraitObligationStack } ;
22
+ use super :: { SelectionCandidateSet , SelectionContext , TraitObligationStack } ;
23
23
use crate :: traits:: util;
24
24
25
25
impl < ' cx , ' tcx > SelectionContext < ' cx , ' tcx > {
@@ -75,27 +75,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
75
75
self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
76
76
77
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) ;
78
+ self . assemble_builtin_copy_clone_candidate (
79
+ obligation. predicate . self_ty ( ) . skip_binder ( ) ,
80
+ & mut candidates,
81
+ ) ;
80
82
}
81
83
Some ( LangItem :: DiscriminantKind ) => {
82
84
// `DiscriminantKind` is automatically implemented for every type.
83
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
85
+ candidates. vec . push ( BuiltinCandidate ) ;
84
86
}
85
87
Some ( LangItem :: PointeeTrait ) => {
86
88
// `Pointee` is automatically implemented for every type.
87
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
89
+ candidates. vec . push ( BuiltinCandidate ) ;
88
90
}
89
91
Some ( LangItem :: Sized ) => {
90
92
self . assemble_builtin_sized_candidate (
91
- obligation,
93
+ obligation. predicate . self_ty ( ) . skip_binder ( ) ,
92
94
& mut candidates,
93
95
SizedTraitKind :: Sized ,
94
96
) ;
95
97
}
96
98
Some ( LangItem :: MetaSized ) => {
97
99
self . assemble_builtin_sized_candidate (
98
- obligation,
100
+ obligation. predicate . self_ty ( ) . skip_binder ( ) ,
99
101
& mut candidates,
100
102
SizedTraitKind :: MetaSized ,
101
103
) ;
@@ -357,15 +359,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
357
359
obligation : & PolyTraitObligation < ' tcx > ,
358
360
candidates : & mut SelectionCandidateSet < ' tcx > ,
359
361
) {
360
- let self_ty = obligation. self_ty ( ) . skip_binder ( ) ;
361
- // gen constructs get lowered to a special kind of coroutine that
362
- // should directly `impl FusedIterator`.
363
- if let ty:: Coroutine ( did, ..) = self_ty. kind ( )
364
- && self . tcx ( ) . coroutine_is_gen ( * did)
365
- {
366
- debug ! ( ?self_ty, ?obligation, "assemble_fused_iterator_candidates" , ) ;
367
-
368
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
362
+ if self . coroutine_is_gen ( obligation. self_ty ( ) . skip_binder ( ) ) {
363
+ candidates. vec . push ( BuiltinCandidate ) ;
369
364
}
370
365
}
371
366
@@ -810,7 +805,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
810
805
hir:: Movability :: Movable => {
811
806
// Movable coroutines are always `Unpin`, so add an
812
807
// unconditional builtin candidate.
813
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
808
+ candidates. vec . push ( BuiltinCandidate ) ;
814
809
}
815
810
}
816
811
}
@@ -1113,45 +1108,163 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1113
1108
}
1114
1109
}
1115
1110
1116
- /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself.
1111
+ /// Assembles `Copy` and `Clone` candidates for built-in types with no libcore-defined
1112
+ /// `Copy` or `Clone` impls.
1117
1113
#[ instrument( level = "debug" , skip( self , candidates) ) ]
1118
- fn assemble_builtin_sized_candidate (
1114
+ fn assemble_builtin_copy_clone_candidate (
1119
1115
& mut self ,
1120
- obligation : & PolyTraitObligation < ' tcx > ,
1116
+ self_ty : Ty < ' tcx > ,
1121
1117
candidates : & mut SelectionCandidateSet < ' tcx > ,
1122
- sizedness : SizedTraitKind ,
1123
1118
) {
1124
- match self . sizedness_conditions ( obligation, sizedness) {
1125
- BuiltinImplConditions :: Where ( nested) => {
1126
- candidates
1127
- . vec
1128
- . push ( SizedCandidate { has_nested : !nested. skip_binder ( ) . is_empty ( ) } ) ;
1119
+ match * self_ty. kind ( ) {
1120
+ // These impls exist because we cannot express sufficiently
1121
+ // generic impls in libcore.
1122
+ ty:: FnDef ( ..)
1123
+ | ty:: FnPtr ( ..)
1124
+ | ty:: Error ( _)
1125
+ | ty:: Tuple ( ..)
1126
+ | ty:: CoroutineWitness ( ..)
1127
+ | ty:: Pat ( ..) => {
1128
+ candidates. vec . push ( BuiltinCandidate ) ;
1129
+ }
1130
+
1131
+ // Implementations provided in libcore.
1132
+ ty:: Uint ( _)
1133
+ | ty:: Int ( _)
1134
+ | ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
1135
+ | ty:: Bool
1136
+ | ty:: Float ( _)
1137
+ | ty:: Char
1138
+ | ty:: RawPtr ( ..)
1139
+ | ty:: Never
1140
+ | ty:: Ref ( _, _, hir:: Mutability :: Not )
1141
+ | ty:: Array ( ..) => { }
1142
+
1143
+ // FIXME(unsafe_binder): Should we conditionally
1144
+ // (i.e. universally) implement copy/clone?
1145
+ ty:: UnsafeBinder ( _) => { }
1146
+
1147
+ // Not `Sized`, which is a supertrait of `Copy`/`Clone`.
1148
+ ty:: Dynamic ( ..)
1149
+ | ty:: Str
1150
+ | ty:: Slice ( ..)
1151
+ | ty:: Foreign ( ..)
1152
+ | ty:: Ref ( _, _, hir:: Mutability :: Mut ) => { }
1153
+
1154
+ ty:: Coroutine ( coroutine_def_id, args) => {
1155
+ match self . tcx ( ) . coroutine_movability ( coroutine_def_id) {
1156
+ hir:: Movability :: Static => { }
1157
+ hir:: Movability :: Movable => {
1158
+ if self . tcx ( ) . features ( ) . coroutine_clone ( ) {
1159
+ let resolved_upvars =
1160
+ self . infcx . shallow_resolve ( args. as_coroutine ( ) . tupled_upvars_ty ( ) ) ;
1161
+ let resolved_witness =
1162
+ self . infcx . shallow_resolve ( args. as_coroutine ( ) . witness ( ) ) ;
1163
+ if resolved_upvars. is_ty_var ( ) || resolved_witness. is_ty_var ( ) {
1164
+ // Not yet resolved.
1165
+ candidates. ambiguous = true ;
1166
+ } else {
1167
+ candidates. vec . push ( BuiltinCandidate ) ;
1168
+ }
1169
+ }
1170
+ }
1171
+ }
1172
+ }
1173
+
1174
+ ty:: Closure ( _, args) => {
1175
+ let resolved_upvars =
1176
+ self . infcx . shallow_resolve ( args. as_closure ( ) . tupled_upvars_ty ( ) ) ;
1177
+ if resolved_upvars. is_ty_var ( ) {
1178
+ // Not yet resolved.
1179
+ candidates. ambiguous = true ;
1180
+ } else {
1181
+ candidates. vec . push ( BuiltinCandidate ) ;
1182
+ }
1129
1183
}
1130
- BuiltinImplConditions :: None => { }
1131
- BuiltinImplConditions :: Ambiguous => {
1184
+
1185
+ ty:: CoroutineClosure ( _, args) => {
1186
+ let resolved_upvars =
1187
+ self . infcx . shallow_resolve ( args. as_coroutine_closure ( ) . tupled_upvars_ty ( ) ) ;
1188
+ if resolved_upvars. is_ty_var ( ) {
1189
+ // Not yet resolved.
1190
+ candidates. ambiguous = true ;
1191
+ } else {
1192
+ candidates. vec . push ( BuiltinCandidate ) ;
1193
+ }
1194
+ }
1195
+
1196
+ // Fallback to whatever user-defined impls or param-env clauses exist in this case.
1197
+ ty:: Adt ( ..) | ty:: Alias ( ..) | ty:: Param ( ..) | ty:: Placeholder ( ..) => { }
1198
+
1199
+ ty:: Infer ( ty:: TyVar ( _) ) => {
1132
1200
candidates. ambiguous = true ;
1133
1201
}
1202
+
1203
+ ty:: Bound ( ..) => { }
1204
+
1205
+ ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
1206
+ bug ! ( "asked to assemble builtin bounds of unexpected type: {:?}" , self_ty) ;
1207
+ }
1134
1208
}
1135
1209
}
1136
1210
1137
- /// Assembles the trait which are built-in to the language itself:
1138
- /// e.g. `Copy` and `Clone`.
1211
+ /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself.
1139
1212
#[ instrument( level = "debug" , skip( self , candidates) ) ]
1140
- fn assemble_builtin_bound_candidates (
1213
+ fn assemble_builtin_sized_candidate (
1141
1214
& mut self ,
1142
- conditions : BuiltinImplConditions < ' tcx > ,
1215
+ self_ty : Ty < ' tcx > ,
1143
1216
candidates : & mut SelectionCandidateSet < ' tcx > ,
1217
+ sizedness : SizedTraitKind ,
1144
1218
) {
1145
- match conditions {
1146
- BuiltinImplConditions :: Where ( nested) => {
1147
- candidates
1148
- . vec
1149
- . push ( BuiltinCandidate { has_nested : !nested. skip_binder ( ) . is_empty ( ) } ) ;
1219
+ match * self_ty. kind ( ) {
1220
+ // Always sized.
1221
+ ty:: Infer ( ty:: IntVar ( _) | ty:: FloatVar ( _) )
1222
+ | ty:: Uint ( _)
1223
+ | ty:: Int ( _)
1224
+ | ty:: Bool
1225
+ | ty:: Float ( _)
1226
+ | ty:: FnDef ( ..)
1227
+ | ty:: FnPtr ( ..)
1228
+ | ty:: RawPtr ( ..)
1229
+ | ty:: Char
1230
+ | ty:: Ref ( ..)
1231
+ | ty:: Coroutine ( ..)
1232
+ | ty:: CoroutineWitness ( ..)
1233
+ | ty:: Array ( ..)
1234
+ | ty:: Closure ( ..)
1235
+ | ty:: CoroutineClosure ( ..)
1236
+ | ty:: Never
1237
+ | ty:: Error ( _) => {
1238
+ candidates. vec . push ( SizedCandidate ) ;
1239
+ }
1240
+
1241
+ // Conditionally `Sized`.
1242
+ ty:: Tuple ( ..) | ty:: Pat ( ..) | ty:: Adt ( ..) | ty:: UnsafeBinder ( _) => {
1243
+ candidates. vec . push ( SizedCandidate ) ;
1150
1244
}
1151
- BuiltinImplConditions :: None => { }
1152
- BuiltinImplConditions :: Ambiguous => {
1245
+
1246
+ // `MetaSized` but not `Sized`.
1247
+ ty:: Str | ty:: Slice ( _) | ty:: Dynamic ( ..) => match sizedness {
1248
+ SizedTraitKind :: Sized => { }
1249
+ SizedTraitKind :: MetaSized => {
1250
+ candidates. vec . push ( SizedCandidate ) ;
1251
+ }
1252
+ } ,
1253
+
1254
+ // Not `MetaSized` or `Sized`.
1255
+ ty:: Foreign ( ..) => { }
1256
+
1257
+ ty:: Alias ( ..) | ty:: Param ( _) | ty:: Placeholder ( ..) => { }
1258
+
1259
+ ty:: Infer ( ty:: TyVar ( _) ) => {
1153
1260
candidates. ambiguous = true ;
1154
1261
}
1262
+
1263
+ ty:: Bound ( ..) => { }
1264
+
1265
+ ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
1266
+ bug ! ( "asked to assemble builtin bounds of unexpected type: {:?}" , self_ty) ;
1267
+ }
1155
1268
}
1156
1269
}
1157
1270
@@ -1160,7 +1273,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1160
1273
_obligation : & PolyTraitObligation < ' tcx > ,
1161
1274
candidates : & mut SelectionCandidateSet < ' tcx > ,
1162
1275
) {
1163
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
1276
+ candidates. vec . push ( BuiltinCandidate ) ;
1164
1277
}
1165
1278
1166
1279
fn assemble_candidate_for_tuple (
@@ -1171,7 +1284,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1171
1284
let self_ty = self . infcx . shallow_resolve ( obligation. self_ty ( ) . skip_binder ( ) ) ;
1172
1285
match self_ty. kind ( ) {
1173
1286
ty:: Tuple ( _) => {
1174
- candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ;
1287
+ candidates. vec . push ( BuiltinCandidate ) ;
1175
1288
}
1176
1289
ty:: Infer ( ty:: TyVar ( _) ) => {
1177
1290
candidates. ambiguous = true ;
@@ -1215,7 +1328,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1215
1328
let self_ty = self . infcx . resolve_vars_if_possible ( obligation. self_ty ( ) ) ;
1216
1329
1217
1330
match self_ty. skip_binder ( ) . kind ( ) {
1218
- ty:: FnPtr ( ..) => candidates. vec . push ( BuiltinCandidate { has_nested : false } ) ,
1331
+ ty:: FnPtr ( ..) => candidates. vec . push ( BuiltinCandidate ) ,
1219
1332
ty:: Bool
1220
1333
| ty:: Char
1221
1334
| ty:: Int ( _)
0 commit comments