Skip to content
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

Bug: compiler error when inheriting from DataTemplateSelectorT #1457

Closed
dlech opened this issue Nov 23, 2024 · 6 comments · Fixed by #1458
Closed

Bug: compiler error when inheriting from DataTemplateSelectorT #1457

dlech opened this issue Nov 23, 2024 · 6 comments · Fixed by #1458

Comments

@dlech
Copy link
Contributor

dlech commented Nov 23, 2024

Version

2.0.240405.15

Summary

There is a compiler error due to code generated by cppwinrt when trying to use winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT as a base class.

Reproducible example

struct Example : DataTemplateSelectorT<Example>
{
};

Grab the project from https://github.com/dlech/BlankApp1, open in Visual Studio and build.

Code that causes the problem is here: https://github.com/dlech/BlankApp1/blob/d2869cb888d4d67534ba76643816a15bfa0274c8/BlankApp1/App.cpp#L16-L18

Expected behavior

cppwrint should generate code that doesn't cause a compile error.

Actual behavior

Build fails with the following error:

1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66450,9): error C2602: 'winrt::impl::consume_Windows_UI_Xaml_Controls_IDataTemplateSelectorOverrides<D>::SelectTemplateCore' is not a member of a base class of 'winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<Example>'
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66450,9): error C2602:         with
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66450,9): error C2602:         [
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66450,9): error C2602:             D=Example
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66450,9): error C2602:         ]
1>(compiling source file '/App.cpp')
1>    C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\impl\Windows.UI.Xaml.Controls.0.h(17492,14):
1>    see declaration of 'winrt::impl::consume_Windows_UI_Xaml_Controls_IDataTemplateSelectorOverrides<D>::SelectTemplateCore'
1>        with
1>        [
1>            D=Example
1>        ]
1>    C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66436,12):
1>    see declaration of 'winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<Example>'
1>    C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66450,9):
1>    the template instantiation context (the oldest one first) is
1>        C:\Users\extra\source\repos\BlankApp1\BlankApp1\App.cpp(16,18):
1>        see reference to class template instantiation 'winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<Example>' being compiled
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66451,9): error C2602: 'winrt::impl::consume_Windows_UI_Xaml_Controls_IDataTemplateSelectorOverrides2<D>::SelectTemplateCore' is not a member of a base class of 'winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<Example>'
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66451,9): error C2602:         with
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66451,9): error C2602:         [
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66451,9): error C2602:             D=Example
1>C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66451,9): error C2602:         ]
1>(compiling source file '/App.cpp')
1>    C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\impl\Windows.UI.Xaml.Controls.0.h(17501,14):
1>    see declaration of 'winrt::impl::consume_Windows_UI_Xaml_Controls_IDataTemplateSelectorOverrides2<D>::SelectTemplateCore'
1>        with
1>        [
1>            D=Example
1>        ]
1>    C:\Users\extra\source\repos\BlankApp1\BlankApp1\Generated Files\winrt\Windows.UI.Xaml.Controls.h(66436,12):
1>    see declaration of 'winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<Example>'

Additional comments

I discovered this while working on the PyWinRT bindings. Using any other TypeT as a base class compiles fine. There seems to be something odd about winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT::SelectTemplateCore specially. It is likely the only type where it has two overloads with the same name and different parameters defined in two different interfaces.

@dlech
Copy link
Contributor Author

dlech commented Nov 23, 2024

The error from the reproducible test case says "is not a member of a base class of ", but I think this is actually a case of a ambiguous name. Here is the output from compiling some similar code with the clang compiler instead of msvc.

C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/Windows.UI.Xaml.Controls.h:66451:15: error: using declaration refers into 'impl::consume_t<python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>, winrt::Windows::UI::Xaml::Controls::IDataTemplateSelectorOverrides2>::', which is not a base class of 'DataTemplateSelectorT<py::python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>>'
 66451 |         using impl::consume_t<D, winrt::Windows::UI::Xaml::Controls::IDataTemplateSelectorOverrides2>::SelectTemplateCore;
       |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/Windows.UI.Xaml.Controls.h:31610:88: error: member 'SelectTemplateCore' found in multiple base classes of different types
 31610 |             *result = detach_from<winrt::Windows::UI::Xaml::DataTemplate>(this->shim().SelectTemplateCore(*reinterpret_cast<winrt::Windows::Foundation::IInspectable const*>(&item), *reinterpret_cast<winrt::Windows::UI::Xaml::DependencyObject const*>(&container)));   
       |                                                                                    
    ^
C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/base.h:7255:12: note: in instantiation of member function 'winrt::impl::produce<py::python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>, winrt::Windows::UI::Xaml::Controls::IDataTemplateSelectorOverrides>::SelectTemplateCore' requested here
 7255 |     struct producer
      |            ^
C:/Users/extra/work/pywinrt/projection/winrt-Windows.UI.Xaml.Controls/py.Windows.UI.Xaml.Controls.cpp:105:83: note: in instantiation of member function 'winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<py::python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>>::DataTemplateSelectorT' requested here
  105 |         python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>() : winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>>() {}
      |                                                                                   ^ 
C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/impl/Windows.UI.Xaml.Controls.2.h:3504:14: note: member found by ambiguous name lookup
 3504 |         auto SelectTemplateCore(winrt::Windows::Foundation::IInspectable const& item, winrt::Windows::UI::Xaml::DependencyObject const& container) const;
      |              ^
C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/impl/Windows.UI.Xaml.Controls.2.h:3513:14: note: member found by ambiguous name lookup
 3513 |         auto SelectTemplateCore(winrt::Windows::Foundation::IInspectable const& item) const;
      |              ^
