@@ -276,7 +276,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
276276 && let ty:: Adt ( adt_def, args) = ty. kind ( )
277277 {
278278 let def_id = adt_def. did ( ) ;
279- // If any sub type reference the original type definition and the sub type has a type
279+ // If any child type references the original type definition and the child type has a type
280280 // parameter that strictly contains the original parameter, the original type is a recursive
281281 // type that can expanding indefinitely. Example,
282282 // ```
@@ -285,21 +285,43 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
285285 // Item(T),
286286 // }
287287 // ```
288- let is_expanding_recursive = adt_def. is_enum ( )
289- && debug_context ( cx) . adt_stack . borrow ( ) . iter ( ) . any ( |( parent_def_id, parent_args) | {
290- if def_id == * parent_def_id {
291- args. iter ( ) . zip ( parent_args. iter ( ) ) . any ( |( arg, parent_arg) | {
292- if let ( Some ( arg) , Some ( parent_arg) ) = ( arg. as_type ( ) , parent_arg. as_type ( ) )
293- {
294- arg != parent_arg && arg. contains ( parent_arg)
295- } else {
296- false
297- }
298- } )
299- } else {
300- false
301- }
302- } ) ;
288+ let is_expanding_recursive = {
289+ let stack = debug_context ( cx) . adt_stack . borrow ( ) ;
290+ stack
291+ . iter ( )
292+ . enumerate ( )
293+ . rev ( )
294+ . skip ( 1 )
295+ . filter ( |( _, ( ancestor_def_id, _) ) | def_id == * ancestor_def_id)
296+ . any ( |( ancestor_index, ( _, ancestor_args) ) | {
297+ args. iter ( )
298+ . zip ( ancestor_args. iter ( ) )
299+ . filter_map ( |( arg, ancestor_arg) | arg. as_type ( ) . zip ( ancestor_arg. as_type ( ) ) )
300+ . any ( |( arg, ancestor_arg) |
301+ // Strictly contains.
302+ ( arg != ancestor_arg && arg. contains ( ancestor_arg) )
303+ // Check all types between current and ancestor use the
304+ // ancestor_arg.
305+ // Otherwise, duplicate wrappers in normal recursive type may be
306+ // regarded as expanding.
307+ // ```
308+ // struct Recursive {
309+ // a: Box<Box<Recursive>>,
310+ // }
311+ // ```
312+ // It can produce an ADT stack like this,
313+ // - Box<Recursive>
314+ // - Recursive
315+ // - Box<Box<Recursive>>
316+ && stack[ ancestor_index + 1 ..stack. len ( ) ] . iter ( ) . all (
317+ |( _, intermediate_args) |
318+ intermediate_args
319+ . iter ( )
320+ . filter_map ( |arg| arg. as_type ( ) )
321+ . any ( |mid_arg| mid_arg. contains ( ancestor_arg) )
322+ ) )
323+ } )
324+ } ;
303325 if is_expanding_recursive {
304326 // FIXME: indicate that this is an expanding recursive type in stub metadata?
305327 return DINodeCreationResult :: new ( stub_info. metadata , false ) ;
0 commit comments