@@ -1075,24 +1075,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
10751075 | ty:: Error ( _) => false ,
10761076 }
10771077 } 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 ( ) {
10961079 ty:: Bool
10971080 | ty:: Char
10981081 | ty:: Int ( _)
@@ -1113,21 +1096,17 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
11131096 | ty:: Never
11141097 // Extern types have unit metadata, according to RFC 2850
11151098 | 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 .
11181101 | ty:: Adt ( ..)
1119- // If returned by `struct_tail_without_normalization` this is the empty tuple.
11201102 | 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.
11221104 | 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}` .
11241106 | ty:: Error ( _) => true ,
11251107
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 ,
11311110
11321111 ty:: Infer ( ty:: TyVar ( _) ) => {
11331112 candidate_set. mark_ambiguous ( ) ;
@@ -1485,49 +1464,93 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
14851464 let lang_items = tcx. lang_items ( ) ;
14861465 let item_def_id = obligation. predicate . def_id ;
14871466 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) {
14891469 let discriminant_def_id = tcx. require_lang_item ( LangItem :: Discriminant , None ) ;
14901470 assert_eq ! ( discriminant_def_id, item_def_id) ;
14911471
1492- ( self_ty. discriminant_ty ( tcx) . into ( ) , Vec :: new ( ) )
1472+ self_ty. discriminant_ty ( tcx) . into ( )
14931473 } else if lang_items. pointee_trait ( ) == Some ( trait_def_id) {
14941474 let metadata_def_id = tcx. require_lang_item ( LangItem :: Metadata , None ) ;
14951475 assert_eq ! ( metadata_def_id, item_def_id) ;
14961476
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 ( _) ) => {
15101531 span_bug ! (
15111532 obligation. cause. span,
15121533 "`<{self_ty:?} as Pointee>::Metadata` projection candidate assembled, \
15131534 but we cannot project further",
15141535 ) ;
15151536 }
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 ( )
15211540 } else {
15221541 bug ! ( "unexpected builtin trait with associated type: {:?}" , obligation. predicate) ;
15231542 } ;
15241543
15251544 let predicate =
15261545 ty:: ProjectionPredicate { projection_ty : ty:: AliasTy :: new ( tcx, item_def_id, args) , term } ;
15271546
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)
15311554}
15321555
15331556fn confirm_fn_pointer_candidate < ' cx , ' tcx > (
0 commit comments