Skip to content

ir: Cleanup name duplication in aliases and named types. #461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ impl CodeGenerator for Type {
TypeKind::TemplateRef(..) |
TypeKind::Function(..) |
TypeKind::ResolvedTypeRef(..) |
TypeKind::Named(..) => {
TypeKind::Named => {
// These items don't need code generation, they only need to be
// converted to rust types in fields, arguments, and such.
return;
Expand All @@ -517,8 +517,8 @@ impl CodeGenerator for Type {
}
// NB: The code below will pick the correct
// applicable_template_args.
TypeKind::TemplateAlias(ref spelling, inner, _) |
TypeKind::Alias(ref spelling, inner) => {
TypeKind::TemplateAlias(inner, _) |
TypeKind::Alias(inner) => {
let inner_item = ctx.resolve_item(inner);
let name = item.canonical_name(ctx);

Expand All @@ -534,6 +534,7 @@ impl CodeGenerator for Type {

// If this is a known named type, disallow generating anything
// for it too.
let spelling = self.name().expect("Unnamed alias?");
if utils::type_from_named(ctx, spelling, inner).is_some() {
return;
}
Expand Down Expand Up @@ -2043,14 +2044,15 @@ impl ToRustTy for Type {
P(inner_ty)
}
TypeKind::ResolvedTypeRef(inner) => inner.to_rust_ty(ctx),
TypeKind::TemplateAlias(ref spelling, inner, _) |
TypeKind::Alias(ref spelling, inner) => {
TypeKind::TemplateAlias(inner, _) |
TypeKind::Alias(inner) => {
let applicable_named_args =
item.applicable_template_args(ctx)
.into_iter()
.filter(|arg| ctx.resolve_type(*arg).is_named())
.collect::<Vec<_>>();

let spelling = self.name().expect("Unnamed alias?");
if item.is_opaque(ctx) && !applicable_named_args.is_empty() {
// Pray if there's no available layout.
let layout = self.layout(ctx).unwrap_or_else(Layout::zero);
Expand Down Expand Up @@ -2104,7 +2106,7 @@ impl ToRustTy for Type {
ty.to_ptr(is_const, ctx.span())
}
}
TypeKind::Named(..) => {
TypeKind::Named => {
let name = item.canonical_name(ctx);
let ident = ctx.rust_ident(&name);
quote_ty!(ctx.ext_cx(), $ident)
Expand Down
10 changes: 5 additions & 5 deletions src/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,23 +561,23 @@ impl Item {
parent_template_args.iter().any(|parent_item| {
let parent_ty = ctx.resolve_type(*parent_item);
match (parent_ty.kind(), item_ty.kind()) {
(&TypeKind::Named(ref n), &TypeKind::Named(ref i)) => {
n == i
(&TypeKind::Named, &TypeKind::Named) => {
parent_ty.name() == item_ty.name()
}
_ => false,
}
})
}

match *ty.kind() {
TypeKind::Named(..) => vec![self.id()],
TypeKind::Named => vec![self.id()],
TypeKind::Array(inner, _) |
TypeKind::Pointer(inner) |
TypeKind::Reference(inner) |
TypeKind::ResolvedTypeRef(inner) => {
ctx.resolve_item(inner).applicable_template_args(ctx)
}
TypeKind::Alias(_, inner) => {
TypeKind::Alias(inner) => {
let parent_args = ctx.resolve_item(self.parent_id())
.applicable_template_args(ctx);
let inner = ctx.resolve_item(inner);
Expand All @@ -594,7 +594,7 @@ impl Item {
}
// XXX Is this completely correct? Partial template specialization
// is hard anyways, sigh...
TypeKind::TemplateAlias(_, _, ref args) |
TypeKind::TemplateAlias(_, ref args) |
TypeKind::TemplateRef(_, ref args) => args.clone(),
// In a template specialization we've got all we want.
TypeKind::Comp(ref ci) if ci.is_template_specialization() => {
Expand Down
87 changes: 34 additions & 53 deletions src/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,6 @@ impl Type {
&self.kind
}

/// Overrides the kind of the item. This is mostly a template alias
/// implementation detail, and debug assertions guard it like so.
pub fn set_kind(&mut self, kind: TypeKind) {
if cfg!(debug_assertions) {
match (&self.kind, &kind) {
(&TypeKind::Alias(ref alias_name, alias_inner),
&TypeKind::TemplateAlias(ref name, inner, _)) => {
assert_eq!(alias_name, name);
assert_eq!(alias_inner, inner);
}
_ => panic!("Unexpected kind in `set_kind`!"),
};
}
self.kind = kind;
}

/// Get a mutable reference to this type's kind.
pub fn kind_mut(&mut self) -> &mut TypeKind {
&mut self.kind
Expand All @@ -102,7 +86,7 @@ impl Type {
/// Is this a named type?
pub fn is_named(&self) -> bool {
match self.kind {
TypeKind::Named(..) => true,
TypeKind::Named => true,
_ => false,
}
}
Expand Down Expand Up @@ -143,17 +127,15 @@ impl Type {
TypeKind::BlockPointer |
TypeKind::Int(..) |
TypeKind::Float(..) |
TypeKind::Named(..) => true,
TypeKind::Named => true,
_ => false,
}
}

/// Creates a new named type, with name `name`.
pub fn named(name: String) -> Self {
assert!(!name.is_empty());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be good to assert about identifiers like we now do in codegen here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the point is that invalid identifiers may come here, we just don't want to generate code for them. It'd be good if they didn't, but more work needs to happen so that's true.

// TODO: stop duplicating the name, it's stupid.
let kind = TypeKind::Named(name.clone());
Self::new(Some(name), None, kind, false)
Self::new(Some(name), None, TypeKind::Named, false)
}

/// Is this a floating point type?
Expand Down Expand Up @@ -230,8 +212,8 @@ impl Type {
// FIXME: Can we do something about template parameters? Huh...
match self.kind {
TypeKind::TemplateRef(t, _) |
TypeKind::TemplateAlias(_, t, _) |
TypeKind::Alias(_, t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) |
TypeKind::ResolvedTypeRef(t) => ctx.resolve_type(t).has_vtable(ctx),
TypeKind::Comp(ref info) => info.has_vtable(ctx),
_ => false,
Expand All @@ -243,8 +225,8 @@ impl Type {
pub fn has_destructor(&self, ctx: &BindgenContext) -> bool {
match self.kind {
TypeKind::TemplateRef(t, _) |
TypeKind::TemplateAlias(_, t, _) |
TypeKind::Alias(_, t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) |
TypeKind::ResolvedTypeRef(t) => {
ctx.resolve_type(t).has_destructor(ctx)
}
Expand All @@ -259,16 +241,16 @@ impl Type {
ty: &Type)
-> bool {
let name = match *ty.kind() {
TypeKind::Named(ref name) => name,
TypeKind::Named => ty.name(),
ref other @ _ => unreachable!("Not a named type: {:?}", other),
};

match self.kind {
TypeKind::Named(ref this_name) => this_name == name,
TypeKind::Named => self.name() == name,
TypeKind::ResolvedTypeRef(t) |
TypeKind::Array(t, _) |
TypeKind::Pointer(t) |
TypeKind::Alias(_, t) => {
TypeKind::Alias(t) => {
ctx.resolve_type(t)
.signature_contains_named_type(ctx, ty)
}
Expand All @@ -280,7 +262,7 @@ impl Type {
ctx.resolve_type(sig.return_type())
.signature_contains_named_type(ctx, ty)
}
TypeKind::TemplateAlias(_, _, ref template_args) |
TypeKind::TemplateAlias(_, ref template_args) |
TypeKind::TemplateRef(_, ref template_args) => {
template_args.iter().any(|arg| {
ctx.resolve_type(*arg)
Expand All @@ -298,8 +280,8 @@ impl Type {
/// tests/headers/381-decltype-alias.hpp
pub fn is_invalid_named_type(&self) -> bool {
match self.kind {
TypeKind::Named(ref name) => {
assert!(!name.is_empty());
TypeKind::Named => {
let name = self.name().expect("Unnamed named type?");
let mut chars = name.chars();
let first = chars.next().unwrap();
let mut remaining = chars;
Expand Down Expand Up @@ -330,7 +312,7 @@ impl Type {
ctx: &'tr BindgenContext)
-> Option<&'tr Type> {
match self.kind {
TypeKind::Named(..) |
TypeKind::Named |
TypeKind::Array(..) |
TypeKind::Comp(..) |
TypeKind::Int(..) |
Expand All @@ -345,8 +327,8 @@ impl Type {
TypeKind::Pointer(..) => Some(self),

TypeKind::ResolvedTypeRef(inner) |
TypeKind::Alias(_, inner) |
TypeKind::TemplateAlias(_, inner, _) |
TypeKind::Alias(inner) |
TypeKind::TemplateAlias(inner, _) |
TypeKind::TemplateRef(inner, _) => {
ctx.resolve_type(inner).safe_canonical_type(ctx)
}
Expand Down Expand Up @@ -379,8 +361,8 @@ impl CanDeriveDebug for Type {
len <= RUST_DERIVE_IN_ARRAY_LIMIT && t.can_derive_debug(ctx, ())
}
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(_, t, _) |
TypeKind::Alias(_, t) => t.can_derive_debug(ctx, ()),
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) => t.can_derive_debug(ctx, ()),
TypeKind::Comp(ref info) => {
info.can_derive_debug(ctx, self.layout(ctx))
}
Expand All @@ -399,9 +381,9 @@ impl<'a> CanDeriveCopy<'a> for Type {
t.can_derive_copy_in_array(ctx, ())
}
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(_, t, _) |
TypeKind::TemplateAlias(t, _) |
TypeKind::TemplateRef(t, _) |
TypeKind::Alias(_, t) => t.can_derive_copy(ctx, ()),
TypeKind::Alias(t) => t.can_derive_copy(ctx, ()),
TypeKind::Comp(ref info) => {
info.can_derive_copy(ctx, (item, self.layout(ctx)))
}
Expand All @@ -415,10 +397,10 @@ impl<'a> CanDeriveCopy<'a> for Type {
-> bool {
match self.kind {
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateAlias(_, t, _) |
TypeKind::Alias(_, t) |
TypeKind::TemplateAlias(t, _) |
TypeKind::Alias(t) |
TypeKind::Array(t, _) => t.can_derive_copy_in_array(ctx, ()),
TypeKind::Named(..) => false,
TypeKind::Named => false,
_ => self.can_derive_copy(ctx, item),
}
}
Expand Down Expand Up @@ -460,11 +442,11 @@ pub enum TypeKind {
Complex(FloatKind),

/// A type alias, with a name, that points to another type.
Alias(String, ItemId),
Alias(ItemId),

/// A templated alias, pointing to an inner type, just as `Alias`, but with
/// template parameters.
TemplateAlias(String, ItemId, Vec<ItemId>),
TemplateAlias(ItemId, Vec<ItemId>),

/// An array of a type and a lenght.
Array(ItemId, usize),
Expand Down Expand Up @@ -509,7 +491,7 @@ pub enum TypeKind {
ResolvedTypeRef(ItemId),

/// A named type, that is, a template parameter.
Named(String),
Named,
}

impl Type {
Expand All @@ -527,12 +509,12 @@ impl Type {
size == 0 || ctx.resolve_type(inner).is_unsized(ctx)
}
TypeKind::ResolvedTypeRef(inner) |
TypeKind::Alias(_, inner) |
TypeKind::TemplateAlias(_, inner, _) |
TypeKind::Alias(inner) |
TypeKind::TemplateAlias(inner, _) |
TypeKind::TemplateRef(inner, _) => {
ctx.resolve_type(inner).is_unsized(ctx)
}
TypeKind::Named(..) |
TypeKind::Named |
TypeKind::Int(..) |
TypeKind::Float(..) |
TypeKind::Complex(..) |
Expand Down Expand Up @@ -725,8 +707,7 @@ impl Type {
}
};

TypeKind::TemplateAlias(name.clone(),
inner_type,
TypeKind::TemplateAlias(inner_type,
args)
}
CXCursor_TemplateRef => {
Expand Down Expand Up @@ -873,7 +854,7 @@ impl Type {
let inner = cursor.typedef_type().expect("Not valid Type?");
let inner =
Item::from_ty_or_ref(inner, location, parent_id, ctx);
TypeKind::Alias(ty.spelling(), inner)
TypeKind::Alias(inner)
}
CXType_Enum => {
let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?");
Expand Down Expand Up @@ -935,12 +916,12 @@ impl TypeCollector for Type {
TypeKind::Pointer(inner) |
TypeKind::Reference(inner) |
TypeKind::Array(inner, _) |
TypeKind::Alias(_, inner) |
TypeKind::Alias(inner) |
TypeKind::ResolvedTypeRef(inner) => {
types.insert(inner);
}

TypeKind::TemplateAlias(_, inner, ref template_args) |
TypeKind::TemplateAlias(inner, ref template_args) |
TypeKind::TemplateRef(inner, ref template_args) => {
types.insert(inner);
for &item in template_args {
Expand All @@ -962,7 +943,7 @@ impl TypeCollector for Type {

// None of these variants have edges to other items and types.
TypeKind::UnresolvedTypeRef(_, _, None) |
TypeKind::Named(_) |
TypeKind::Named |
TypeKind::Void |
TypeKind::NullPtr |
TypeKind::Int(_) |
Expand Down