@@ -12,7 +12,7 @@ use super::SelectionContext;
1212use super :: SelectionError ;
1313use super :: {
1414 ImplSourceClosureData , ImplSourceDiscriminantKindData , ImplSourceFnPointerData ,
15- ImplSourceGeneratorData , ImplSourceUserDefinedData ,
15+ ImplSourceGeneratorData , ImplSourcePointeeData , ImplSourceUserDefinedData ,
1616} ;
1717use super :: { Normalized , NormalizedTy , ProjectionCacheEntry , ProjectionCacheKey } ;
1818
@@ -1069,6 +1069,51 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
10691069 | ty:: Error ( _) => false ,
10701070 }
10711071 }
1072+ super :: ImplSource :: Pointee ( ..) => {
1073+ // While `Pointee` is automatically implemented for every type,
1074+ // the concrete metadata type may not be known yet.
1075+ //
1076+ // Any type with multiple potential metadata types is therefore not eligible.
1077+ let self_ty = selcx. infcx ( ) . shallow_resolve ( obligation. predicate . self_ty ( ) ) ;
1078+
1079+ // FIXME: should this normalize?
1080+ let tail = selcx. tcx ( ) . struct_tail_without_normalization ( self_ty) ;
1081+ match tail. kind ( ) {
1082+ ty:: Bool
1083+ | ty:: Char
1084+ | ty:: Int ( _)
1085+ | ty:: Uint ( _)
1086+ | ty:: Float ( _)
1087+ | ty:: Foreign ( _)
1088+ | ty:: Str
1089+ | ty:: Array ( ..)
1090+ | ty:: Slice ( _)
1091+ | ty:: RawPtr ( ..)
1092+ | ty:: Ref ( ..)
1093+ | ty:: FnDef ( ..)
1094+ | ty:: FnPtr ( ..)
1095+ | ty:: Dynamic ( ..)
1096+ | ty:: Closure ( ..)
1097+ | ty:: Generator ( ..)
1098+ | ty:: GeneratorWitness ( ..)
1099+ | ty:: Never
1100+ // If returned by `struct_tail_without_normalization` this is a unit struct
1101+ // without any fields, or not a struct, and therefore is Sized.
1102+ | ty:: Adt ( ..)
1103+ // If returned by `struct_tail_without_normalization` this is the empty tuple.
1104+ | ty:: Tuple ( ..)
1105+ // Integers and floats are always Sized, and so have unit type metadata.
1106+ | ty:: Infer ( ty:: InferTy :: IntVar ( _) | ty:: InferTy :: FloatVar ( ..) ) => true ,
1107+
1108+ ty:: Projection ( ..)
1109+ | ty:: Opaque ( ..)
1110+ | ty:: Param ( ..)
1111+ | ty:: Bound ( ..)
1112+ | ty:: Placeholder ( ..)
1113+ | ty:: Infer ( ..)
1114+ | ty:: Error ( _) => false ,
1115+ }
1116+ }
10721117 super :: ImplSource :: Param ( ..) => {
10731118 // This case tell us nothing about the value of an
10741119 // associated type. Consider:
@@ -1169,6 +1214,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
11691214 super :: ImplSource :: DiscriminantKind ( data) => {
11701215 confirm_discriminant_kind_candidate ( selcx, obligation, data)
11711216 }
1217+ super :: ImplSource :: Pointee ( data) => confirm_pointee_candidate ( selcx, obligation, data) ,
11721218 super :: ImplSource :: Object ( _)
11731219 | super :: ImplSource :: AutoImpl ( ..)
11741220 | super :: ImplSource :: Param ( ..)
@@ -1256,6 +1302,26 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
12561302 confirm_param_env_candidate ( selcx, obligation, ty:: Binder :: dummy ( predicate) , false )
12571303}
12581304
1305+ fn confirm_pointee_candidate < ' cx , ' tcx > (
1306+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
1307+ obligation : & ProjectionTyObligation < ' tcx > ,
1308+ _: ImplSourcePointeeData ,
1309+ ) -> Progress < ' tcx > {
1310+ let tcx = selcx. tcx ( ) ;
1311+
1312+ let self_ty = selcx. infcx ( ) . shallow_resolve ( obligation. predicate . self_ty ( ) ) ;
1313+ let substs = tcx. mk_substs ( [ self_ty. into ( ) ] . iter ( ) ) ;
1314+
1315+ let metadata_def_id = tcx. require_lang_item ( LangItem :: Metadata , None ) ;
1316+
1317+ let predicate = ty:: ProjectionPredicate {
1318+ projection_ty : ty:: ProjectionTy { substs, item_def_id : metadata_def_id } ,
1319+ ty : self_ty. ptr_metadata_ty ( tcx) ,
1320+ } ;
1321+
1322+ confirm_param_env_candidate ( selcx, obligation, ty:: Binder :: bind ( predicate) , false )
1323+ }
1324+
12591325fn confirm_fn_pointer_candidate < ' cx , ' tcx > (
12601326 selcx : & mut SelectionContext < ' cx , ' tcx > ,
12611327 obligation : & ProjectionTyObligation < ' tcx > ,
0 commit comments