Migrate windows-bindgen to use windows-metadata for winmd parsing#3915
Migrate windows-bindgen to use windows-metadata for winmd parsing#3915
Conversation
Remove the duplicate ECMA-335 winmd parsing code (~1647 lines) from
windows-bindgen and replace it with windows-metadata's reader types.
Changes:
- Add windows-metadata = { workspace = true } to Cargo.toml
- Delete winmd/file.rs (ECMA-335 binary parser, ~851 lines)
- Delete winmd/bindings.rs (Windows PE structs, ~234 lines)
- Delete winmd/row.rs (Row types with 'static trick, ~159 lines)
- Delete winmd/blob.rs (Blob with reader() method, ~191 lines)
- Delete winmd/codes.rs (coded indices Decode trait, ~128 lines)
- Delete winmd/attributes.rs (flags macros, ~84 lines)
- Rewrite winmd/mod.rs: type aliases for windows-metadata 'static types,
ELEMENT_TYPE constants, extension traits (BlobExt, TypeDefOrRefExt,
MemberRefParentExt, HasReader, GuidAttributeExt)
- Rewrite winmd/reader.rs: Reader wraps windows-metadata TypeIndex via
Box::into_raw and unsafe 'static transmute; thread-local for reader access
- Rewrite tables/*.rs as extension traits on windows-metadata types
- Rename conflicting methods: field_type(), constant_type(),
constant_value(), method_signature() to avoid shadowing metadata's
inherent methods
- Update all call sites throughout codebase
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
|
@copilot looks like a reasonable first pass - please fix the build breaks and then I'll take another look. |
… extension methods Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
Fixed in c18956b. The build break was in |
|
@copilot more build failures - keep fixing them please. |
Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
|
@copilot Additional CI failures, fix them. |
|
@copilot There are additional CI failures. Check them out and apply fixes as needed. |
|
@copilot please fix the build failure. |
…es, bindings.rs, code gen names Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
Fixed in d20212c. There were multiple independent build failures:
All 15 |
|
@copilot please fix the remaining build failures. |
…unds Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
Fixed in d55670c. The The root cause: The 2 remaining bytes were exactly |
- ConstantExt no longer has constant_value(); all call sites now use .value() directly (the inherent windows_metadata::Constant::value()) - Removed mod impl_map; from tables/mod.rs; ImplMapExt::scope() was an unused alias for import_scope() and had no call sites Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
|
@copilot please fix build break. |
| self.str(2) | ||
| impl ImplMapExt for ImplMap { | ||
| fn scope(&self) -> ModuleRef { | ||
| self.import_scope() |
There was a problem hiding this comment.
@copilot why not remove the trait and just call the method directly?
There was a problem hiding this comment.
Done in d5e3ac7. impl_map.rs deleted — ImplMapExt had no call sites (all call sites already use import_scope() directly).
|
|
||
| pub use windows_metadata::MethodCallAttributes; | ||
| // Extension trait for Blob: adds bindgen-specific read helpers. | ||
| pub trait BlobExt { |
There was a problem hiding this comment.
@copilot I think we've removed all uses of direct blob parsing - can we remove this now?
There was a problem hiding this comment.
Done in d5e3ac7. The entire BlobExt trait and implementation removed — all four methods (read_usize, read_str, read_integer, reader) had no call sites outside the definition.
…s_default_constructor - required_interfaces(): use with_full_name().next() instead of unwrap_full_name() so contract types (like Windows.Foundation.UniversalApiContract) that are skipped from the Reader map are gracefully skipped rather than causing a panic - has_default_constructor(): check for actual Type::Interface args rather than any Value::Utf8, so ActivatableAttribute(UniversalApiContract, 4) (no factory interface) correctly returns true Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
Fixed in 58c2a2b. The panic was
Fixed by replacing |
…MapExt - tables/field.rs: field_type() now calls windows-metadata Field::ty() + Type::from_metadata_type() instead of manual blob parsing - tables/impl_map.rs: deleted (file was not in mod.rs; ImplMapExt had no call sites) - winmd/mod.rs: removed BlobExt trait and implementation (read_usize/read_str/read_integer/reader all had no call sites) Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
|
@copilot please fix build break. |
…in index.rs Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
Fixed in 869f32e. The Root cause: |
windows-bindgencontained ~1,650 lines of ECMA-335 parsing logic that duplicated whatwindows-metadataalready provides. This removes all of that internal parsing code and replaces it with direct use ofwindows-metadata, including full unification of theType,Value, andSignaturerepresentations.What's this all about?
windows-bindgennow delegates all ECMA-335 parsing — type signatures, method signatures, attribute arguments, and constant values — exclusively towindows-metadata. All intermediate extension-trait wrappers that merely forwarded towindows-metadatainherent methods have been removed; call sites now call those methods directly.Changes
winmd/file.rs,row.rs,blob.rs,codes.rs,attributes.rs— the internal ECMA-335 parsertables/attribute.rs— theAttributeExttrait is no longer needed; call sites now callwindows-metadata::Attribute::value()directlytables/impl_map.rs— theImplMapExttrait had no call sites and is no longer needed; all call sites now callwindows-metadata::ImplMapmethods directlywinmd/bindings.rs— restored as a generated file (produced bytool_bindings);winmd/mod.rsnow includes it viamod bindings; pub use bindings::*;winmd/mod.rs— re-exportswindows-metadatatypes as'staticaliases (e.g.type TypeDef = windows_metadata::reader::TypeDef<'static>), preserving the existing'staticlifetime convention without pervasive lifetime changes;CorElementTypeandELEMENT_TYPE_*constants are now sourced frombindings.rs;MethodCallAttributesis now re-exported directly fromwindows-metadatarather than redefined locally;TypeDefOrRefExtandMemberRefParentExttype_name()impls are now free ofunsafe/transmute;BlobExttrait removed as all direct blob parsing has been eliminatedwinmd/reader.rs—Readerwrapswindows_metadata::reader::TypeIndexviaBox::into_raw+ unsafe'statictransmute; the oldreader: *const Readerfield on eachFileis replaced by a thread-localCURRENT_READER;with_full_nametrims generic arity suffixes (`1,`2, etc.) so rawTypeDef::name()values resolve correctly against theTypeIndexmap; nested-type collection is now recursive to handle deeply-nested structs (e.g.VARIANT → VARIANT_0 → _Anonymous_e__Struct)tables/*.rs— replaced with extension traits (TypeDefExt,FieldExt,MethodDefExt, etc.) that layer bindgen-specific methods on top of the metadata types; nounsafeortransmuteis needed in any table extensiontables/field.rs—field_type()now callswindows-metadata::Field::ty()+Type::from_metadata_type()instead of manual blob parsing;FieldExtis the only remaining trait wrappertables/method_def.rs—method_signature()now delegates towindows-metadata::MethodDef::signature()for blob parsing; a newType::from_metadata_type()converter mapswindows_metadata::Type→windows_bindgen::Type;from_blob_implis eliminated entirelytables/constant.rs—ConstantExt::constant_value()wrapper removed; call sites now callwindows-metadata::Constant::value()directly;constant_type()usesType::from_metadata_type()tables/type_ref.rs—TypeRef::name()andTypeRef::namespace()are called directly; nounsafeortransmuterequiredtypes/mod.rs— addedType::from_metadata_type()which convertswindows-metadata::Typetowindows-bindgen::Type(full remap includingVALUETYPE/CLASSresolution viacurrent_reader().unwrap_full_name());from_blobnow delegates toblob.read_type_signature()+from_metadata_type;from_blob_impldeletedvalue.rs— removed the customValueenum; replaced withpub use windows_metadata::Value; addedValueExttrait providing thewrite()method; all callers updated (Value::Str→Value::Utf8,Value::TypeName→Value::Utf8,Value::String→Value::Utf16)types/delegate.rs,types/interface.rs,types/class.rs,types/method.rs— code generation now usestrim_tick(def.name())for Rust identifiers so WinRT generic types (e.g.IIterable`1) produce valid tokenstypes/class.rs—required_interfaces()now useswith_full_name().next()instead ofunwrap_full_name()so WinRT API contract types (e.g.Windows.Foundation.UniversalApiContract) that are intentionally excluded from the Reader map are gracefully skipped rather than causing a panic;has_default_constructor()now checks for actualType::Interfacefactory args rather than anyValue::Utf8arg, soActivatableAttribute(UniversalApiContract, 4)(default constructor, no factory) is correctly identifiedtypes/index.rs—method_signature()now receives the interface's actualgenericsslice instead of&[], fixing a panic (index out of bounds) whentool_bindingsprocesses generic interfaces (e.g.IIterable<T>) whose method signatures containELEMENT_TYPE_VARreferenceslib.rs— restorednon_snake_caseandnon_camel_case_typeslint expectations required bybindings.rscrates/libs/windows/features.json— regenerated with correct trimmed names for generic WinRT typesCargo.toml— addedwindows-metadatadependencywindows-metadata:ImplMap::import_name()— changed return type from&strto&'a strwindows-metadata:ModuleRef::name()— changed return type from&strto&'a strwindows-metadata:TypeDefOrRef::namespace()andTypeDefOrRef::name()— changed to return&'a str, consistent withMemberRefParent; eliminates the need forunsafe { transmute }inTypeDefOrRefExt::type_name()andMemberRefParentExt::type_name()windows-metadata:flags!macro — changed the inner field visibility frompub(crate)topubso flag types such asMethodCallAttributescan be constructed from raw values by external cratesThe approach keeps the existing unsafe
'staticpattern (heap-pinnedTypeIndex, never moved, freed inDrop) to avoid cascading lifetime parameter changes across the entire codebase, while eliminating all duplicate parsing logic.windows-metadatais now used exclusively for all ECMA-335 blob parsing — type signatures, method signatures, attribute arguments, and constant values. Nounsafeortransmuteappears in any of thetables/extension trait implementations, and no direct blob parsing remains anywhere inwindows-bindgen.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.