Skip to content

windows-bindgen should avoid Param traits as much as possible #3320

@kennykerr

Description

@kennykerr

The Param trait provide the convertibility necessary for many APIs but the metadata, particularly for Win32, don't make it clear what those APIs are so the bindings tend to overuse the Param trait "just in case". This causes a lot of confusion especially for folks new to Rust or Windows. A common mistake is to pass a raw pointer value when a HANDLE is expected. The Rust compiler error would be very straightforward if not for the Param trait.

fn main() {
    let handle = std::ptr::null_mut();
    windows::Wdk::Foundation::NtClose(handle);
}

In this case, the compiler error message is very unhelpful.

D:\git\sample>cargo check -p hello_world
    Checking hello_world v0.1.0 (D:\git\sample\crates\hello_world)
error[E0277]: the trait bound `*mut _: Param<HANDLE, CopyType>` is not satisfied
 --> crates\hello_world\src/main.rs:3:39
  |
3 |     windows::Wdk::Foundation::NtClose(handle);
  |     --------------------------------- ^^^^^^ the trait `CanInto<HANDLE>` is not implemented for `*mut _`, which is required by `*mut _: Param<HANDLE, CopyType>`
  |     |
  |     required by a bound introduced by this call
  |
  = help: the following other types implement trait `CanInto<T>`:
            `HINSTANCE` implements `CanInto<HMODULE>`
            `HMODULE` implements `CanInto<HINSTANCE>`
            `HWND` implements `CanInto<HANDLE>`
            `IAgileObject` implements `CanInto<IUnknown>`
            `IAgileReference` implements `CanInto<IUnknown>`
            `IGenericFactory` implements `CanInto<IInspectable>`
            `IGenericFactory` implements `CanInto<IUnknown>`
            `IInspectable` implements `CanInto<IUnknown>`
          and 2 others
  = note: required for `*mut _` to implement `Param<HANDLE, CopyType>`
note: required by a bound in `NtClose`
 --> C:\Users\kekerr\.cargo\registry\src\index.crates.io-6f17d22bba15001f\windows-0.58.0\src\Windows\Wdk\Foundation\mod.rs:4:9
  |
2 | pub unsafe fn NtClose<P0>(handle: P0) -> super::super::Win32::Foundation::NTSTATUS
  |               ------- required by a bound in this function
3 | where
4 |     P0: windows_core::Param<super::super::Win32::Foundation::HANDLE>,
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `NtClose`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `hello_world` (bin "hello_world") due to 1 previous error

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions