diff --git a/crates/libs/bindgen/src/metadata.rs b/crates/libs/bindgen/src/metadata.rs index 9a60ddc868..0a0dff5b07 100644 --- a/crates/libs/bindgen/src/metadata.rs +++ b/crates/libs/bindgen/src/metadata.rs @@ -442,9 +442,7 @@ pub fn type_interfaces(ty: &Type) -> Vec { // This will both sort the results and should make finding dupes faster fn walk(result: &mut Vec, parent: &Type, is_base: bool) { if let Type::TypeDef(row, generics) = parent { - for imp in row.interface_impls() { - let mut child = Interface { ty: imp.ty(generics), kind: if imp.has_attribute("DefaultAttribute") { InterfaceKind::Default } else { InterfaceKind::None } }; - + for mut child in type_def_interfaces(*row, generics) { child.kind = if !is_base && child.kind == InterfaceKind::Default { InterfaceKind::Default } else if child.kind == InterfaceKind::Overridable { @@ -656,8 +654,15 @@ pub fn type_def_has_packing(row: TypeDef) -> bool { } } +pub fn type_def_interfaces(def: TypeDef, generics: &[Type]) -> impl Iterator + '_ { + def.interface_impls().map(|imp| { + let kind = if imp.has_attribute("DefaultAttribute") { InterfaceKind::Default } else { InterfaceKind::None }; + Interface { kind, ty: imp.ty(generics) } + }) +} + pub fn type_def_default_interface(row: TypeDef) -> Option { - row.interface_impls().find_map(move |imp| if imp.has_attribute("DefaultAttribute") { Some(imp.ty(&[])) } else { None }) + type_def_interfaces(row, &[]).find_map(move |interface| if interface.kind == InterfaceKind::Default { Some(interface.ty) } else { None }) } fn type_signature(ty: &Type) -> String { diff --git a/crates/libs/bindgen/src/rdl/from_reader.rs b/crates/libs/bindgen/src/rdl/from_reader.rs index b5bc799604..856e8a131c 100644 --- a/crates/libs/bindgen/src/rdl/from_reader.rs +++ b/crates/libs/bindgen/src/rdl/from_reader.rs @@ -286,12 +286,11 @@ impl Writer { // TODO: then list default interface first // Then everything else - for imp in def.interface_impls() { - let ty = imp.ty(generics); - if imp.has_attribute("DefaultAttribute") { - types.insert(0, self.ty(&ty)); + for interface in type_def_interfaces(def, generics) { + if interface.kind == InterfaceKind::Default { + types.insert(0, self.ty(&interface.ty)); } else { - types.push(self.ty(&ty)); + types.push(self.ty(&interface.ty)); } } diff --git a/crates/libs/bindgen/src/winmd/from_reader.rs b/crates/libs/bindgen/src/winmd/from_reader.rs index bfe8aa3d09..ed5f4d1783 100644 --- a/crates/libs/bindgen/src/winmd/from_reader.rs +++ b/crates/libs/bindgen/src/winmd/from_reader.rs @@ -43,9 +43,8 @@ pub fn from_reader(reader: &metadata::Reader, config: std::collections::BTreeMap }); } - for imp in def.interface_impls() { - let ty = imp.ty(generics); - let ty = winmd_type(&ty); + for interface in metadata::type_def_interfaces(def, generics) { + let ty = winmd_type(&interface.ty); let reference = match &ty { winmd::Type::TypeRef(type_name) if type_name.generics.is_empty() => writer.insert_type_ref(&type_name.namespace, &type_name.name),