Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Exposing a function that returns an array of tuples fails to compile

Closed
#1,329 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

A pull request for this has already been merged.

  • #1330 by @jgabry — merged

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
30/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
cpp, r

Research direction

Start by reproducing the failure with the snippet in the issue, which calls $expose_functions() on a function that returns an array of tuples. The header inst/include/rcpp_tuple_interop.hpp defines the tuple wrap overload, and compile_functions() in R/expose.R sets the include order for the generated code. Done means the tuple-array return compiles and exposes, and the existing tuple-argument behaviour still works.

Written by the indexing model from the issue text.

Description

bug

A Stan function that returns an array of tuples can't be exposed with $expose_functions(), and because every function in the block is compiled together, that means no functions from the model can be exposed.

library(cmdstanr)
mod <- cmdstan_model(write_stan_file("
functions {
  array[] tuple(real, real) f(array[] tuple(real, real) x) { return x; }
}
"))
mod$expose_functions()

The only message R shows is "Error 1 occurred building shared library". The compiler output is actually

Rcpp/internal/wrap.h:528:23: error: static assertion failed due to
requirement '!sizeof(std::tuple<double, double>)': cannot convert type
to SEXP

I did some investigating with Claude. Here's its diagnosis, although I haven't verified myself yet that this is correct:

The cause is in inst/include/rcpp_tuple_interop.hpp. It defines Rcpp::wrap for std::tuple, which works when the tuple is the return type itself (and for nested tuples, where the overload calls itself).
For std::vector<std::tuple<...>> Rcpp's own container wrap takes over and calls ::Rcpp::wrap per element from inside the Rcpp headers (wrap.h:200, range_wrap_dispatch___generic), where our overload isn't visible yet, so the generic fallback fires its static assertion. It's the same visibility problem that keeps Rcpp::List::create(args...) from compiling for nested tuples (see the commit message of #1310).

Taking a tuple array as an argument is fine, the Exporter side handles it. Only returning one fails.

Rcpp's documented way to extend wrap for a new type is to include RcppCommon.h, declare the overload, then include Rcpp.h, so the declaration is visible to the templates in the Rcpp headers. The
generated code includes Rcpp.h first through the other interop headers, so this would need the include order in compile_functions() (R/expose.R) rearranged. Untested.

Tested on macOS with CmdStan 2.40.0, Rcpp 1.1.2, on the v1.0 branch with the fix for #1001 (#1310) in. Pre-existing: the old tuple header failed the same way.

Dominant language
R
Stars
164
Forks
69
Avg merge
1d 10h
Merged PRs (30d)
47

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from stan-dev/cmdstanr

All issues in stan-dev/cmdstanr

Similar issues

More R issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.