@@ -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,163 @@ 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 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+ }
11271172 }
1128- BuiltinImplConditions :: None => { }
1129- BuiltinImplConditions :: Ambiguous => {
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+ }
1183+ }
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 ( _) ) => {
11301200 candidates. ambiguous = true ;
11311201 }
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+ }
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+ 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+ }
11511268 }
11521269 }
11531270
0 commit comments