Skip to content

Commit 24a3c4f

Browse files
committed
types: Detect cycles when detecting if a type can derive debug
1 parent d4934c5 commit 24a3c4f

File tree

1 file changed

+33
-14
lines changed

1 file changed

+33
-14
lines changed

src/types.rs

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::cell::RefCell;
1+
use std::cell::{Cell, RefCell};
22
use std::fmt;
33
use std::rc::Rc;
44
use std::collections::HashMap;
@@ -321,6 +321,9 @@ pub struct CompInfo {
321321
pub has_non_type_template_params: bool,
322322
/// If this type was unnamed when parsed
323323
pub was_unnamed: bool,
324+
/// Used to detect if we've run in a can_derive_debug cycle while
325+
/// cycling around the template arguments.
326+
detect_derive_debug_cycle: Cell<bool>,
324327
}
325328

326329
static mut UNNAMED_COUNTER: u32 = 0;
@@ -358,28 +361,44 @@ impl CompInfo {
358361
typedefs: vec!(),
359362
has_non_type_template_params: false,
360363
was_unnamed: was_unnamed,
364+
detect_derive_debug_cycle: Cell::new(false),
361365
}
362366
}
363367

364368
pub fn can_derive_debug(&self) -> bool {
365-
// XXX: We could probably be smarter about this,
366-
// checking that the length of the generated array
367-
// for our layout is less or equal than 32.
368-
if self.kind != CompKind::Struct {
369+
if self.hide || self.opaque {
369370
return false;
370371
}
371372

372-
if self.hide || self.opaque {
373-
return false;
373+
if self.detect_derive_debug_cycle.get() {
374+
println!("Derive debug cycle detected: {}!", self.name);
375+
return true;
374376
}
375377

376-
self.args.iter().all(|ty| ty.can_derive_debug()) &&
377-
self.members.iter()
378-
.all(|member| match *member {
379-
CompMember::Field(ref f) |
380-
CompMember::CompField(_, ref f) => f.ty.can_derive_debug(),
381-
_ => true,
382-
})
378+
match self.kind {
379+
CompKind::Union => {
380+
let size_divisor = if self.layout.align == 0 { 1 } else { self.layout.align };
381+
if self.layout.size / size_divisor > 32 {
382+
return false;
383+
}
384+
385+
true
386+
}
387+
CompKind::Struct => {
388+
self.detect_derive_debug_cycle.set(true);
389+
390+
let can_derive_debug = self.args.iter().all(|ty| ty.can_derive_debug()) &&
391+
self.members.iter()
392+
.all(|member| match *member {
393+
CompMember::Field(ref f) |
394+
CompMember::CompField(_, ref f) => f.ty.can_derive_debug(),
395+
_ => true,
396+
});
397+
self.detect_derive_debug_cycle.set(false);
398+
399+
can_derive_debug
400+
}
401+
}
383402
}
384403
}
385404

0 commit comments

Comments
 (0)