Skip to content

HRTBs Aren't Assignable for a non-&self method but work fine for &self methods in the same impl #90448

@TheBlueMatt

Description

@TheBlueMatt

We have a bunch of code that reads a full Rust crate via syn and auto-generates C bindings for everything by concretizing traits into structs with a list of function pointers and wrapper structs for all the native types. While updating our C bindings for our latest release which now uses HRTBs for some traits, we ended up in a state where we cannot call a non-&self method due to HRTBs not being assignable, but can call a &self method in the sample impl block on the same concrete type just fine.

A simplified crate is included below, which fails in the playpen on latest nightly.

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=4d0e229a84ebc2d8d3e5060b1e7b0bb9

// Minimized Rust Code
trait A<'a> {
    type Inner: B + 'a;
    fn get(&'a self) -> Self::Inner;
}
trait B {}
trait C<TheB: B> {}

struct Thing<TheA, TheC> where TheA: for<'a> A<'a>, TheC: for<'a> C<<TheA as A<'a>>::Inner> {
    a: TheA,
    c: TheC,
}
impl<TheA, TheC> Thing<TheA, TheC> where TheA: for<'a> A<'a>, TheC: for<'a> C<<TheA as A<'a>>::Inner> {
  fn create(a: TheA, c: TheC) -> Self {
      Self { a , c }
  }
  fn call(&self) {}
}

// Minimized auto-generated C mappings
#[repr(C)]
pub struct BImpl {}
impl B for BImpl {}

#[repr(C)]
pub struct AImpl {}
impl<'a> A<'a> for AImpl {
    type Inner = BImpl;
    fn get(&'a self) -> BImpl { BImpl {} }
}

#[repr(C)]
pub struct CImpl {}
impl C<BImpl> for CImpl {
}

type ConcreteThing = Thing<AImpl, CImpl>;
#[repr(C)] // Here to show what's going on, though the compilation errors happen with a direct Thing<> too
pub struct CThing { inner: ConcreteThing }

// Static methods don't work?
#[no_mangle]
pub extern "C" fn Create_Thing(a: AImpl, c: CImpl) -> CThing {
    CThing { inner: ConcreteThing::create(a, c) }
}

// ... but non-static methods on the same work fine?
#[no_mangle]
pub extern "C" fn Thing_call(obj: &CThing) {
    obj.inner.call()
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions