- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 48
Closed
Labels
Description
Current Behavior:
The following Stan model compiles in stanc3:
functions {
   real foo(int x){
     return 1.0;
   }
   real bar(int y){
     return 2.0;
   }
   void baz(){
     // NB: putting this in later blocks produce an error due to assigning to a global variable
     foo = bar;
   }
}
model {
     print(foo(1));
    baz();
   print(foo(1));
}but the C++ fails to compile:
Cmdstan output
Building fun.stan
make: Entering directory '/home/brian/Dev/cpp/cmdstan'
cd /home/brian/Dev/ml/stanc3 && echo "--- Rebuilding stanc ---\n" && dune build @install
--- Rebuilding stanc ---\n
cp /home/brian/Dev/ml/stanc3/_build/default/src/stanc/stanc.exe bin/stanc
--- Translating Stan model to C++ code ---
bin/stanc  --o=../../ml/stanc3/fun.hpp ../../ml/stanc3/fun.stan
--- Compiling, linking C++ code ---
g++ -std=c++1y -pthread -D_REENTRANT -Wno-sign-compare -Wno-ignored-attributes      -I stan/lib/stan_math/lib/tbb_2020.3/include    -O3 -I src -I stan/src -I lib/rapidjson_1.1.0/ -I lib/CLI11-1.9.1/ -I stan/lib/stan_math/ -I stan/lib/stan_math/lib/eigen_3.3.9 -I stan/lib/stan_math/lib/boost_1.75.0 -I stan/lib/stan_math/lib/sundials_6.0.0/include -I stan/lib/stan_math/lib/sundials_6.0.0/src/sundials    -DBOOST_DISABLE_ASSERTS          -c -Wno-ignored-attributes   -x c++ -o ../../ml/stanc3/fun.o ../../ml/stanc3/fun.hpp
In file included from stan/lib/stan_math/stan/math/prim/meta/is_eigen_matrix_base.hpp:6,
                 from stan/lib/stan_math/stan/math/prim/meta/is_eigen.hpp:5,
                 from stan/lib/stan_math/stan/math/prim/meta/base_type.hpp:6,
                 from stan/lib/stan_math/stan/math/prim/meta/return_type.hpp:6,
                 from stan/lib/stan_math/stan/math/prim/meta/append_return_type.hpp:5,
                 from stan/lib/stan_math/stan/math/prim/meta.hpp:176,
                 from stan/lib/stan_math/stan/math/rev/core/accumulate_adjoints.hpp:4,
                 from stan/lib/stan_math/stan/math/rev/core.hpp:4,
                 from stan/lib/stan_math/stan/math/rev.hpp:8,
                 from stan/lib/stan_math/stan/math.hpp:19,
                 from stan/src/stan/model/model_header.hpp:4:
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp: In instantiation of ‘struct stan::is_base_pointer_convertible<Eigen::EigenBase, double (&)(const int&, std::basic_ostream<char>*)>’:
stan/lib/stan_math/stan/math/prim/meta/is_var_matrix.hpp:18:8:   recursively required by substitution of ‘template<class T> struct stan::value_type<T, typename std::enable_if<stan::is_eigen<T>::value, void>::type> [with T = double (&)(const int&, std::basic_ostream<char>*)]’
stan/lib/stan_math/stan/math/prim/meta/is_var_matrix.hpp:18:8:   required from ‘struct stan::is_var_matrix<double (&)(const int&, std::basic_ostream<char>*)>’
stan/lib/stan_math/stan/math/prim/meta/conjunction.hpp:17:8:   required from ‘struct stan::math::conjunction<stan::is_var_matrix<double (&)(const int&, std::basic_ostream<char, std::char_traits<char> >*)>, stan::is_eigen<double (&)(const int&, std::basic_ostream<char, std::char_traits<char> >*)> >’
stan/lib/stan_math/stan/math/prim/meta/require_helpers.hpp:63:24:   required by substitution of ‘template<class ... Checks> using require_any_not_t = std::enable_if_t<(! stan::math::conjunction<T>::value)> [with Checks = {stan::is_var_matrix<double (&)(const int&, std::basic_ostream<char, std::char_traits<char> >*)>, stan::is_eigen<double (&)(const int&, std::basic_ostream<char, std::char_traits<char> >*)>}]’
stan/src/stan/model/indexing/access_helpers.hpp:43:65:   required by substitution of ‘template<class T1, class T2, stan::require_any_not_t<stan::is_var_matrix<Container>, stan::is_eigen<T_actual> >* <anonymous> > void stan::model::internal::assign_impl(T1&&, T2&&) [with T1 = double (&)(const int&, std::basic_ostream<char>*); T2 = double (&)(const int&, std::basic_ostream<char>*); stan::require_any_not_t<stan::is_var_matrix<Container>, stan::is_eigen<T_actual> >* <anonymous> = <missing>]’
stan/src/stan/model/indexing/assign.hpp:57:24:   required from ‘void stan::model::assign(T&&, U&&, const char*) [with T = double (&)(const int&, std::basic_ostream<char>*); U = double (&)(const int&, std::basic_ostream<char>*); stan::require_t<std::is_assignable<typename std::decay<_Tp>::type&, typename std::decay<_Func>::type> >* <anonymous> = 0]’
../../ml/stanc3/fun.hpp:73:61:   required from here
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:29:17: error: no matching function for call to ‘stan::is_base_pointer_convertible<Eigen::EigenBase, double (&)(const int&, std::basic_ostream<char>*)>::f(double (*)(const int&, std::basic_ostream<char>*))’
   29 |     = decltype(f(std::declval<std::remove_reference_t<Derived> *>()))::value
      |                ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:24:26: note: candidate: ‘static std::false_type stan::is_base_pointer_convertible<Base, Derived>::f(const void*) [with Base = Eigen::EigenBase; Derived = double (&)(const int&, std::basic_ostream<char>*); std::false_type = std::integral_constant<bool, false>]’ <near match>
   24 |   static std::false_type f(const void *);
      |                          ^
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:24:26: note:   conversion of argument 1 would be ill-formed:
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:29:17: error: invalid conversion from ‘double (*)(const int&, std::basic_ostream<char>*)’ to ‘const void*’ [-fpermissive]
   29 |     = decltype(f(std::declval<std::remove_reference_t<Derived> *>()))::value
      |                ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                 |
      |                 double (*)(const int&, std::basic_ostream<char>*)
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:26:25: note: candidate: ‘template<class OtherDerived> static std::true_type stan::is_base_pointer_convertible<Base, Derived>::f(const Base<OtherDerived>*) [with OtherDerived = OtherDerived; Base = Eigen::EigenBase; Derived = double (&)(const int&, std::basic_ostream<char>*)]’
   26 |   static std::true_type f(const Base<OtherDerived> *);
      |                         ^
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:26:25: note:   template argument deduction/substitution failed:
stan/lib/stan_math/stan/math/prim/meta/is_base_pointer_convertible.hpp:29:17: note:   mismatched types ‘const Eigen::EigenBase<Derived>’ and ‘double(const int&, std::basic_ostream<char>*)’
   29 |     = decltype(f(std::declval<std::remove_reference_t<Derived> *>()))::value
      |                ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** [make/program:58: ../../ml/stanc3/fun] Error 1
make: Leaving directory '/home/brian/Dev/cpp/cmdstan'Expected Behavior:
At the moment I would expect this to be an error. After something like #742 or lambdas, I would expect the C++ generated to compile.
This is probably a low-priority issue as the cases it comes up are obviously pathological, I just wanted to document it.