pybind11
pybind11 copied to clipboard
Compilation error `recursive type or function dependency context too complex` when using a lot of Eigen array arguments
Issue description
The bindings for a function that worked in pybind11 2.2.4 does not compile anymore in pybind11 2.3.0. The function contains a lot of arguments with Eigen arrays.
Reproducible example code
I've built this minimal case:
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>
namespace py = pybind11;
using EigenArray2d = Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
using EigenArray2dConstRef = Eigen::Ref<const EigenArray2d>;
void f(
EigenArray2dConstRef const& a00,
EigenArray2dConstRef const& a01,
EigenArray2dConstRef const& a02,
EigenArray2dConstRef const& a03,
EigenArray2dConstRef const& a04,
EigenArray2dConstRef const& a05,
EigenArray2dConstRef const& a06,
EigenArray2dConstRef const& a07,
EigenArray2dConstRef const& a08,
EigenArray2dConstRef const& a09,
EigenArray2dConstRef const& a10,
EigenArray2dConstRef const& a11,
EigenArray2dConstRef const& a12,
EigenArray2dConstRef const& a13,
EigenArray2dConstRef const& a14,
EigenArray2dConstRef const& a15,
EigenArray2dConstRef const& a16,
EigenArray2dConstRef const& a17,
EigenArray2dConstRef const& a18,
EigenArray2dConstRef const& a19
);
void test(py::module& m)
{
m.def("f", &f);
}
my current workaround is to create wrapper functions (or constructors), receiving py::args
and py::kwargs
, casting everything and passing them down to the original function (but this does not seem to be a good solution).
Error information
This is the current compilation error, from MSVC 2017 (15.8.7):
c:\conda\envs\test_pybind11\include\pybind11\detail\descr.h(45): fatal error C1202: recursive type or function dependency context too complex
c:\conda\envs\test_pybind11\include\pybind11\detail\descr.h(49): note: see reference to function template instantiation 'pybind11::detail::descr<1038> pybind11::detail::plus_impl<52,986,,,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450...
c:\conda\envs\test_pybind11\include\pybind11\detail\descr.h(90): note: see reference to function template instantiation 'pybind11::detail::descr<1038> pybind11::detail::operator +<52,986,,>(const pybind11::detail::descr<52> &,const pybind11::detail::descr<986> &)' being compiled
c:\conda\envs\test_pybind11\include\pybind11\cast.h(1900): note: see reference to function template instantiation 'pybind11::detail::descr<1038> pybind11::detail::concat<50,,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>,pybind11::detail::descr<50>>(const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &,const pybind11::detail::descr<50> &)' being compiled
c:\conda\envs\test_pybind11\include\pybind11\pybind11.h(101): note: see reference to class template instantiation 'pybind11::detail::argument_loader<const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &>' being compiled
c:\conda\envs\test_pybind11\include\pybind11\pybind11.h(64): note: see reference to function template instantiation 'void pybind11::cpp_function::initialize<Return(__cdecl *&)(const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &),Return,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,pybind11::name,pybind11::scope,pybind11::sibling>(Func,Return (__cdecl *)(const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &),const pybind11::name &,const pybind11::scope &,c...
c:\conda\envs\test_pybind11\include\pybind11\pybind11.h(819): note: see reference to function template instantiation 'pybind11::cpp_function::cpp_function<void,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,const EigenArray2dConstRef&,pybind11::name,pybind11::scope,pybind11::sibling>(Return (__cdecl *)(const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &),const pybind11::name &,const pybind11::scope &,const pybind11::sibling &)' being compiled
with
[
Return=void
]
c:\dev\test_pybind11\test_pybind11.cpp(34): note: see reference to function template instantiation 'pybind11::module &pybind11::module::def<void(__cdecl *)(const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &),>(const char *,Func &&)' being compiled
with
[
Func=void (__cdecl *)(const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &,const EigenArray2dConstRef &)
]
c:\conda\envs\test_pybind11\include\pybind11\cast.h(1556): note: see reference to class template instantiation 'pybind11::detail::descr<8>' being compiled
c:\conda\envs\test_pybind11\include\pybind11\cast.h(1554): note: see reference to class template instantiation 'pybind11::detail::descr<5>' being compiled
c:\conda\envs\test_pybind11\include\pybind11\cast.h(1109): note: see reference to class template instantiation 'pybind11::detail::descr<7>' being compiled
cc @tarcisiofischer
Sounds like MSVC runs into some internal limits when expanding templates. I'm not convinced that this is actually a pybind11 issue.
Indeed, it looks like that. I've posted the issue anyway, because the same code worked in version 2.2.4. Also, if more people gets the same error, at least it's documented here with a possible workaround :).
The closest changes that I found that could be related to it were these ones, but they are from Jul/2017, so it is a far shot.
I'm getting this while wrapping an object that inherits from other objects and has many properties of it's own. My (very bad) solution for now is not to wrap all the properties under windows so that MSVC does not fail due to this.
Is there any workarround? maybe declare an object wrapper in two steps?
Resolved by #4587