Skip to content

Missing template argument for inner type typedef. #422

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

Closed
kkimdev opened this issue Jan 23, 2017 · 8 comments · Fixed by #2275
Closed

Missing template argument for inner type typedef. #422

kkimdev opened this issue Jan 23, 2017 · 8 comments · Fixed by #2275
Labels

Comments

@kkimdev
Copy link

kkimdev commented Jan 23, 2017

Header:

template <typename T>
class Foo {
 public:
  class InnerType {};
};

typedef Foo<int>::InnerType Bar;

Bar func();

Generated:

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo<T> {
    pub _address: u8,
    pub _phantom_0: ::std::marker::PhantomData<T>,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo_InnerType<T> {
    pub _address: u8,
    pub _phantom_0: ::std::marker::PhantomData<T>,
}
pub use self::Foo_InnerType as Bar;
extern "C" {
    #[link_name = "_Z4funcv"]
    pub fn func() -> Bar;
}

Compile error

error[E0243]: wrong number of type arguments: expected 1, found 0
  --> generated.rs:18:22
   |
18 |     pub fn func() -> Bar;
   |                      ^^^ expected 1 type argument

I think it should have generated

pub type Bar = self::Foo_InnerType<::std::os::raw::c_int>;
@fitzgen fitzgen added the bug label Jan 24, 2017
@fitzgen
Copy link
Member

fitzgen commented Jan 24, 2017

@emilio this seems related to the type aliases -> use statements change. I don't think that trick is valid if we have template arguments.

@emilio
Copy link
Contributor

emilio commented Jan 24, 2017

huh? Indeed we check for that. I was pretty sure this check should've caught it, I'll take a look

@emilio
Copy link
Contributor

emilio commented Jan 24, 2017

So we do check that, and that check works. the thing is that the applicable_template_args check probably avoids specialized args.

@emilio
Copy link
Contributor

emilio commented Jan 24, 2017

i.e., this was a pre-existing bug

@emilio
Copy link
Contributor

emilio commented Jan 24, 2017

This is annoying. So when scanning the Foo<int>::InnerType, clang says us we're a template specialization, but when it points us to the specialized template, it points us to the unspecialized version of Foo (which is probably a logical thing to do, but that we don't take into account).

When asking about template parameters, of course, clangs tells us that we have none, so we end up not seeing the int at all. Ouch.

I can't keep investigating today (3AM here and I need to wake up in exactly 4 hours :/), but that's pretty much it, we're going to need to find that type, somehow.

@fitzgen
Copy link
Member

fitzgen commented Mar 7, 2017

After #544, there is still a bug here, but we need to modify the test case so that Foo<T>::InnerType uses T to make the bug reproduce:

template <typename T>
class Foo {
public:
    class InnerType {
        T t;
    };
};

typedef Foo<int>::InnerType Bar;

Bar func();

Generates this code:

/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
    pub _address: u8,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo_InnerType<T> {
    pub t: T,
}
pub type Bar = InnerType;
extern "C" {
    #[link_name = "_Z4funcv"]
    pub fn func() -> Bar;
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct InnerType {
    pub _address: u8,
}
impl Clone for InnerType {
    fn clone(&self) -> Self { *self }
}

Not sure what is going on with that top level InnerType.

@kkimdev
Copy link
Author

kkimdev commented May 6, 2019

@emilio @fitzgen

@fitzgen's example code now generates the following and compiles fine. Should we consider this as fixed?

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
    pub _address: u8,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo_InnerType<T> {
    pub t: T,
    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
}
pub type Bar = InnerType;
extern "C" {
    #[link_name = "\u{1}_Z4funcv"]
    pub fn func() -> Bar;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct InnerType {
    pub _address: u8,
}

@emilio
Copy link
Contributor

emilio commented May 6, 2019

Yes, we should add a test-case to the test-suite if we don't have one though.

amanjeev added a commit to ferrous-systems/rust-bindgen that referenced this issue Sep 19, 2022
GitHub issue 422 was fixed but needs a test.
rust-lang#422

Signed-off-by: Amanjeev Sethi <[email protected]>
emilio pushed a commit that referenced this issue Sep 23, 2022
GitHub issue 422 was fixed but needs a test.
#422

Signed-off-by: Amanjeev Sethi <[email protected]>
qsdrqs pushed a commit to qsdrqs/rust-bindgen that referenced this issue Oct 26, 2022
GitHub issue 422 was fixed but needs a test.
rust-lang#422

Signed-off-by: Amanjeev Sethi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants