@@ -1075,24 +1075,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1075
1075
| ty:: Error ( _) => false ,
1076
1076
}
1077
1077
} else if lang_items. pointee_trait ( ) == Some ( trait_ref. def_id ) {
1078
- let tail = selcx. tcx ( ) . struct_tail_with_normalize (
1079
- self_ty,
1080
- |ty| {
1081
- // We throw away any obligations we get from this, since we normalize
1082
- // and confirm these obligations once again during confirmation
1083
- normalize_with_depth (
1084
- selcx,
1085
- obligation. param_env ,
1086
- obligation. cause . clone ( ) ,
1087
- obligation. recursion_depth + 1 ,
1088
- ty,
1089
- )
1090
- . value
1091
- } ,
1092
- || { } ,
1093
- ) ;
1094
-
1095
- match tail. kind ( ) {
1078
+ match self_ty. kind ( ) {
1096
1079
ty:: Bool
1097
1080
| ty:: Char
1098
1081
| ty:: Int ( _)
@@ -1113,21 +1096,17 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
1113
1096
| ty:: Never
1114
1097
// Extern types have unit metadata, according to RFC 2850
1115
1098
| ty:: Foreign ( _)
1116
- // If returned by `struct_tail_without_normalization` this is a unit struct
1117
- // without any fields, or not a struct, and therefore is Sized .
1099
+ // The metadata of an ADT or tuple is the metadata of its tail,
1100
+ // or unit if it has no tail .
1118
1101
| ty:: Adt ( ..)
1119
- // If returned by `struct_tail_without_normalization` this is the empty tuple.
1120
1102
| ty:: Tuple ( ..)
1121
- // Integers and floats are always Sized , and so have unit type metadata.
1103
+ // Integers and floats are always sized , and so have unit type metadata.
1122
1104
| ty:: Infer ( ty:: InferTy :: IntVar ( _) | ty:: InferTy :: FloatVar ( ..) )
1123
- // `{type error}` is sized, so its metadata must be the unit type.
1105
+ // The metadata of `{type error}` is `{ type error}` .
1124
1106
| ty:: Error ( _) => true ,
1125
1107
1126
- // We normalize from `Wrapper<Tail>::Metadata` to `Tail::Metadata`.
1127
- ty:: Param ( _) | ty:: Alias ( ..) => self_ty != tail,
1128
-
1129
- // FIXME: These should probably project to the tail as well.
1130
- ty:: Bound ( ..) | ty:: Placeholder ( ..) => false ,
1108
+ // The metadata of these types can only be known from param env candidates.
1109
+ ty:: Param ( _) | ty:: Alias ( ..) | ty:: Bound ( ..) | ty:: Placeholder ( ..) => false ,
1131
1110
1132
1111
ty:: Infer ( ty:: TyVar ( _) ) => {
1133
1112
candidate_set. mark_ambiguous ( ) ;
@@ -1485,49 +1464,93 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
1485
1464
let lang_items = tcx. lang_items ( ) ;
1486
1465
let item_def_id = obligation. predicate . def_id ;
1487
1466
let trait_def_id = tcx. trait_of_item ( item_def_id) . unwrap ( ) ;
1488
- let ( term, obligations) = if lang_items. discriminant_kind_trait ( ) == Some ( trait_def_id) {
1467
+ let mut potentially_unnormalized = false ;
1468
+ let term = if lang_items. discriminant_kind_trait ( ) == Some ( trait_def_id) {
1489
1469
let discriminant_def_id = tcx. require_lang_item ( LangItem :: Discriminant , None ) ;
1490
1470
assert_eq ! ( discriminant_def_id, item_def_id) ;
1491
1471
1492
- ( self_ty. discriminant_ty ( tcx) . into ( ) , Vec :: new ( ) )
1472
+ self_ty. discriminant_ty ( tcx) . into ( )
1493
1473
} else if lang_items. pointee_trait ( ) == Some ( trait_def_id) {
1494
1474
let metadata_def_id = tcx. require_lang_item ( LangItem :: Metadata , None ) ;
1495
1475
assert_eq ! ( metadata_def_id, item_def_id) ;
1496
1476
1497
- let mut obligations = Vec :: new ( ) ;
1498
- let normalize = |ty| {
1499
- normalize_with_depth_to (
1500
- selcx,
1501
- obligation. param_env ,
1502
- obligation. cause . clone ( ) ,
1503
- obligation. recursion_depth + 1 ,
1504
- ty,
1505
- & mut obligations,
1506
- )
1507
- } ;
1508
- let metadata_ty = self_ty. ptr_metadata_ty_or_tail ( tcx, normalize) . unwrap_or_else ( |tail| {
1509
- if tail == self_ty {
1477
+ let metadata_ty = match self_ty. kind ( ) {
1478
+ ty:: Bool
1479
+ | ty:: Char
1480
+ | ty:: Int ( ..)
1481
+ | ty:: Uint ( ..)
1482
+ | ty:: Float ( ..)
1483
+ | ty:: Array ( ..)
1484
+ | ty:: RawPtr ( ..)
1485
+ | ty:: Ref ( ..)
1486
+ | ty:: FnDef ( ..)
1487
+ | ty:: FnPtr ( ..)
1488
+ | ty:: Closure ( ..)
1489
+ | ty:: CoroutineClosure ( ..)
1490
+ | ty:: Infer ( ty:: IntVar ( ..) | ty:: FloatVar ( ..) )
1491
+ | ty:: Coroutine ( ..)
1492
+ | ty:: CoroutineWitness ( ..)
1493
+ | ty:: Never
1494
+ | ty:: Foreign ( ..)
1495
+ | ty:: Dynamic ( _, _, ty:: DynStar ) => tcx. types . unit ,
1496
+
1497
+ ty:: Error ( e) => Ty :: new_error ( tcx, * e) ,
1498
+
1499
+ ty:: Str | ty:: Slice ( _) => tcx. types . usize ,
1500
+
1501
+ ty:: Dynamic ( _, _, ty:: Dyn ) => {
1502
+ let dyn_metadata = tcx. require_lang_item ( LangItem :: DynMetadata , None ) ;
1503
+ tcx. type_of ( dyn_metadata) . instantiate ( tcx, & [ self_ty. into ( ) ] )
1504
+ }
1505
+
1506
+ // We know that `self_ty` has the same metadata as its tail. This allows us
1507
+ // to prove predicates like `Wrapper<Tail>::Metadata == Tail::Metadata`.
1508
+ ty:: Adt ( def, args) if def. is_struct ( ) => match def. non_enum_variant ( ) . tail_opt ( ) {
1509
+ None => tcx. types . unit ,
1510
+ Some ( tail_def) => {
1511
+ let tail_ty = tail_def. ty ( tcx, args) ;
1512
+ potentially_unnormalized = true ;
1513
+ Ty :: new_projection ( tcx, metadata_def_id, [ tail_ty] )
1514
+ }
1515
+ } ,
1516
+ ty:: Adt ( _, _) => tcx. types . unit ,
1517
+
1518
+ ty:: Tuple ( elements) => match elements. last ( ) {
1519
+ None => tcx. types . unit ,
1520
+ Some ( & tail_ty) => {
1521
+ potentially_unnormalized = true ;
1522
+ Ty :: new_projection ( tcx, metadata_def_id, [ tail_ty] )
1523
+ }
1524
+ } ,
1525
+
1526
+ ty:: Param ( _)
1527
+ | ty:: Alias ( ..)
1528
+ | ty:: Bound ( ..)
1529
+ | ty:: Placeholder ( ..)
1530
+ | ty:: Infer ( ty:: TyVar ( _) | ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
1510
1531
span_bug ! (
1511
1532
obligation. cause. span,
1512
1533
"`<{self_ty:?} as Pointee>::Metadata` projection candidate assembled, \
1513
1534
but we cannot project further",
1514
1535
) ;
1515
1536
}
1516
- // We know that `self_ty` has the same metadata as `tail`. This allows us
1517
- // to prove predicates like `Wrapper<Tail>::Metadata == Tail::Metadata`.
1518
- Ty :: new_projection ( tcx, metadata_def_id, [ tail] )
1519
- } ) ;
1520
- ( metadata_ty. into ( ) , obligations)
1537
+ } ;
1538
+
1539
+ metadata_ty. into ( )
1521
1540
} else {
1522
1541
bug ! ( "unexpected builtin trait with associated type: {:?}" , obligation. predicate) ;
1523
1542
} ;
1524
1543
1525
1544
let predicate =
1526
1545
ty:: ProjectionPredicate { projection_ty : ty:: AliasTy :: new ( tcx, item_def_id, args) , term } ;
1527
1546
1528
- confirm_param_env_candidate ( selcx, obligation, ty:: Binder :: dummy ( predicate) , false )
1529
- . with_addl_obligations ( obligations)
1530
- . with_addl_obligations ( data)
1547
+ confirm_param_env_candidate (
1548
+ selcx,
1549
+ obligation,
1550
+ ty:: Binder :: dummy ( predicate) ,
1551
+ potentially_unnormalized,
1552
+ )
1553
+ . with_addl_obligations ( data)
1531
1554
}
1532
1555
1533
1556
fn confirm_fn_pointer_candidate < ' cx , ' tcx > (
0 commit comments