@@ -152,6 +152,8 @@ enum SelectionCandidate<'tcx> {
152
152
153
153
ObjectCandidate ,
154
154
155
+ BuiltinObjectCandidate ,
156
+
155
157
ErrorCandidate ,
156
158
}
157
159
@@ -818,21 +820,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
818
820
debug ! ( "obligation self ty is {}" ,
819
821
obligation. predicate. 0 . self_ty( ) . repr( self . tcx( ) ) ) ;
820
822
823
+ // User-defined copy impls are permitted, but only for
824
+ // structs and enums.
821
825
try!( self . assemble_candidates_from_impls ( obligation, & mut candidates) ) ;
822
826
827
+ // For other types, we'll use the builtin rules.
823
828
try!( self . assemble_builtin_bound_candidates ( ty:: BoundCopy ,
824
829
stack,
825
830
& mut candidates) ) ;
826
831
}
827
832
Some ( bound @ ty:: BoundSized ) => {
828
- // Sized and Copy are always automatically computed.
833
+ // Sized is never implementable by end-users, it is
834
+ // always automatically computed.
829
835
try!( self . assemble_builtin_bound_candidates ( bound, stack, & mut candidates) ) ;
830
836
}
831
837
832
- _ => {
833
- // For the time being, we ignore user-defined impls for builtin-bounds, other than
834
- // `Copy`.
835
- // (And unboxed candidates only apply to the Fn/FnMut/etc traits.)
838
+ Some ( ty:: BoundSend ) |
839
+ Some ( ty:: BoundSync ) |
840
+ None => {
836
841
try!( self . assemble_closure_candidates ( obligation, & mut candidates) ) ;
837
842
try!( self . assemble_fn_pointer_candidates ( obligation, & mut candidates) ) ;
838
843
try!( self . assemble_candidates_from_impls ( obligation, & mut candidates) ) ;
@@ -1178,7 +1183,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1178
1183
if data. bounds . builtin_bounds . contains ( & bound) {
1179
1184
debug ! ( "assemble_candidates_from_object_ty: matched builtin bound, \
1180
1185
pushing candidate") ;
1181
- candidates. vec . push ( BuiltinCandidate ( bound ) ) ;
1186
+ candidates. vec . push ( BuiltinObjectCandidate ) ;
1182
1187
return ;
1183
1188
}
1184
1189
}
@@ -1272,6 +1277,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1272
1277
( & ImplCandidate ( ..) , & ParamCandidate ( ..) ) |
1273
1278
( & ClosureCandidate ( ..) , & ParamCandidate ( ..) ) |
1274
1279
( & FnPointerCandidate ( ..) , & ParamCandidate ( ..) ) |
1280
+ ( & BuiltinObjectCandidate ( ..) , & ParamCandidate ( _) ) |
1275
1281
( & BuiltinCandidate ( ..) , & ParamCandidate ( ..) ) => {
1276
1282
// We basically prefer always prefer to use a
1277
1283
// where-clause over another option. Where clauses
@@ -1359,7 +1365,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1359
1365
Ok ( If ( Vec :: new ( ) ) )
1360
1366
}
1361
1367
1362
- ty:: ty_uniq( referent_ty ) => { // Box<T>
1368
+ ty:: ty_uniq( _ ) => { // Box<T>
1363
1369
match bound {
1364
1370
ty:: BoundCopy => {
1365
1371
Err ( Unimplemented )
@@ -1369,26 +1375,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1369
1375
Ok ( If ( Vec :: new ( ) ) )
1370
1376
}
1371
1377
1372
- ty:: BoundSync |
1373
- ty:: BoundSend => {
1374
- Ok ( If ( vec ! [ referent_ty] ) )
1378
+ ty:: BoundSync | ty:: BoundSend => {
1379
+ self . tcx ( ) . sess . bug ( "Send/Sync shouldn't occur in builtin_bounds()" ) ;
1375
1380
}
1376
1381
}
1377
1382
}
1378
1383
1379
1384
ty:: ty_ptr( ..) => { // *const T, *mut T
1380
1385
match bound {
1381
- ty:: BoundCopy |
1382
- ty:: BoundSized => {
1386
+ ty:: BoundCopy | ty:: BoundSized => {
1383
1387
Ok ( If ( Vec :: new ( ) ) )
1384
1388
}
1385
1389
1386
- ty:: BoundSync |
1387
- ty:: BoundSend => {
1388
- self . tcx ( ) . sess . bug (
1389
- & format ! (
1390
- "raw pointers should have a negative \
1391
- impl for `Send` and `Sync`") [ ] ) ;
1390
+ ty:: BoundSync | ty:: BoundSend => {
1391
+ self . tcx ( ) . sess . bug ( "Send/Sync shouldn't occur in builtin_bounds()" ) ;
1392
1392
}
1393
1393
}
1394
1394
}
@@ -1398,7 +1398,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1398
1398
ty:: BoundSized => {
1399
1399
Err ( Unimplemented )
1400
1400
}
1401
- ty:: BoundCopy | ty :: BoundSync | ty :: BoundSend => {
1401
+ ty:: BoundCopy => {
1402
1402
if data. bounds . builtin_bounds . contains ( & bound) {
1403
1403
Ok ( If ( Vec :: new ( ) ) )
1404
1404
} else {
@@ -1417,6 +1417,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1417
1417
Err ( Unimplemented )
1418
1418
}
1419
1419
}
1420
+ ty:: BoundSync | ty:: BoundSend => {
1421
+ self . tcx ( ) . sess . bug ( "Send/Sync shouldn't occur in builtin_bounds()" ) ;
1422
+ }
1420
1423
}
1421
1424
}
1422
1425
@@ -1441,9 +1444,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1441
1444
Ok ( If ( Vec :: new ( ) ) )
1442
1445
}
1443
1446
1444
- ty:: BoundSync |
1445
- ty:: BoundSend => {
1446
- Ok ( If ( vec ! [ referent_ty] ) )
1447
+ ty:: BoundSync | ty:: BoundSend => {
1448
+ self . tcx ( ) . sess . bug ( "Send/Sync shouldn't occur in builtin_bounds()" ) ;
1447
1449
}
1448
1450
}
1449
1451
}
@@ -1472,23 +1474,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1472
1474
}
1473
1475
}
1474
1476
1475
- ty:: BoundSync |
1476
- ty:: BoundSend => {
1477
- Ok ( If ( vec ! [ element_ty] ) )
1477
+ ty:: BoundSync | ty:: BoundSend => {
1478
+ self . tcx ( ) . sess . bug ( "Send/Sync shouldn't occur in builtin_bounds()" ) ;
1478
1479
}
1479
1480
}
1480
1481
}
1481
1482
1482
1483
ty:: ty_str => {
1483
1484
// Equivalent to [u8]
1484
1485
match bound {
1485
- ty:: BoundSync |
1486
- ty:: BoundSend => {
1487
- Ok ( If ( Vec :: new ( ) ) )
1486
+ ty:: BoundSync | ty:: BoundSend => {
1487
+ self . tcx ( ) . sess . bug ( "Send/Sync shouldn't occur in builtin_bounds()" ) ;
1488
1488
}
1489
1489
1490
- ty:: BoundCopy |
1491
- ty:: BoundSized => {
1490
+ ty:: BoundCopy | ty:: BoundSized => {
1492
1491
Err ( Unimplemented )
1493
1492
}
1494
1493
}
@@ -1576,15 +1575,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1576
1575
// "opened" unsized/existential type (one that has
1577
1576
// been dereferenced)
1578
1577
match bound {
1579
- ty:: BoundCopy |
1580
- ty:: BoundSync |
1581
- ty:: BoundSend => {
1578
+ ty:: BoundCopy => {
1582
1579
Ok ( If ( vec ! ( ty) ) )
1583
1580
}
1584
1581
1585
1582
ty:: BoundSized => {
1586
1583
Err ( Unimplemented )
1587
1584
}
1585
+
1586
+ ty:: BoundSync |
1587
+ ty:: BoundSend => {
1588
+ self . tcx ( ) . sess . bug ( "Send/Sync shouldn't occur in builtin_bounds()" ) ;
1589
+ }
1588
1590
}
1589
1591
}
1590
1592
ty:: ty_err => {
@@ -1606,16 +1608,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1606
1608
{
1607
1609
// First check for markers and other nonsense.
1608
1610
match bound {
1609
- ty:: BoundCopy => {
1610
- return Ok ( ParameterBuiltin )
1611
- }
1611
+ // Fallback to whatever user-defined impls exist in this case.
1612
+ ty:: BoundCopy => Ok ( ParameterBuiltin ) ,
1612
1613
1613
- ty:: BoundSend |
1614
- ty:: BoundSync |
1615
- ty:: BoundSized => { }
1616
- }
1614
+ // Sized if all the component types are sized.
1615
+ ty:: BoundSized => Ok ( If ( types) ) ,
1617
1616
1618
- Ok ( If ( types) )
1617
+ // Shouldn't be coming through here.
1618
+ ty:: BoundSend | ty:: BoundSync => unreachable ! ( ) ,
1619
+ }
1619
1620
}
1620
1621
}
1621
1622
@@ -1739,6 +1740,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1739
1740
Ok ( VtableClosure ( closure_def_id, substs) )
1740
1741
}
1741
1742
1743
+ BuiltinObjectCandidate => {
1744
+ // This indicates something like `(Trait+Send) :
1745
+ // Send`. In this case, we know that this holds
1746
+ // because that's what the object type is telling us,
1747
+ // and there's really no additional obligations to
1748
+ // prove and no types in particular to unify etc.
1749
+ Ok ( VtableParam ( Vec :: new ( ) ) )
1750
+ }
1751
+
1742
1752
ObjectCandidate => {
1743
1753
let data = self . confirm_object_candidate ( obligation) ;
1744
1754
Ok ( VtableObject ( data) )
@@ -2449,6 +2459,7 @@ impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
2449
2459
PhantomFnCandidate => format ! ( "PhantomFnCandidate" ) ,
2450
2460
ErrorCandidate => format ! ( "ErrorCandidate" ) ,
2451
2461
BuiltinCandidate ( b) => format ! ( "BuiltinCandidate({:?})" , b) ,
2462
+ BuiltinObjectCandidate => format ! ( "BuiltinObjectCandidate" ) ,
2452
2463
ParamCandidate ( ref a) => format ! ( "ParamCandidate({})" , a. repr( tcx) ) ,
2453
2464
ImplCandidate ( a) => format ! ( "ImplCandidate({})" , a. repr( tcx) ) ,
2454
2465
DefaultImplCandidate ( t) => format ! ( "DefaultImplCandidate({:?})" , t) ,
0 commit comments