Skip to content

Commit 8600b06

Browse files
author
bors-servo
authored
Auto merge of #23 - emilio:crtp, r=nox
Avoid recursing infinitely with CRTP while looking for a destructor. Fixes #22 r? @nox
2 parents 4f92390 + 101fdb0 commit 8600b06

File tree

4 files changed

+67
-9
lines changed

4 files changed

+67
-9
lines changed

src/gen.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,7 @@ fn gen_globals(mut ctx: &mut GenCtx,
480480
(Some(l), Some(lg)) if l.size == lg.size => {},
481481
(None, None) => {},
482482
_ => {
483-
// XXX real logger
484-
println!("warning: substituted type for {} does not match its size", g.name());
483+
warn!("warning: substituted type for {} does not match its size", g.name());
485484
}
486485
}
487486
g = substituted;
@@ -492,7 +491,7 @@ fn gen_globals(mut ctx: &mut GenCtx,
492491

493492
let mut pending_translations = std::mem::replace(&mut ctx.current_module_mut().translations, HashMap::new());
494493
for (name, g) in pending_translations.drain() {
495-
println!("warning: generating definition for not found type: {}", name);
494+
warn!("warning: generating definition for not found type: {}", name);
496495
gen_global(ctx, g, &mut defs);
497496
}
498497

@@ -983,7 +982,7 @@ fn cstruct_to_rs(ctx: &mut GenCtx, name: &str, ci: CompInfo) -> Vec<P<ast::Item>
983982
let is_translatable = cty_is_translatable(&f_ty);
984983
if !is_translatable || f_ty.is_opaque() {
985984
if !is_translatable {
986-
println!("{}::{} not translatable, void: {}", ci.name, f.name, f_ty == TVoid);
985+
warn!("{}::{} not translatable, void: {}", ci.name, f.name, f_ty == TVoid);
987986
}
988987
if let Some(layout) = f_ty.layout() {
989988
fields.push(mk_blob_field(ctx, &f_name, &layout));
@@ -1326,7 +1325,7 @@ fn enum_size_to_rust_type_name(signed: bool, size: usize) -> &'static str {
13261325
(true, 8) => "i64",
13271326
(false, 8) => "u64",
13281327
_ => {
1329-
println!("invalid enum decl: signed: {}, size: {}", signed, size);
1328+
warn!("invalid enum decl: signed: {}, size: {}", signed, size);
13301329
"i32"
13311330
}
13321331
}

src/types.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,12 @@ pub struct CompInfo {
440440
pub was_unnamed: bool,
441441
/// Set of static vars declared inside this class.
442442
pub vars: Vec<Global>,
443-
/// Used to detect if we've run in a can_derive_debug cycle while
444-
/// cycling around the template arguments.
443+
/// Used to detect if we've run in a can_derive_debug cycle while cycling
444+
/// around the template arguments.
445445
detect_derive_debug_cycle: Cell<bool>,
446+
/// Used to detect if we've run in a has_destructor cycle while cycling
447+
/// around the template arguments.
448+
detect_has_destructor_cycle: Cell<bool>,
446449
}
447450

448451
static mut UNNAMED_COUNTER: u32 = 0;
@@ -490,6 +493,7 @@ impl CompInfo {
490493
has_non_type_template_params: false,
491494
was_unnamed: was_unnamed,
492495
detect_derive_debug_cycle: Cell::new(false),
496+
detect_has_destructor_cycle: Cell::new(false),
493497
}
494498
}
495499

@@ -548,7 +552,15 @@ impl CompInfo {
548552
}
549553

550554
pub fn has_destructor(&self) -> bool {
551-
self.has_destructor || match self.kind {
555+
if self.detect_has_destructor_cycle.get() {
556+
warn!("Cycle detected looking for destructors: {}!", self.name);
557+
// Assume no destructor, since we don't have an explicit one.
558+
return false;
559+
}
560+
561+
self.detect_has_destructor_cycle.set(true);
562+
563+
let has_destructor = self.has_destructor || match self.kind {
552564
CompKind::Union => false,
553565
CompKind::Struct => {
554566
// NB: We can't rely on a type with type parameters
@@ -570,7 +582,11 @@ impl CompInfo {
570582
_ => false,
571583
})
572584
}
573-
}
585+
};
586+
587+
self.detect_has_destructor_cycle.set(false);
588+
589+
has_destructor
574590
}
575591

576592
pub fn can_derive_copy(&self) -> bool {

tests/expectations/crtp.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
#[repr(C)]
8+
#[derive(Debug, Copy, Clone)]
9+
pub struct Base<T> {
10+
pub _phantom0: ::std::marker::PhantomData<T>,
11+
}
12+
#[repr(C)]
13+
#[derive(Debug, Copy)]
14+
pub struct Derived {
15+
pub _base: Base<Derived>,
16+
}
17+
impl ::std::clone::Clone for Derived {
18+
fn clone(&self) -> Self { *self }
19+
}
20+
#[repr(C)]
21+
#[derive(Debug)]
22+
pub struct BaseWithDestructor<T> {
23+
pub _phantom0: ::std::marker::PhantomData<T>,
24+
}
25+
#[repr(C)]
26+
#[derive(Debug)]
27+
pub struct DerivedFromBaseWithDestructor {
28+
pub _base: BaseWithDestructor<DerivedFromBaseWithDestructor>,
29+
}

tests/headers/crtp.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// bindgen-flags: -no-type-renaming
2+
3+
template<class T>
4+
class Base {};
5+
6+
class Derived : public Base<Derived> {};
7+
8+
template<class T>
9+
class BaseWithDestructor {
10+
~BaseWithDestructor();
11+
};
12+
13+
class DerivedFromBaseWithDestructor :
14+
public BaseWithDestructor<DerivedFromBaseWithDestructor> {};

0 commit comments

Comments
 (0)