Skip to content

Commit e9f452b

Browse files
author
bors-servo
authored
Auto merge of rust-lang#847 - fitzgen:derive-debug-opaque-types, r=emilio
Derive debug and opaque types See each commit for details. Follow up to rust-lang#842. r? @emilio or @Manishearth
2 parents 877b65c + 684fc38 commit e9f452b

14 files changed

+196
-170
lines changed

src/ir/analysis/derive_debug.rs

Lines changed: 70 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use ir::ty::TypeKind;
1111
use ir::comp::Field;
1212
use ir::traversal::Trace;
1313
use ir::comp::FieldMethods;
14-
use ir::layout::Layout;
1514
use ir::derive::CanTriviallyDeriveDebug;
1615
use ir::comp::CompKind;
1716

@@ -79,13 +78,16 @@ impl<'ctx, 'gen> CannotDeriveDebug<'ctx, 'gen> {
7978
}
8079

8180
fn insert(&mut self, id: ItemId) -> ConstrainResult {
81+
trace!("inserting {:?} into the cannot_derive_debug set", id);
82+
8283
let was_not_already_in_set = self.cannot_derive_debug.insert(id);
8384
assert!(
8485
was_not_already_in_set,
8586
"We shouldn't try and insert {:?} twice because if it was \
8687
already in the set, `constrain` should have exited early.",
8788
id
8889
);
90+
8991
ConstrainResult::Changed
9092
}
9193
}
@@ -128,16 +130,35 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
128130
}
129131

130132
fn constrain(&mut self, id: ItemId) -> ConstrainResult {
133+
trace!("constrain: {:?}", id);
134+
131135
if self.cannot_derive_debug.contains(&id) {
136+
trace!(" already know it cannot derive Debug");
132137
return ConstrainResult::Same;
133138
}
134139

135140
let item = self.ctx.resolve_item(id);
136141
let ty = match item.as_type() {
137-
None => return ConstrainResult::Same,
138-
Some(ty) => ty
142+
Some(ty) => ty,
143+
None => {
144+
trace!(" not a type; ignoring");
145+
return ConstrainResult::Same;
146+
}
139147
};
140148

149+
if ty.is_opaque(self.ctx, item) {
150+
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
151+
l.opaque().can_trivially_derive_debug(self.ctx, ())
152+
});
153+
return if layout_can_derive {
154+
trace!(" we can trivially derive Debug for the layout");
155+
ConstrainResult::Same
156+
} else {
157+
trace!(" we cannot derive Debug for the layout");
158+
self.insert(id)
159+
};
160+
}
161+
141162
match *ty.kind() {
142163
// Handle the simple cases. These can derive debug without further
143164
// information.
@@ -155,61 +176,59 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
155176
TypeKind::ObjCInterface(..) |
156177
TypeKind::ObjCId |
157178
TypeKind::ObjCSel => {
179+
trace!(" simple type that can always derive Debug");
158180
ConstrainResult::Same
159-
},
160-
161-
TypeKind::Opaque => {
162-
if ty.layout(self.ctx)
163-
.map_or(true, |l| l.opaque().can_trivially_derive_debug(self.ctx, ())) {
164-
ConstrainResult::Same
165-
} else {
166-
self.insert(id)
167-
}
168-
},
181+
}
169182

170183
TypeKind::Array(t, len) => {
171184
if self.cannot_derive_debug.contains(&t) {
185+
trace!(" arrays of T for which we cannot derive Debug \
186+
also cannot derive Debug");
172187
return self.insert(id);
173188
}
174189

175190
if len <= RUST_DERIVE_IN_ARRAY_LIMIT {
191+
trace!(" array is small enough to derive Debug");
176192
ConstrainResult::Same
177193
} else {
194+
trace!(" array is too large to derive Debug");
178195
self.insert(id)
179196
}
180-
},
197+
}
181198

