@@ -17,12 +17,20 @@ use std::cmp;
1717pub enum Representability {
1818 Representable ,
1919 ContainsRecursive ,
20- SelfRecursive ( Vec < Span > ) ,
20+ /// Return a list of types that are included in themselves:
21+ /// the spans where they are self-included, and (if found)
22+ /// the HirId of the FieldDef that defines the self-inclusion.
23+ SelfRecursive ( Vec < ( Span , Option < hir:: HirId > ) > ) ,
2124}
2225
2326/// Check whether a type is representable. This means it cannot contain unboxed
2427/// structural recursion. This check is needed for structs and enums.
25- pub fn ty_is_representable < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , sp : Span ) -> Representability {
28+ pub fn ty_is_representable < ' tcx > (
29+ tcx : TyCtxt < ' tcx > ,
30+ ty : Ty < ' tcx > ,
31+ sp : Span ,
32+ field_id : Option < hir:: HirId > ,
33+ ) -> Representability {
2634 debug ! ( "is_type_representable: {:?}" , ty) ;
2735 // To avoid a stack overflow when checking an enum variant or struct that
2836 // contains a different, structurally recursive type, maintain a stack of
@@ -38,11 +46,12 @@ pub fn ty_is_representable<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, sp: Span) -> R
3846 let mut force_result = false ;
3947 let r = is_type_structurally_recursive (
4048 tcx,
41- sp,
4249 & mut seen,
4350 & mut shadow_seen,
4451 & mut representable_cache,
4552 ty,
53+ sp,
54+ field_id,
4655 & mut force_result,
4756 ) ;
4857 debug ! ( "is_type_representable: {:?} is {:?}" , ty, r) ;
@@ -61,11 +70,12 @@ fn fold_repr<It: Iterator<Item = Representability>>(iter: It) -> Representabilit
6170
6271fn are_inner_types_recursive < ' tcx > (
6372 tcx : TyCtxt < ' tcx > ,
64- sp : Span ,
6573 seen : & mut Vec < Ty < ' tcx > > ,
6674 shadow_seen : & mut Vec < ty:: AdtDef < ' tcx > > ,
6775 representable_cache : & mut FxHashMap < Ty < ' tcx > , Representability > ,
6876 ty : Ty < ' tcx > ,
77+ sp : Span ,
78+ field_id : Option < hir:: HirId > ,
6979 force_result : & mut bool ,
7080) -> Representability {
7181 debug ! ( "are_inner_types_recursive({:?}, {:?}, {:?})" , ty, seen, shadow_seen) ;
@@ -75,11 +85,12 @@ fn are_inner_types_recursive<'tcx>(
7585 fold_repr ( fields. iter ( ) . map ( |ty| {
7686 is_type_structurally_recursive (
7787 tcx,
78- sp,
7988 seen,
8089 shadow_seen,
8190 representable_cache,
8291 ty,
92+ sp,
93+ field_id,
8394 force_result,
8495 )
8596 } ) )
@@ -88,20 +99,26 @@ fn are_inner_types_recursive<'tcx>(
8899 // FIXME(#11924) Behavior undecided for zero-length vectors.
89100 ty:: Array ( ty, _) => is_type_structurally_recursive (
90101 tcx,
91- sp,
92102 seen,
93103 shadow_seen,
94104 representable_cache,
95105 * ty,
106+ sp,
107+ field_id,
96108 force_result,
97109 ) ,
98110 ty:: Adt ( def, substs) => {
99111 // Find non representable fields with their spans
100112 fold_repr ( def. all_fields ( ) . map ( |field| {
101113 let ty = field. ty ( tcx, substs) ;
102- let span = match field. did . as_local ( ) . and_then ( |id| tcx. hir ( ) . find_by_def_id ( id) ) {
103- Some ( hir:: Node :: Field ( field) ) => field. ty . span ,
104- _ => sp,
114+ let ( sp, field_id) = match field
115+ . did
116+ . as_local ( )
117+ . map ( |id| tcx. hir ( ) . local_def_id_to_hir_id ( id) )
118+ . and_then ( |id| tcx. hir ( ) . find ( id) )
119+ {
120+ Some ( hir:: Node :: Field ( field) ) => ( field. ty . span , Some ( field. hir_id ) ) ,
121+ _ => ( sp, field_id) ,
105122 } ;
106123
107124 let mut result = None ;
@@ -130,7 +147,7 @@ fn are_inner_types_recursive<'tcx>(
130147 // result without adjusting).
131148 if shadow_seen. len ( ) > seen. len ( ) && shadow_seen. first ( ) == Some ( def) {
132149 * force_result = true ;
133- result = Some ( Representability :: SelfRecursive ( vec ! [ span ] ) ) ;
150+ result = Some ( Representability :: SelfRecursive ( vec ! [ ( sp , field_id ) ] ) ) ;
134151 }
135152
136153 if result == None {
@@ -161,16 +178,17 @@ fn are_inner_types_recursive<'tcx>(
161178 result = Some (
162179 match is_type_structurally_recursive (
163180 tcx,
164- span,
165181 & mut nested_seen,
166182 shadow_seen,
167183 representable_cache,
168184 raw_adt_ty,
185+ sp,
186+ field_id,
169187 force_result,
170188 ) {
171189 Representability :: SelfRecursive ( _) => {
172190 if * force_result {
173- Representability :: SelfRecursive ( vec ! [ span ] )
191+ Representability :: SelfRecursive ( vec ! [ ( sp , field_id ) ] )
174192 } else {
175193 Representability :: ContainsRecursive
176194 }
@@ -208,15 +226,16 @@ fn are_inner_types_recursive<'tcx>(
208226 result = Some (
209227 match is_type_structurally_recursive (
210228 tcx,
211- span,
212229 seen,
213230 shadow_seen,
214231 representable_cache,
215232 ty,
233+ sp,
234+ field_id,
216235 force_result,
217236 ) {
218237 Representability :: SelfRecursive ( _) => {
219- Representability :: SelfRecursive ( vec ! [ span ] )
238+ Representability :: SelfRecursive ( vec ! [ ( sp , field_id ) ] )
220239 }
221240 x => x,
222241 } ,
@@ -247,29 +266,31 @@ fn same_adt<'tcx>(ty: Ty<'tcx>, def: ty::AdtDef<'tcx>) -> bool {
247266// contain any types on stack `seen`?
248267fn is_type_structurally_recursive < ' tcx > (
249268 tcx : TyCtxt < ' tcx > ,
250- sp : Span ,
251269 seen : & mut Vec < Ty < ' tcx > > ,
252270 shadow_seen : & mut Vec < ty:: AdtDef < ' tcx > > ,
253271 representable_cache : & mut FxHashMap < Ty < ' tcx > , Representability > ,
254272 ty : Ty < ' tcx > ,
273+ sp : Span ,
274+ field_id : Option < hir:: HirId > ,
255275 force_result : & mut bool ,
256276) -> Representability {
257- debug ! ( "is_type_structurally_recursive: {:?} {:?}" , ty, sp) ;
277+ debug ! ( "is_type_structurally_recursive: {:?} {:?} {:?} " , ty, sp, field_id ) ;
258278 if let Some ( representability) = representable_cache. get ( & ty) {
259279 debug ! (
260- "is_type_structurally_recursive: {:?} {:?} - (cached) {:?}" ,
261- ty, sp, representability
280+ "is_type_structurally_recursive: {:?} {:?} {:?} - (cached) {:?}" ,
281+ ty, sp, field_id , representability
262282 ) ;
263283 return representability. clone ( ) ;
264284 }
265285
266286 let representability = is_type_structurally_recursive_inner (
267287 tcx,
268- sp,
269288 seen,
270289 shadow_seen,
271290 representable_cache,
272291 ty,
292+ sp,
293+ field_id,
273294 force_result,
274295 ) ;
275296
@@ -279,11 +300,12 @@ fn is_type_structurally_recursive<'tcx>(
279300
280301fn is_type_structurally_recursive_inner < ' tcx > (
281302 tcx : TyCtxt < ' tcx > ,
282- sp : Span ,
283303 seen : & mut Vec < Ty < ' tcx > > ,
284304 shadow_seen : & mut Vec < ty:: AdtDef < ' tcx > > ,
285305 representable_cache : & mut FxHashMap < Ty < ' tcx > , Representability > ,
286306 ty : Ty < ' tcx > ,
307+ sp : Span ,
308+ field_id : Option < hir:: HirId > ,
287309 force_result : & mut bool ,
288310) -> Representability {
289311 match ty. kind ( ) {
@@ -305,7 +327,7 @@ fn is_type_structurally_recursive_inner<'tcx>(
305327 if let Some ( & seen_adt) = iter. next ( ) {
306328 if same_adt ( seen_adt, * def) {
307329 debug ! ( "SelfRecursive: {:?} contains {:?}" , seen_adt, ty) ;
308- return Representability :: SelfRecursive ( vec ! [ sp ] ) ;
330+ return Representability :: SelfRecursive ( vec ! [ ( sp , field_id ) ] ) ;
309331 }
310332 }
311333
@@ -335,11 +357,12 @@ fn is_type_structurally_recursive_inner<'tcx>(
335357 shadow_seen. push ( * def) ;
336358 let out = are_inner_types_recursive (
337359 tcx,
338- sp,
339360 seen,
340361 shadow_seen,
341362 representable_cache,
342363 ty,
364+ sp,
365+ field_id,
343366 force_result,
344367 ) ;
345368 shadow_seen. pop ( ) ;
@@ -350,11 +373,12 @@ fn is_type_structurally_recursive_inner<'tcx>(
350373 // No need to push in other cases.
351374 are_inner_types_recursive (
352375 tcx,
353- sp,
354376 seen,
355377 shadow_seen,
356378 representable_cache,
357379 ty,
380+ sp,
381+ field_id,
358382 force_result,
359383 )
360384 }
0 commit comments