In file included from C:/Users/extra/work/pywinrt/projection/winrt-Windows.UI.Xaml.Controls/py.Windows.UI.Xaml.Controls.cpp:3:
In file included from C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/pywinrt/py.Windows.UI.Xaml.Controls.h:85:
In file included from C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/pywinrt/py.Windows.UI.Xaml.h:61:
In file included from C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/pywinrt/py.Windows.UI.Xaml.Controls.Primitives.h:33:
In file included from C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/pywinrt/py.Windows.UI.Xaml.Input.h:47:
C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/Windows.UI.Xaml.Controls.h:31622:88: error: member 'SelectTemplateCore' found in multiple base classes of different types
 31622 |             *result = detach_from<winrt::Windows::UI::Xaml::DataTemplate>(this->shim().SelectTemplateCore(*reinterpret_cast<winrt::Windows::Foundation::IInspectable const*>(&item)));
       |                                                                                    
    ^
C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/base.h:7255:12: note: in instantiation of member function 'winrt::impl::produce<py::python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>, winrt::Windows::UI::Xaml::Controls::IDataTemplateSelectorOverrides2>::SelectTemplateForItemCore' requested here
 7255 |     struct producer
      |            ^
C:/Users/extra/work/pywinrt/projection/winrt-Windows.UI.Xaml.Controls/py.Windows.UI.Xaml.Controls.cpp:105:83: note: in instantiation of member function 'winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<py::python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>>::DataTemplateSelectorT' requested here
  105 |         python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>() : winrt::Windows::UI::Xaml::Controls::DataTemplateSelectorT<python_impl<winrt::Windows::UI::Xaml::Controls::DataTemplateSelector>>() {}
      |                                                                                   ^ 
C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/impl/Windows.UI.Xaml.Controls.2.h:3504:14: note: member found by ambiguous name lookup
 3504 |         auto SelectTemplateCore(winrt::Windows::Foundation::IInspectable const& item, winrt::Windows::UI::Xaml::DependencyObject const& container) const;
      |              ^
C:/Users/extra/work/pywinrt/projection/winrt-sdk/src/winrt_sdk/cppwinrt/winrt/impl/Windows.UI.Xaml.Controls.2.h:3513:14: note: member found by ambiguous name lookup
 3513 |         auto SelectTemplateCore(winrt::Windows::Foundation::IInspectable const& item) const;
      |              ^
4 errors generated.

@sylveon
Copy link
Contributor

sylveon commented Nov 23, 2024

Here's a smaller repro:

namespace RuntimeComponent2
{
    interface IClass;
    interface IClassFactory;
    interface IClassOverrides;
    interface IClassOverrides2;

    [exclusiveto(RuntimeComponent2.Class)]
    [uuid(A907D496-46A0-4CD7-8DBE-F9A581DF60B1)]
    [version(0x00000001)]
    interface IClass : IInspectable
    {
    }

    [exclusiveto(RuntimeComponent2.Class)]
    [uuid(511BAAD0-210A-457D-9521-433D2B11B7D2)]
    [version(0x00000001)]
    interface IClassFactory : IInspectable
    {
        HRESULT CreateInstance([in] IInspectable* baseInterface, [out] IInspectable** innerInterface, [out][retval] RuntimeComponent2.Class** value);
    }

    [exclusiveto(RuntimeComponent2.Class)]
    [uuid(2D162925-5966-4BFA-8638-4D345689F6CF)]
    [version(0x00000001)]
    interface IClassOverrides : IInspectable
    {
        HRESULT Foo(int a);
    }

    [exclusiveto(RuntimeComponent2.Class)]
    [uuid(6C3FB5FC-8E84-4C91-AC15-04A1D885500F)]
    [version(0x00000001)]
    interface IClassOverrides2 : IInspectable
    {
        [overload("Foo")] HRESULT Foo2(int a, int b);
    }

    [composable(RuntimeComponent2.IClassFactory, public,1)]
    [marshaling_behavior(agile)]
    [threading(both)]
    [version(0x00000001)]
    runtimeclass Class
    {
        [default] interface RuntimeComponent2.IClass;
        [overridable] interface RuntimeComponent2.IClassOverrides;
        [overridable] interface RuntimeComponent2.IClassOverrides2;
    }
}

It appears to be a bug in write_class_override_usings. If I remove [overload("Foo")] the two using are not created and the bug does not reproduce.

DataTemplateSelector appears to be the only case of this happening
Image

@sylveon
Copy link
Contributor

sylveon commented Nov 23, 2024

Opened #1458 with a fix. Was relatively trivial thankfully.

@dlech
Copy link
Contributor Author

dlech commented Nov 23, 2024

Wow, same day service! Thanks for having a look!

@sylveon
Copy link
Contributor

sylveon commented Nov 23, 2024

Haha. I wanted to make sure it wasn't a regression introduced by a previous PR of mine, which was the last change to code touching overridable members.

Once I realized it was a bug in write_class_override_usings (which my PR didn't change, so it wasn't a regression) it became fairly obvious what the issue was.

The code was writing an using impl::consume_t for overloads that came from different interfaces, because otherwise you would get "ambiguous call" compiler errors. But when you use FooT to inherit from a WinRT class, any IFooOverridable interface isn't added by inheriting from consume_t<IFooOverridable> but from produce<IFooOverridable>. Just had to adjust the writer to compensate for this case :)

Copy link

github-actions bot commented Dec 4, 2024

This issue is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 5 days.

dmachaj pushed a commit that referenced this issue Dec 4, 2024
* Fix overloads coming from overridable interfaces

Fixes #1457

* PR feedback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants