@@ -145,11 +145,11 @@ pub enum CopyImplementationError<'tcx> {
145145///
146146/// The ordering of the cases is significant. They are sorted so that cmp::max
147147/// will keep the "more erroneous" of two values.
148- #[ derive( Copy , Clone , PartialOrd , Ord , Eq , PartialEq , Debug ) ]
148+ #[ derive( Clone , PartialOrd , Ord , Eq , PartialEq , Debug ) ]
149149pub enum Representability {
150150 Representable ,
151151 ContainsRecursive ,
152- SelfRecursive ,
152+ SelfRecursive ( Vec < Span > ) ,
153153}
154154
155155impl < ' tcx > ParameterEnvironment < ' tcx > {
@@ -1003,37 +1003,51 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
10031003
10041004 /// Check whether a type is representable. This means it cannot contain unboxed
10051005 /// structural recursion. This check is needed for structs and enums.
1006- pub fn is_representable ( & ' tcx self , tcx : TyCtxt < ' a , ' tcx , ' tcx > , sp : Span )
1006+ pub fn is_representable ( & ' tcx self ,
1007+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
1008+ sp : Span )
10071009 -> Representability {
10081010
10091011 // Iterate until something non-representable is found
1010- fn find_nonrepresentable < ' a , ' tcx , It > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
1011- sp : Span ,
1012- seen : & mut Vec < Ty < ' tcx > > ,
1013- iter : It )
1014- -> Representability
1015- where It : Iterator < Item =Ty < ' tcx > > {
1016- iter. fold ( Representability :: Representable ,
1017- |r, ty| cmp:: max ( r, is_type_structurally_recursive ( tcx, sp, seen, ty) ) )
1012+ fn fold_repr < It : Iterator < Item =Representability > > ( iter : It ) -> Representability {
1013+ iter. fold ( Representability :: Representable , |r1, r2| {
1014+ match ( r1, r2) {
1015+ ( Representability :: SelfRecursive ( v1) ,
1016+ Representability :: SelfRecursive ( v2) ) => {
1017+ Representability :: SelfRecursive ( v1. iter ( ) . map ( |s| * s) . chain ( v2) . collect ( ) )
1018+ }
1019+ ( r1, r2) => cmp:: max ( r1, r2)
1020+ }
1021+ } )
10181022 }
10191023
10201024 fn are_inner_types_recursive < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , sp : Span ,
10211025 seen : & mut Vec < Ty < ' tcx > > , ty : Ty < ' tcx > )
10221026 -> Representability {
10231027 match ty. sty {
10241028 TyTuple ( ref ts, _) => {
1025- find_nonrepresentable ( tcx, sp, seen, ts. iter ( ) . cloned ( ) )
1029+ // Find non representable
1030+ fold_repr ( ts. iter ( ) . map ( |ty| {
1031+ is_type_structurally_recursive ( tcx, sp, seen, ty)
1032+ } ) )
10261033 }
10271034 // Fixed-length vectors.
10281035 // FIXME(#11924) Behavior undecided for zero-length vectors.
10291036 TyArray ( ty, _) => {
10301037 is_type_structurally_recursive ( tcx, sp, seen, ty)
10311038 }
10321039 TyAdt ( def, substs) => {
1033- find_nonrepresentable ( tcx,
1034- sp,
1035- seen,
1036- def. all_fields ( ) . map ( |f| f. ty ( tcx, substs) ) )
1040+ // Find non representable fields with their spans
1041+ fold_repr ( def. all_fields ( ) . map ( |field| {
1042+ let ty = field. ty ( tcx, substs) ;
1043+ let span = tcx. hir . span_if_local ( field. did ) . unwrap_or ( sp) ;
1044+ match is_type_structurally_recursive ( tcx, span, seen, ty) {
1045+ Representability :: SelfRecursive ( _) => {
1046+ Representability :: SelfRecursive ( vec ! [ span] )
1047+ }
1048+ x => x,
1049+ }
1050+ } ) )
10371051 }
10381052 TyClosure ( ..) => {
10391053 // this check is run on type definitions, so we don't expect
@@ -1072,7 +1086,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
10721086 sp : Span ,
10731087 seen : & mut Vec < Ty < ' tcx > > ,
10741088 ty : Ty < ' tcx > ) -> Representability {
1075- debug ! ( "is_type_structurally_recursive: {:?}" , ty) ;
1089+ debug ! ( "is_type_structurally_recursive: {:?} {:?} " , ty, sp ) ;
10761090
10771091 match ty. sty {
10781092 TyAdt ( def, _) => {
@@ -1093,7 +1107,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
10931107 debug ! ( "SelfRecursive: {:?} contains {:?}" ,
10941108 seen_type,
10951109 ty) ;
1096- return Representability :: SelfRecursive ;
1110+ return Representability :: SelfRecursive ( vec ! [ sp ] ) ;
10971111 }
10981112 }
10991113
0 commit comments