@@ -19,7 +19,7 @@ use rustc_middle::{bug, span_bug};
1919use tracing:: { debug, instrument, trace} ;
2020
2121use super :: SelectionCandidate :: * ;
22- use super :: { BuiltinImplConditions , SelectionCandidateSet , SelectionContext , TraitObligationStack } ;
22+ use super :: { SelectionCandidateSet , SelectionContext , TraitObligationStack } ;
2323use crate :: traits:: util;
2424
2525impl < ' cx , ' tcx > SelectionContext < ' cx , ' tcx > {
@@ -75,8 +75,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
7575 self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
7676
7777 // 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+ ) ;
8082 }
8183 Some ( LangItem :: DiscriminantKind ) => {
8284 // `DiscriminantKind` is automatically implemented for every type.
@@ -88,14 +90,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
8890 }
8991 Some ( LangItem :: Sized ) => {
9092 self . assemble_builtin_sized_candidate (
91- obligation,
93+ obligation. predicate . self_ty ( ) . skip_binder ( ) ,
9294 & mut candidates,
9395 SizedTraitKind :: Sized ,
9496 ) ;
9597 }
9698 Some ( LangItem :: MetaSized ) => {
9799 self . assemble_builtin_sized_candidate (
98- obligation,
100+ obligation. predicate . self_ty ( ) . skip_binder ( ) ,
99101 & mut candidates,
100102 SizedTraitKind :: MetaSized ,
101103 ) ;
@@ -357,14 +359,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
357359 obligation : & PolyTraitObligation < ' tcx > ,
358360 candidates : & mut SelectionCandidateSet < ' tcx > ,
359361 ) {
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-
362+ if self . coroutine_is_gen ( obligation. self_ty ( ) . skip_binder ( ) ) {
368363 candidates. vec . push ( BuiltinCandidate ) ;
369364 }
370365 }
@@ -1113,41 +1108,164 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11131108 }
11141109 }
11151110
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.
11171113 #[ instrument( level = "debug" , skip( self , candidates) ) ]
1118- fn assemble_builtin_sized_candidate (
1114+ fn assemble_builtin_copy_clone_candidate (
11191115 & mut self ,
1120- obligation : & PolyTraitObligation < ' tcx > ,
1116+ self_ty : Ty < ' tcx > ,
11211117 candidates : & mut SelectionCandidateSet < ' tcx > ,
1122- sizedness : SizedTraitKind ,
11231118 ) {
1124- match self . sizedness_conditions ( obligation, sizedness) {
1125- BuiltinImplConditions :: Where ( _nested) => {
1126- candidates. vec . push ( SizedCandidate ) ;
1119+ match * self_ty. kind ( ) {
1120+ // These impls are built-in 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 ( ..) | ty:: Str | ty:: Slice ( ..) | ty:: Foreign ( ..) => { }
1149+
1150+ // Not `Copy` or `Clone` by design.
1151+ ty:: Ref ( _, _, hir:: Mutability :: Mut ) => { }
1152+
1153+ ty:: Coroutine ( coroutine_def_id, args) => {
1154+ match self . tcx ( ) . coroutine_movability ( coroutine_def_id) {
1155+ hir:: Movability :: Static => { }
1156+ hir:: Movability :: Movable => {
1157+ if self . tcx ( ) . features ( ) . coroutine_clone ( ) {
1158+ let resolved_upvars =
1159+ self . infcx . shallow_resolve ( args. as_coroutine ( ) . tupled_upvars_ty ( ) ) ;
1160+ let resolved_witness =
1161+ self . infcx . shallow_resolve ( args. as_coroutine ( ) . witness ( ) ) ;
1162+ if resolved_upvars. is_ty_var ( ) || resolved_witness. is_ty_var ( ) {
1163+ // Not yet resolved.
1164+ candidates. ambiguous = true ;
1165+ } else {
1166+ candidates. vec . push ( BuiltinCandidate ) ;
1167+ }
1168+ }
1169+ }
1170+ }
11271171 }
1128- BuiltinImplConditions :: None => { }
1129- BuiltinImplConditions :: Ambiguous => {
1172+
1173+ ty:: Closure ( _, args) => {
1174+ let resolved_upvars =
1175+ self . infcx . shallow_resolve ( args. as_closure ( ) . tupled_upvars_ty ( ) ) ;
1176+ if resolved_upvars. is_ty_var ( ) {
1177+ // Not yet resolved.
1178+ candidates. ambiguous = true ;
1179+ } else {
1180+ candidates. vec . push ( BuiltinCandidate ) ;
1181+ }
1182+ }
1183+
1184+ ty:: CoroutineClosure ( _, args) => {
1185+ let resolved_upvars =
1186+ self . infcx . shallow_resolve ( args. as_coroutine_closure ( ) . tupled_upvars_ty ( ) ) ;
1187+ if resolved_upvars. is_ty_var ( ) {
1188+ // Not yet resolved.
1189+ candidates. ambiguous = true ;
1190+ } else {
1191+ candidates. vec . push ( BuiltinCandidate ) ;
1192+ }
1193+ }
1194+
1195+ // Fallback to whatever user-defined impls or param-env clauses exist in this case.
1196+ ty:: Adt ( ..) | ty:: Alias ( ..) | ty:: Param ( ..) | ty:: Placeholder ( ..) => { }
1197+
1198+ ty:: Infer ( ty:: TyVar ( _) ) => {
11301199 candidates. ambiguous = true ;
11311200 }
1201+
1202+ // Only appears when assembling higher-ranked `for<T> T: Clone`.
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+ }
11321208 }
11331209 }
11341210
1135- /// Assembles the trait which are built-in to the language itself:
1136- /// e.g. `Copy` and `Clone`.
1211+ /// Assembles the `Sized` and `MetaSized` traits which are built-in to the language itself.
11371212 #[ instrument( level = "debug" , skip( self , candidates) ) ]
1138- fn assemble_builtin_bound_candidates (
1213+ fn assemble_builtin_sized_candidate (
11391214 & mut self ,
1140- conditions : BuiltinImplConditions < ' tcx > ,
1215+ self_ty : Ty < ' tcx > ,
11411216 candidates : & mut SelectionCandidateSet < ' tcx > ,
1217+ sizedness : SizedTraitKind ,
11421218 ) {
1143- match conditions {
1144- BuiltinImplConditions :: Where ( _) => {
1145- candidates. vec . push ( BuiltinCandidate ) ;
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 ) ;
11461244 }
1147- BuiltinImplConditions :: None => { }
1148- 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 ( _) ) => {
11491260 candidates. ambiguous = true ;
11501261 }
1262+
1263+ // Only appears when assembling higher-ranked `for<T> T: Sized`.
1264+ ty:: Bound ( ..) => { }
1265+
1266+ ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
1267+ bug ! ( "asked to assemble builtin bounds of unexpected type: {:?}" , self_ty) ;
1268+ }
11511269 }
11521270 }
11531271
0 commit comments