@@ -1399,6 +1399,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1399
1399
let self_ty = selcx. infcx ( ) . shallow_resolve ( obligation. predicate . self_ty ( ) ) ;
1400
1400
1401
1401
let tail = selcx. tcx ( ) . struct_tail_with_normalize ( self_ty, |ty| {
1402
+ // We throw away any obligations we get from this, since we normalize
1403
+ // and confirm these obligations once again during confirmation
1402
1404
normalize_with_depth (
1403
1405
selcx,
1404
1406
obligation. param_env ,
@@ -1415,7 +1417,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1415
1417
| ty:: Int ( _)
1416
1418
| ty:: Uint ( _)
1417
1419
| ty:: Float ( _)
1418
- | ty:: Foreign ( _)
1419
1420
| ty:: Str
1420
1421
| ty:: Array ( ..)
1421
1422
| ty:: Slice ( _)
@@ -1428,6 +1429,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1428
1429
| ty:: Generator ( ..)
1429
1430
| ty:: GeneratorWitness ( ..)
1430
1431
| ty:: Never
1432
+ // Extern types have unit metadata, according to RFC 2850
1433
+ | ty:: Foreign ( _)
1431
1434
// If returned by `struct_tail_without_normalization` this is a unit struct
1432
1435
// without any fields, or not a struct, and therefore is Sized.
1433
1436
| ty:: Adt ( ..)
@@ -1436,9 +1439,10 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1436
1439
// Integers and floats are always Sized, and so have unit type metadata.
1437
1440
| ty:: Infer ( ty:: InferTy :: IntVar ( _) | ty:: InferTy :: FloatVar ( ..) ) => true ,
1438
1441
1439
- ty:: Projection ( ..)
1440
- | ty:: Opaque ( ..)
1441
- | ty:: Param ( ..)
1442
+ // type parameters and unnormalized projections have pointer metadata if they're still known to be sized
1443
+ ty:: Param ( _) | ty:: Projection ( ..) => tail. is_sized ( selcx. tcx ( ) . at ( obligation. cause . span ) , obligation. param_env ) ,
1444
+
1445
+ ty:: Opaque ( ..)
1442
1446
| ty:: Bound ( ..)
1443
1447
| ty:: Placeholder ( ..)
1444
1448
| ty:: Infer ( ..)
@@ -1657,7 +1661,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
1657
1661
let self_ty = selcx. infcx ( ) . shallow_resolve ( obligation. predicate . self_ty ( ) ) ;
1658
1662
1659
1663
let mut obligations = vec ! [ ] ;
1660
- let metadata_ty = self_ty. ptr_metadata_ty ( tcx, |ty| {
1664
+ let ( metadata_ty, check_is_sized ) = self_ty. ptr_metadata_ty ( tcx, |ty| {
1661
1665
normalize_with_depth_to (
1662
1666
selcx,
1663
1667
obligation. param_env ,
@@ -1667,6 +1671,19 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
1667
1671
& mut obligations,
1668
1672
)
1669
1673
} ) ;
1674
+ if check_is_sized {
1675
+ let sized_predicate = ty:: Binder :: dummy ( ty:: TraitRef :: new (
1676
+ tcx. require_lang_item ( LangItem :: Sized , None ) ,
1677
+ tcx. mk_substs_trait ( self_ty, & [ ] ) ,
1678
+ ) )
1679
+ . without_const ( )
1680
+ . to_predicate ( tcx) ;
1681
+ obligations. push ( Obligation :: new (
1682
+ obligation. cause . clone ( ) ,
1683
+ obligation. param_env ,
1684
+ sized_predicate,
1685
+ ) ) ;
1686
+ }
1670
1687
1671
1688
let substs = tcx. mk_substs ( [ self_ty. into ( ) ] . iter ( ) ) ;
1672
1689
let metadata_def_id = tcx. require_lang_item ( LangItem :: Metadata , None ) ;
0 commit comments