@@ -1469,6 +1469,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1469
1469
let self_ty = selcx. infcx ( ) . shallow_resolve ( obligation. predicate . self_ty ( ) ) ;
1470
1470
1471
1471
let tail = selcx. tcx ( ) . struct_tail_with_normalize ( self_ty, |ty| {
1472
+ // We throw away any obligations we get from this, since we normalize
1473
+ // and confirm these obligations once again during confirmation
1472
1474
normalize_with_depth (
1473
1475
selcx,
1474
1476
obligation. param_env ,
@@ -1485,7 +1487,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1485
1487
| ty:: Int ( _)
1486
1488
| ty:: Uint ( _)
1487
1489
| ty:: Float ( _)
1488
- | ty:: Foreign ( _)
1489
1490
| ty:: Str
1490
1491
| ty:: Array ( ..)
1491
1492
| ty:: Slice ( _)
@@ -1498,6 +1499,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1498
1499
| ty:: Generator ( ..)
1499
1500
| ty:: GeneratorWitness ( ..)
1500
1501
| ty:: Never
1502
+ // Extern types have unit metadata, according to RFC 2850
1503
+ | ty:: Foreign ( _)
1501
1504
// If returned by `struct_tail_without_normalization` this is a unit struct
1502
1505
// without any fields, or not a struct, and therefore is Sized.
1503
1506
| ty:: Adt ( ..)
@@ -1506,9 +1509,18 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1506
1509
// Integers and floats are always Sized, and so have unit type metadata.
1507
1510
| ty:: Infer ( ty:: InferTy :: IntVar ( _) | ty:: InferTy :: FloatVar ( ..) ) => true ,
1508
1511
1509
- ty:: Projection ( ..)
1512
+ // type parameters, opaques, and unnormalized projections have pointer
1513
+ // metadata if they're known (e.g. by the param_env) to be sized
1514
+ ty:: Param ( _) | ty:: Projection ( ..) | ty:: Opaque ( ..)
1515
+ if tail. is_sized ( selcx. tcx ( ) . at ( obligation. cause . span ) , obligation. param_env ) =>
1516
+ {
1517
+ true
1518
+ }
1519
+
1520
+ // FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
1521
+ ty:: Param ( _)
1522
+ | ty:: Projection ( ..)
1510
1523
| ty:: Opaque ( ..)
1511
- | ty:: Param ( ..)
1512
1524
| ty:: Bound ( ..)
1513
1525
| ty:: Placeholder ( ..)
1514
1526
| ty:: Infer ( ..)
@@ -1517,7 +1529,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1517
1529
candidate_set. mark_ambiguous ( ) ;
1518
1530
}
1519
1531
false
1520
- } ,
1532
+ }
1521
1533
}
1522
1534
}
1523
1535
super :: ImplSource :: Param ( ..) => {
@@ -1727,7 +1739,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
1727
1739
let self_ty = selcx. infcx ( ) . shallow_resolve ( obligation. predicate . self_ty ( ) ) ;
1728
1740
1729
1741
let mut obligations = vec ! [ ] ;
1730
- let metadata_ty = self_ty. ptr_metadata_ty ( tcx, |ty| {
1742
+ let ( metadata_ty, check_is_sized ) = self_ty. ptr_metadata_ty ( tcx, |ty| {
1731
1743
normalize_with_depth_to (
1732
1744
selcx,
1733
1745
obligation. param_env ,
@@ -1737,6 +1749,19 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
1737
1749
& mut obligations,
1738
1750
)
1739
1751
} ) ;
1752
+ if check_is_sized {
1753
+ let sized_predicate = ty:: Binder :: dummy ( ty:: TraitRef :: new (
1754
+ tcx. require_lang_item ( LangItem :: Sized , None ) ,
1755
+ tcx. mk_substs_trait ( self_ty, & [ ] ) ,
1756
+ ) )
1757
+ . without_const ( )
1758
+ . to_predicate ( tcx) ;
1759
+ obligations. push ( Obligation :: new (
1760
+ obligation. cause . clone ( ) ,
1761
+ obligation. param_env ,
1762
+ sized_predicate,
1763
+ ) ) ;
1764
+ }
1740
1765
1741
1766
let substs = tcx. mk_substs ( [ self_ty. into ( ) ] . iter ( ) ) ;
1742
1767
let metadata_def_id = tcx. require_lang_item ( LangItem :: Metadata , None ) ;
0 commit comments