|
1 |
| -use std::cell::RefCell; |
| 1 | +use std::cell::{Cell, RefCell}; |
2 | 2 | use std::fmt;
|
3 | 3 | use std::rc::Rc;
|
4 | 4 | use std::collections::HashMap;
|
@@ -321,6 +321,9 @@ pub struct CompInfo {
|
321 | 321 | pub has_non_type_template_params: bool,
|
322 | 322 | /// If this type was unnamed when parsed
|
323 | 323 | 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>, |
324 | 327 | }
|
325 | 328 |
|
326 | 329 | static mut UNNAMED_COUNTER: u32 = 0;
|
@@ -358,28 +361,44 @@ impl CompInfo {
|
358 | 361 | typedefs: vec!(),
|
359 | 362 | has_non_type_template_params: false,
|
360 | 363 | was_unnamed: was_unnamed,
|
| 364 | + detect_derive_debug_cycle: Cell::new(false), |
361 | 365 | }
|
362 | 366 | }
|
363 | 367 |
|
364 | 368 | 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 { |
369 | 370 | return false;
|
370 | 371 | }
|
371 | 372 |
|
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; |
374 | 376 | }
|
375 | 377 |
|
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 | + } |
383 | 402 | }
|
384 | 403 | }
|
385 | 404 |
|
|
0 commit comments