@@ -145,11 +145,11 @@ pub enum CopyImplementationError<'tcx> {
145
145
///
146
146
/// The ordering of the cases is significant. They are sorted so that cmp::max
147
147
/// 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 ) ]
149
149
pub enum Representability {
150
150
Representable ,
151
151
ContainsRecursive ,
152
- SelfRecursive ,
152
+ SelfRecursive ( Vec < Span > ) ,
153
153
}
154
154
155
155
impl < ' tcx > ParameterEnvironment < ' tcx > {
@@ -1003,37 +1003,51 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
1003
1003
1004
1004
/// Check whether a type is representable. This means it cannot contain unboxed
1005
1005
/// 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 )
1007
1009
-> Representability {
1008
1010
1009
1011
// 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
+ } )
1018
1022
}
1019
1023
1020
1024
fn are_inner_types_recursive < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , sp : Span ,
1021
1025
seen : & mut Vec < Ty < ' tcx > > , ty : Ty < ' tcx > )
1022
1026
-> Representability {
1023
1027
match ty. sty {
1024
1028
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
+ } ) )
1026
1033
}
1027
1034
// Fixed-length vectors.
1028
1035
// FIXME(#11924) Behavior undecided for zero-length vectors.
1029
1036
TyArray ( ty, _) => {
1030
1037
is_type_structurally_recursive ( tcx, sp, seen, ty)
1031
1038
}
1032
1039
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
+ } ) )
1037
1051
}
1038
1052
TyClosure ( ..) => {
1039
1053
// this check is run on type definitions, so we don't expect
@@ -1072,7 +1086,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
1072
1086
sp : Span ,
1073
1087
seen : & mut Vec < Ty < ' tcx > > ,
1074
1088
ty : Ty < ' tcx > ) -> Representability {
1075
- debug ! ( "is_type_structurally_recursive: {:?}" , ty) ;
1089
+ debug ! ( "is_type_structurally_recursive: {:?} {:?} " , ty, sp ) ;
1076
1090
1077
1091
match ty. sty {
1078
1092
TyAdt ( def, _) => {
@@ -1093,7 +1107,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
1093
1107
debug ! ( "SelfRecursive: {:?} contains {:?}" ,
1094
1108
seen_type,
1095
1109
ty) ;
1096
- return Representability :: SelfRecursive ;
1110
+ return Representability :: SelfRecursive ( vec ! [ sp ] ) ;
1097
1111
}
1098
1112
}
1099
1113
0 commit comments