182199
TypeKind::ResolvedTypeRef(t) |
183200
TypeKind::TemplateAlias(t, _) |
184201
TypeKind::Alias(t) => {
185202
if self.cannot_derive_debug.contains(&t) {
203+
trace!(" aliases and type refs to T which cannot derive \
204+
Debug also cannot derive Debug");
186205
self.insert(id)
187206
} else {
207+
trace!(" aliases and type refs to T which can derive \
208+
Debug can also derive Debug");
188209
ConstrainResult::Same
189210
}
190-
},
211+
}
191212

192213
TypeKind::Comp(ref info) => {
193-
if info.has_non_type_template_params() {
194-
if ty.layout(self.ctx)
195-
.map_or(true,
196-
|l| l.opaque().can_trivially_derive_debug(self.ctx, ())) {
197-
return ConstrainResult::Same;
198-
} else {
199-
return self.insert(id);
200-
}
201-
}
214+
assert!(
215+
!info.has_non_type_template_params(),
216+
"The early ty.is_opaque check should have handled this case"
217+
);
202218

203219
if info.kind() == CompKind::Union {
204220
if self.ctx.options().unstable_rust {
221+
trace!(" cannot derive Debug for Rust unions");
205222
return self.insert(id);
206223
}
207224

208225
if ty.layout(self.ctx)
209226
.map_or(true,
210227
|l| l.opaque().can_trivially_derive_debug(self.ctx, ())) {
228+
trace!(" union layout can trivially derive Debug");
211229
return ConstrainResult::Same;
212230
} else {
231+
trace!(" union layout cannot derive Debug");
213232
return self.insert(id);
214233
}
215234
}
@@ -218,6 +237,8 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
218237
.iter()
219238
.any(|base| self.cannot_derive_debug.contains(&base.ty));
220239
if bases_cannot_derive {
240+
trace!(" base members cannot derive Debug, so we can't \
241+
either");
221242
return self.insert(id);
222243
}
223244

@@ -237,69 +258,57 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
237258
}
238259
});
239260
if fields_cannot_derive {
261+
trace!(" fields cannot derive Debug, so we can't either");
240262
return self.insert(id);
241263
}
242264

265+
trace!(" comp can derive Debug");
243266
ConstrainResult::Same
244-
},
267+
}
245268

246269
TypeKind::Pointer(inner) => {
247270
let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx);
248271
if let TypeKind::Function(ref sig) = *inner_type.kind() {
249272
if !sig.can_trivially_derive_debug(&self.ctx, ()) {
273+
trace!(" function pointer that can't trivially derive Debug");
250274
return self.insert(id);
251275
}
252276
}
277+
trace!(" pointers can derive Debug");
253278
ConstrainResult::Same
254-
},
279+
}
255280

256281
TypeKind::TemplateInstantiation(ref template) => {
257282
let args_cannot_derive = template.template_arguments()
258283
.iter()
259284
.any(|arg| self.cannot_derive_debug.contains(&arg));
260285
if args_cannot_derive {
286+
trace!(" template args cannot derive Debug, so \
287+
insantiation can't either");
261288
return self.insert(id);
262289
}
263290

264-
let template_definition = template.template_definition()
265-
.into_resolver()
266-
.through_type_refs()
267-
.through_type_aliases()
268-
.resolve(self.ctx);
269-
270-
let ty_cannot_derive = template_definition
271-
.as_type()
272-
.expect("Instantiations of a non-type?")
273-
.as_comp()
274-
.and_then(|c| {
275-
// For non-type template parameters, or opaque template
276-
// definitions, we generate an opaque blob, and in this
277-
// case the instantiation has a better idea of the
278-
// layout than the definition does.
279-
if template_definition.is_opaque(self.ctx, &()) ||
280-
c.has_non_type_template_params() {
281-
let opaque = ty.layout(self.ctx)
282-
.or_else(|| {
283-
self.ctx
284-
.resolve_type(template.template_definition())
285-
.layout(self.ctx)
286-
})
287-
.unwrap_or(Layout::zero())
288-
.opaque();
289-
Some(!opaque.can_trivially_derive_debug(&self.ctx, ()))
290-
} else {
291-
None
292-
}
293-
})
294-
.unwrap_or_else(|| {
295-
self.cannot_derive_debug.contains(&template.template_definition())
296-
});
297-
if ty_cannot_derive {
291+
assert!(
292+
!template.template_definition().is_opaque(self.ctx, &()),
293+
"The early ty.is_opaque check should have handled this case"
294+
);
295+
let def_cannot_derive = self.cannot_derive_debug
296+
.contains(&template.template_definition());
297+
if def_cannot_derive {
298+
trace!(" template definition cannot derive Debug, so \
299+
insantiation can't either");
298300
return self.insert(id);
299301
}
300302

303+
trace!(" template instantiation can derive Debug");
301304
ConstrainResult::Same
302-
},
305+
}
306+
307+
TypeKind::Opaque => {
308+
unreachable!(
309+
"The early ty.is_opaque check should have handled this case"
310+
)
311+
}
303312
}
304313
}
305314

src/ir/ty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ impl IsOpaque for Type {
359359
TypeKind::Opaque => true,
360360
TypeKind::TemplateInstantiation(ref inst) => inst.is_opaque(ctx, item),
361361
TypeKind::Comp(ref comp) => comp.is_opaque(ctx, &()),
362+
TypeKind::ResolvedTypeRef(to) => to.is_opaque(ctx, &()),
362363
_ => false,
363364
}
364365
}

