diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/analysis/derive_debug.rs | 131 | ||||
-rw-r--r-- | src/ir/ty.rs | 1 |
2 files changed, 71 insertions, 61 deletions
diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs index b9b0be10..ac2a92de 100644 --- a/src/ir/analysis/derive_debug.rs +++ b/src/ir/analysis/derive_debug.rs @@ -11,7 +11,6 @@ use ir::ty::TypeKind; use ir::comp::Field; use ir::traversal::Trace; use ir::comp::FieldMethods; -use ir::layout::Layout; use ir::derive::CanTriviallyDeriveDebug; use ir::comp::CompKind; @@ -79,6 +78,8 @@ impl<'ctx, 'gen> CannotDeriveDebug<'ctx, 'gen> { } fn insert(&mut self, id: ItemId) -> ConstrainResult { + trace!("inserting {:?} into the cannot_derive_debug set", id); + let was_not_already_in_set = self.cannot_derive_debug.insert(id); assert!( was_not_already_in_set, @@ -86,6 +87,7 @@ impl<'ctx, 'gen> CannotDeriveDebug<'ctx, 'gen> { already in the set, `constrain` should have exited early.", id ); + ConstrainResult::Changed } } @@ -128,16 +130,35 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> { } fn constrain(&mut self, id: ItemId) -> ConstrainResult { + trace!("constrain: {:?}", id); + if self.cannot_derive_debug.contains(&id) { + trace!(" already know it cannot derive Debug"); return ConstrainResult::Same; } let item = self.ctx.resolve_item(id); let ty = match item.as_type() { - None => return ConstrainResult::Same, - Some(ty) => ty + Some(ty) => ty, + None => { + trace!(" not a type; ignoring"); + return ConstrainResult::Same; + } }; + if ty.is_opaque(self.ctx, item) { + let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| { + l.opaque().can_trivially_derive_debug(self.ctx, ()) + }); + return if layout_can_derive { + trace!(" we can trivially derive Debug for the layout"); + ConstrainResult::Same + } else { + trace!(" we cannot derive Debug for the layout"); + self.insert(id) + }; + } + match *ty.kind() { // Handle the simple cases. These can derive debug without further // information. @@ -155,61 +176,59 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> { TypeKind::ObjCInterface(..) | TypeKind::ObjCId | TypeKind::ObjCSel => { + trace!(" simple type that can always derive Debug"); ConstrainResult::Same - }, - - TypeKind::Opaque => { - if ty.layout(self.ctx) - .map_or(true, |l| l.opaque().can_trivially_derive_debug(self.ctx, ())) { - ConstrainResult::Same - } else { - self.insert(id) - } - }, + } TypeKind::Array(t, len) => { if self.cannot_derive_debug.contains(&t) { + trace!(" arrays of T for which we cannot derive Debug \ + also cannot derive Debug"); return self.insert(id); } if len <= RUST_DERIVE_IN_ARRAY_LIMIT { + trace!(" array is small enough to derive Debug"); ConstrainResult::Same } else { + trace!(" array is too large to derive Debug"); self.insert(id) } - }, + } TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { if self.cannot_derive_debug.contains(&t) { + trace!(" aliases and type refs to T which cannot derive \ + Debug also cannot derive Debug"); self.insert(id) } else { + trace!(" aliases and type refs to T which can derive \ + Debug can also derive Debug"); ConstrainResult::Same } - }, + } TypeKind::Comp(ref info) => { - if info.has_non_type_template_params() { - if ty.layout(self.ctx) - .map_or(true, - |l| l.opaque().can_trivially_derive_debug(self.ctx, ())) { - return ConstrainResult::Same; - } else { - return self.insert(id); - } - } + assert!( + !info.has_non_type_template_params(), + "The early ty.is_opaque check should have handled this case" + ); if info.kind() == CompKind::Union { if self.ctx.options().unstable_rust { + trace!(" cannot derive Debug for Rust unions"); return self.insert(id); } if ty.layout(self.ctx) .map_or(true, |l| l.opaque().can_trivially_derive_debug(self.ctx, ())) { + trace!(" union layout can trivially derive Debug"); return ConstrainResult::Same; } else { + trace!(" union layout cannot derive Debug"); return self.insert(id); } } @@ -218,6 +237,8 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> { .iter() .any(|base| self.cannot_derive_debug.contains(&base.ty)); if bases_cannot_derive { + trace!(" base members cannot derive Debug, so we can't \ + either"); return self.insert(id); } @@ -237,69 +258,57 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> { } }); if fields_cannot_derive { + trace!(" fields cannot derive Debug, so we can't either"); return self.insert(id); } + trace!(" comp can derive Debug"); ConstrainResult::Same - }, + } TypeKind::Pointer(inner) => { let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { if !sig.can_trivially_derive_debug(&self.ctx, ()) { + trace!(" function pointer that can't trivially derive Debug"); return self.insert(id); } } + trace!(" pointers can derive Debug"); ConstrainResult::Same - }, + } TypeKind::TemplateInstantiation(ref template) => { let args_cannot_derive = template.template_arguments() .iter() .any(|arg| self.cannot_derive_debug.contains(&arg)); if args_cannot_derive { + trace!(" template args cannot derive Debug, so \ + insantiation can't either"); return self.insert(id); } - let template_definition = template.template_definition() - .into_resolver() - .through_type_refs() - .through_type_aliases() - .resolve(self.ctx); - - let ty_cannot_derive = template_definition - .as_type() - .expect("Instantiations of a non-type?") - .as_comp() - .and_then(|c| { - // For non-type template parameters, or opaque template - // definitions, we generate an opaque blob, and in this - // case the instantiation has a better idea of the - // layout than the definition does. - if template_definition.is_opaque(self.ctx, &()) || - c.has_non_type_template_params() { - let opaque = ty.layout(self.ctx) - .or_else(|| { - self.ctx - .resolve_type(template.template_definition()) - .layout(self.ctx) - }) - .unwrap_or(Layout::zero()) - .opaque(); - Some(!opaque.can_trivially_derive_debug(&self.ctx, ())) - } else { - None - } - }) - .unwrap_or_else(|| { - self.cannot_derive_debug.contains(&template.template_definition()) - }); - if ty_cannot_derive { + assert!( + !template.template_definition().is_opaque(self.ctx, &()), + "The early ty.is_opaque check should have handled this case" + ); + let def_cannot_derive = self.cannot_derive_debug + .contains(&template.template_definition()); + if def_cannot_derive { + trace!(" template definition cannot derive Debug, so \ + insantiation can't either"); return self.insert(id); } + trace!(" template instantiation can derive Debug"); ConstrainResult::Same - }, + } + + TypeKind::Opaque => { + unreachable!( + "The early ty.is_opaque check should have handled this case" + ) + } } } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 78274d94..5cbc4cf6 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -359,6 +359,7 @@ impl IsOpaque for Type { TypeKind::Opaque => true, TypeKind::TemplateInstantiation(ref inst) => inst.is_opaque(ctx, item), TypeKind::Comp(ref comp) => comp.is_opaque(ctx, &()), + TypeKind::ResolvedTypeRef(to) => to.is_opaque(ctx, &()), _ => false, } } |