tests/expectations/tests/issue-372.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ pub mod root {
8383
ai = 11,
8484
}
8585
#[repr(C)]
86-
#[derive(Copy)]
8786
pub struct F {
8887
pub w: [u64; 33usize],
8988
}
@@ -99,21 +98,7 @@ pub mod root {
9998
"Alignment of field: " , stringify ! ( F ) , "::" ,
10099
stringify ! ( w ) ));
101100
}
102-
impl Clone for F {
103-
fn clone(&self) -> Self { *self }
104-
}
105101
impl Default for F {
106102
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
107103
}
108-
#[test]
109-
fn __bindgen_test_layout_C_open0_n_close0_instantiation() {
110-
assert_eq!(::std::mem::size_of::<[u64; 33usize]>() , 264usize , concat
111-
! (
112-
"Size of template specialization: " , stringify ! (
113-
[u64; 33usize] ) ));
114-
assert_eq!(::std::mem::align_of::<[u64; 33usize]>() , 8usize , concat
115-
! (
116-
"Alignment of template specialization: " , stringify ! (
117-
[u64; 33usize] ) ));
118-
}
119104
}

tests/expectations/tests/libclang-3.8/partial-specialization-and-inheritance.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,3 @@ impl Usage {
4545
__bindgen_tmp
4646
}
4747
}
48-
#[test]
49-
fn __bindgen_test_layout__bindgen_ty_id_21_open0__bindgen_ty_id_19_close0_instantiation() {
50-
assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat ! (
51-
"Size of template specialization: " , stringify ! (
52-
[u32; 2usize] ) ));
53-
assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat ! (
54-
"Alignment of template specialization: " , stringify ! (
55-
[u32; 2usize] ) ));
56-
}

tests/expectations/tests/libclang-3.9/partial-specialization-and-inheritance.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,3 @@ fn bindgen_test_layout_Usage() {
3333
impl Clone for Usage {
3434
fn clone(&self) -> Self { *self }
3535
}
36-
#[test]
37-
fn __bindgen_test_layout__bindgen_ty_id_20_open0__bindgen_ty_id_18_close0_instantiation() {
38-
assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat ! (
39-
"Size of template specialization: " , stringify ! (
40-
[u32; 2usize] ) ));
41-
assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat ! (
42-
"Alignment of template specialization: " , stringify ! (
43-
[u32; 2usize] ) ));
44-
}

tests/expectations/tests/libclang-4/partial-specialization-and-inheritance.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,3 @@ fn bindgen_test_layout_Usage() {
3333
impl Clone for Usage {
3434
fn clone(&self) -> Self { *self }
3535
}
36-
#[test]
37-
fn __bindgen_test_layout__bindgen_ty_id_20_open0__bindgen_ty_id_18_close0_instantiation() {
38-
assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat ! (
39-
"Size of template specialization: " , stringify ! (
40-
[u32; 2usize] ) ));
41-
assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat ! (
42-
"Alignment of template specialization: " , stringify ! (
43-
[u32; 2usize] ) ));
44-
}

tests/expectations/tests/non-type-params.rs

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
pub type Array16 = u8;
88
pub type ArrayInt4 = [u32; 4usize];
99
#[repr(C)]
10-
#[derive(Debug, Copy)]
10+
#[derive(Debug, Default, Copy)]
1111
pub struct UsesArray {
1212
pub array_char_16: [u8; 16usize],
1313
pub array_bool_8: [u8; 8usize],
@@ -38,33 +38,3 @@ fn bindgen_test_layout_UsesArray() {
3838
impl Clone for UsesArray {
3939
fn clone(&self) -> Self { *self }
4040
}
41-
impl Default for UsesArray {
42-
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
43-
}
44-
#[test]
45-
fn __bindgen_test_layout_Array_open0_int_close0_instantiation() {
46-
assert_eq!(::std::mem::size_of::<[u32; 4usize]>() , 16usize , concat ! (
47-
"Size of template specialization: " , stringify ! (
48-
[u32; 4usize] ) ));
49-
assert_eq!(::std::mem::align_of::<[u32; 4usize]>() , 4usize , concat ! (
50-
"Alignment of template specialization: " , stringify ! (
51-
[u32; 4usize] ) ));
52-
}
53-
#[test]
54-
fn __bindgen_test_layout_Array_open0_char_close0_instantiation() {
55-
assert_eq!(::std::mem::size_of::<[u8; 16usize]>() , 16usize , concat ! (
56-
"Size of template specialization: " , stringify ! (
57-
[u8; 16usize] ) ));
58-
assert_eq!(::std::mem::align_of::<[u8; 16usize]>() , 1usize , concat ! (
59-
"Alignment of template specialization: " , stringify ! (
60-
[u8; 16usize] ) ));
61-
}
62-
#[test]
63-
fn __bindgen_test_layout_Array_open0_bool__close0_instantiation() {
64-
assert_eq!(::std::mem::size_of::<[u8; 8usize]>() , 8usize , concat ! (
65-
"Size of template specialization: " , stringify ! (
66-
[u8; 8usize] ) ));
67-
assert_eq!(::std::mem::align_of::<[u8; 8usize]>() , 1usize , concat ! (
68-
"Alignment of template specialization: " , stringify ! (
69-
[u8; 8usize] ) ));
70-
}

0 commit comments

Comments
 (0)