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

updated extendr to 0.7.0 #1154

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

updated extendr to 0.7.0 #1154

wants to merge 4 commits into from

Conversation

CGMossa
Copy link

@CGMossa CGMossa commented Jul 1, 2024

These are the changes necessary to update r-polars.
I discovered that we could make our macros a bit nicer, so I've done so in:

We will consider a patch release for extendr, where these improvements can be in. We'll just wait a few days / (1-2 weeks) to figure out if there are more patches to be made.

Cheers!

Close #1105

@CGMossa CGMossa marked this pull request as draft July 1, 2024 20:53
@etiennebacher
Copy link
Collaborator

Thanks @CGMossa, let us know once this is ready for review

@CGMossa
Copy link
Author

CGMossa commented Jul 7, 2024

Please review this PR now, and let me know what you think. We'll publish a patch release based on the out come of this PR.

We had to merge a few PRs to make the code nicer here. I think we've accomplished that.

@etiennebacher
Copy link
Collaborator

etiennebacher commented Jul 7, 2024

This PR generates a segfault in some tests. I can reproduce locally, the line that causes it is:

expect_grepl_error(pl$head(df$get_column("a"), -2))

(L185, "tests/testthat/test-lazy_functions.R"). I don't know the cause

@CGMossa
Copy link
Author

CGMossa commented Jul 7, 2024

Running with a debugger yields:

pl$n_unique(pl$all()) does not throw the expected error

Loading required namespace: usethis
> source("/Users/elea/Documents/GitHub/r-polars/tests/testthat/test-lazy_funs.R")
Error in test_that("pl$col", { : could not find function "test_that"
> devtools::load_all()
ℹ Loading polars
> source("/Users/elea/Documents/GitHub/r-polars/tests/testthat/test-lazy_funs.R")
Test passed 
Test passed 
Test passed 
Test passed 
Test passed 
Test passed 
Test passed 
Test passed 
-- Failure: pl$n_unique --------------------------------------------------------
pl$n_unique(pl$all()) does not throw the expected error

Error:
! Test failed
Backtrace:
    x
 1. +-base::source("/Users/elea/Documents/GitHub/r-polars/tests/testthat/test-lazy_functions.R")
 2. | +-base::withVisible(eval(ei, envir))
 3. | \-base::eval(ei, envir)
 4. |   \-base::eval(ei, envir)
 5. +-testthat::test_that(...) at tests/testthat/test-lazy_functions.R:145:1
 6. | \-withr (local) `<fn>`() at tests/testthat/test-lazy_functions.R:145:1
 7. \-reporter$stop_if_needed()
 8.   \-rlang::abort("Test failed", call = NULL)

@CGMossa
Copy link
Author

CGMossa commented Jul 7, 2024

Details

s/testthat/test-lazy_functions.R")

══ Testing test-lazy_functions.R ═══════════════════════════════════════════════
[ FAIL 2 | WARN 0 | SKIP 0 | PASS 41 ]Process 82992 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x800000000000001a)
    frame #0: 0x000000035666dbb0 polars.so`_$LT$polars_core..datatypes..dtype..DataType$u20$as$u20$core..clone..Clone$GT$::clone::h4f9ba5acc57bbc29 + 108
polars.so`_$LT$polars_core..datatypes..dtype..DataType$u20$as$u20$core..clone..Clone$GT$::clone::h4f9ba5acc57bbc29:
->  0x35666dbb0 <+108>: strb   w19, [x0, #0x1]
    0x35666dbb4 <+112>: str    x8, [x0, #0x8]
    0x35666dbb8 <+116>: ldr    q0, [sp]
    0x35666dbbc <+120>: str    q0, [x0, #0x10]
Target 0: (R) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x800000000000001a)
  * frame #0: 0x000000035666dbb0 polars.so`_$LT$polars_core..datatypes..dtype..DataType$u20$as$u20$core..clone..Clone$GT$::clone::h4f9ba5acc57bbc29 + 108
    frame #1: 0x0000000356685ea4 polars.so`r_polars::utils::robj_to_datatype::h76ee6a80e16d0364 + 248
    frame #2: 0x00000003564cb660 polars.so`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::hccee459e432aaacb + 144
    frame #3: 0x000000035662ae38 polars.so`_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$GT$::from_iter::h5f7e619b183f4ff8 + 60
    frame #4: 0x00000003567facf8 polars.so`core::iter::adapters::try_process::h47f708e0c7aace4e + 100
    frame #5: 0x0000000356539808 polars.so`r_polars::lazy::dsl::create_cols_from_datatypes::h20fad0f5a3422d58 + 512
    frame #6: 0x0000000356539aec polars.so`wrap__create_cols_from_datatypes + 28
    frame #7: 0x00000001009dbf24 libR.dylib`R_doDotCall(fun=<unavailable>, nargs=<unavailable>, cargs=<unavailable>, call=0x000000031a3f7158) at dotcode.c:754:11 [opt]
    frame #8: 0x00000001009dc8fc libR.dylib`do_dotcall(call=0x000000031a3f7158, op=<unavailable>, args=<unavailable>, env=<unavailable>) at dotcode.c:1437:11 [opt]
    frame #9: 0x0000000100a0af8c libR.dylib`Rf_eval(e=0x000000031a3f7158, rho=0x000000012e856b70) at eval.c:1265:9 [opt]
    frame #10: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000012429d828, newrho=0x000000012e856b70, sysparent=<unavailable>, rho=0x000000012422da20, arglist=<unavailable>, op=0x000000031a8bcef0) at eval.c:2398:22 [opt]
    frame #11: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000012429d828, op=0x000000031a8bcef0, arglist=0x000000012e856b00, rho=0x000000012422da20, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #12: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000012429d828, op=0x000000031a8bcef0, arglist=<unavailable>, rho=0x000000012422da20, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #13: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000012429d828, rho=0x000000012422da20) at eval.c:1285:12 [opt]
    frame #14: 0x0000000100a10fe8 libR.dylib`do_set(call=<unavailable>, op=0x0000000129015a70, args=0x000000012429d898, rho=0x000000012422da20) at eval.c:3582:8 [opt]
    frame #15: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000012429d8d0, rho=0x000000012422da20) at eval.c:1237:12 [opt]
    frame #16: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x000000012429d908, op=0x0000000129015920, args=0x000000012429da90, rho=0x000000012422da20) at eval.c:3010:10 [opt]
    frame #17: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000012429d908, rho=0x000000012422da20) at eval.c:1237:12 [opt]
    frame #18: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000012429dcf8, rho=0x000000012422da20) at eval.c:1237:12 [opt]
    frame #19: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000012429de10, rho=0x000000012422da20) at eval.c:1237:12 [opt]
    frame #20: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x00000001242b1da0, op=0x0000000129015920, args=0x000000012429e078, rho=0x000000012422da20) at eval.c:3010:10 [opt]
    frame #21: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x00000001242b1da0, rho=0x000000012422da20) at eval.c:1237:12 [opt]
    frame #22: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x0000000103e8d3a0, newrho=0x000000012422da20, sysparent=<unavailable>, rho=0x000000012430b6d8, arglist=<unavailable>, op=0x000000012d848978) at eval.c:2398:22 [opt]
    frame #23: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x0000000103e8d3a0, op=0x000000012d848978, arglist=0x000000012422d8d0, rho=0x000000012430b6d8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #24: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x0000000103e8d3a0, op=0x000000012d848978, arglist=<unavailable>, rho=0x000000012430b6d8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #25: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x0000000103e8d3a0, rho=0x000000012430b6d8) at eval.c:1285:12 [opt]
    frame #26: 0x0000000100aed148 libR.dylib`R_DispatchOrEvalSP(call=0x0000000103e8d448, op=0x0000000129015680, generic="$", args=0x00000001242b57b8, rho=0x000000012430b6d8, ans=0x000000016fded078) at subset.c:657:11 [opt]
    frame #27: 0x0000000100af122c libR.dylib`do_subset3(call=0x0000000103e8d448, op=0x0000000129015680, args=0x00000001242b57b8, env=0x000000012430b6d8) at subset.c:1265:8 [opt]
    frame #28: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x0000000103e8d448, rho=0x000000012430b6d8) at eval.c:1237:12 [opt]
    frame #29: 0x0000000100a0abec libR.dylib`Rf_eval(e=0x0000000103e8d608, rho=0x000000012430b6d8) at eval.c:1226:6 [opt]
    frame #30: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x000000012430d070) at eval.c:976:13 [opt]
    frame #31: 0x0000000100a0abd4 libR.dylib`Rf_eval(e=0x000000012905b2a8, rho=0x00000001242b7588) at eval.c:1192:6 [opt]
    frame #32: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x00000001242b5438) at eval.c:976:13 [opt]
    frame #33: 0x0000000100a0abd4 libR.dylib`Rf_eval(e=0x0000000129058d20, rho=0x00000001242b5518) at eval.c:1192:6 [opt]
    frame #34: 0x0000000100a0b80c libR.dylib`Rf_evalList(el=0x0000000125bcdbc0, rho=0x00000001242b5518, call=0x0000000125bcdd48, n=1) at eval.c:3680:12 [opt]
    frame #35: 0x0000000100a0ae60 libR.dylib`Rf_eval(e=0x0000000125bcdd48, rho=0x00000001242b5518) at eval.c:1256:6 [opt]
    frame #36: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x00000001242b5588) at eval.c:976:13 [opt]
    frame #37: 0x0000000100a1db50 libR.dylib`bcEval_loop [inlined] getvar(symbol=<unavailable>, rho=<unavailable>, dd=FALSE, keepmiss=FALSE, vcache=<unavailable>, sidx=<unavailable>) at eval.c:5857:3 [opt]
    frame #38: 0x0000000100a1da7c libR.dylib`bcEval_loop(ploc=0x000000016fdeead8) at eval.c:7871:20 [opt]
    frame #39: 0x0000000100a0b46c libR.dylib`bcEval(body=0x00000001281c9a10, rho=0x00000001242b5710) at eval.c:7524:16 [opt]
    frame #40: 0x0000000100a0ab6c libR.dylib`Rf_eval(e=0x00000001281c9a10, rho=0x00000001242b5710) at eval.c:1167:8 [opt]
    frame #41: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x0000000125bce678, newrho=0x00000001242b5710, sysparent=<unavailable>, rho=0x00000001242b5518, arglist=<unavailable>, op=0x00000001281c9b28) at eval.c:2398:22 [opt]
    frame #42: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x0000000125bce678, op=0x00000001281c9b28, arglist=0x00000001242b55c0, rho=0x00000001242b5518, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #43: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x0000000125bce678, op=0x00000001281c9b28, arglist=<unavailable>, rho=0x00000001242b5518, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #44: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x0000000125bce678, rho=0x00000001242b5518) at eval.c:1285:12 [opt]
    frame #45: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x0000000125bce6b0, op=0x0000000129015920, args=0x0000000125bcead8, rho=0x00000001242b5518) at eval.c:3010:10 [opt]
    frame #46: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x0000000125bce6b0, rho=0x00000001242b5518) at eval.c:1237:12 [opt]
    frame #47: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000012e33fa20, newrho=0x00000001242b5518, sysparent=<unavailable>, rho=0x00000001242b7588, arglist=<unavailable>, op=0x0000000125b1e950) at eval.c:2398:22 [opt]
    frame #48: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000012e33fa20, op=0x0000000125b1e950, arglist=0x00000001242b54a8, rho=0x00000001242b7588, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #49: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000012e33fa20, op=0x0000000125b1e950, arglist=<unavailable>, rho=0x00000001242b7588, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #50: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000012e33fa20, rho=0x00000001242b7588) at eval.c:1285:12 [opt]
    frame #51: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x00000001242b7b00) at eval.c:976:13 [opt]
    frame #52: 0x0000000100a1db50 libR.dylib`bcEval_loop [inlined] getvar(symbol=<unavailable>, rho=<unavailable>, dd=FALSE, keepmiss=FALSE, vcache=<unavailable>, sidx=<unavailable>) at eval.c:5857:3 [opt]
    frame #53: 0x0000000100a1da7c libR.dylib`bcEval_loop(ploc=0x000000016fdf08f8) at eval.c:7871:20 [opt]
    frame #54: 0x0000000100a0b46c libR.dylib`bcEval(body=0x0000000107043fc0, rho=0x00000001242b7d30) at eval.c:7524:16 [opt]
    frame #55: 0x0000000100a0ab6c libR.dylib`Rf_eval(e=0x0000000107043fc0, rho=0x00000001242b7d30) at eval.c:1167:8 [opt]
    frame #56: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000012e340b68, newrho=0x00000001242b7d30, sysparent=<unavailable>, rho=0x00000001242b7588, arglist=<unavailable>, op=0x0000000107044110) at eval.c:2398:22 [opt]
    frame #57: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000012e340b68, op=0x0000000107044110, arglist=0x00000001242b7b38, rho=0x00000001242b7588, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #58: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000012e340b68, op=0x0000000107044110, arglist=<unavailable>, rho=0x00000001242b7588, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #59: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000012e340b68, rho=0x00000001242b7588) at eval.c:1285:12 [opt]
    frame #60: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x000000012e340ba0, op=0x0000000129015920, args=0x000000012e340cf0, rho=0x00000001242b7588) at eval.c:3010:10 [opt]
    frame #61: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000012e340ba0, rho=0x00000001242b7588) at eval.c:1237:12 [opt]
    frame #62: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x0000000103e8d720, newrho=0x00000001242b7588, sysparent=<unavailable>, rho=0x000000012430b6d8, arglist=<unavailable>, op=0x000000012e338858) at eval.c:2398:22 [opt]
    frame #63: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x0000000103e8d720, op=0x000000012e338858, arglist=0x00000001242b7240, rho=0x000000012430b6d8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #64: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x0000000103e8d720, op=0x000000012e338858, arglist=<unavailable>, rho=0x000000012430b6d8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #65: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x0000000103e8d720, rho=0x000000012430b6d8) at eval.c:1285:12 [opt]
    frame #66: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x000000012430b7f0) at eval.c:976:13 [opt]
    frame #67: 0x0000000100a0abd4 libR.dylib`Rf_eval(e=0x00000001075d0650, rho=0x000000012430bb38) at eval.c:1192:6 [opt]
    frame #68: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x000000012430bbe0) at eval.c:976:13 [opt]
    frame #69: 0x0000000100a0abd4 libR.dylib`Rf_eval(e=0x0000000129058d20, rho=0x000000012430bcc0) at eval.c:1192:6 [opt]
    frame #70: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x000000012430be10) at eval.c:976:13 [opt]
    frame #71: 0x0000000100a0abd4 libR.dylib`Rf_eval(e=0x0000000129058d20, rho=0x000000012430c040) at eval.c:1192:6 [opt]
    frame #72: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x000000012430c120) at eval.c:976:13 [opt]
    frame #73: 0x0000000100a0abd4 libR.dylib`Rf_eval(e=0x0000000129058d20, rho=0x000000012430c200) at eval.c:1192:6 [opt]
    frame #74: 0x0000000100a0b80c libR.dylib`Rf_evalList(el=0x0000000125c0a100, rho=0x000000012430c200, call=0x0000000125c0a138, n=1) at eval.c:3680:12 [opt]
    frame #75: 0x0000000100a0ae60 libR.dylib`Rf_eval(e=0x0000000125c0a138, rho=0x000000012430c200) at eval.c:1256:6 [opt]
    frame #76: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x000000012430c3c0) at eval.c:976:13 [opt]
    frame #77: 0x0000000100a1db50 libR.dylib`bcEval_loop [inlined] getvar(symbol=<unavailable>, rho=<unavailable>, dd=FALSE, keepmiss=FALSE, vcache=<unavailable>, sidx=<unavailable>) at eval.c:5857:3 [opt]
    frame #78: 0x0000000100a1da7c libR.dylib`bcEval_loop(ploc=0x000000016fdf3418) at eval.c:7871:20 [opt]
    frame #79: 0x0000000100a0b46c libR.dylib`bcEval(body=0x00000001281e4820, rho=0x000000012430cc80) at eval.c:7524:16 [opt]
    frame #80: 0x0000000100a0ab6c libR.dylib`Rf_eval(e=0x00000001281e4820, rho=0x000000012430cc80) at eval.c:1167:8 [opt]
    frame #81: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x0000000125c0a640, newrho=0x000000012430cc80, sysparent=<unavailable>, rho=0x000000012430c200, arglist=<unavailable>, op=0x00000001281e4d60) at eval.c:2398:22 [opt]
    frame #82: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x0000000125c0a640, op=0x00000001281e4d60, arglist=0x000000012430c3f8, rho=0x000000012430c200, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #83: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x0000000125c0a640, op=0x00000001281e4d60, arglist=<unavailable>, rho=0x000000012430c200, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #84: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x0000000125c0a640, rho=0x000000012430c200) at eval.c:1285:12 [opt]
    frame #85: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x0000000125c0a678, op=0x0000000129015920, args=0x0000000125c0a800, rho=0x000000012430c200) at eval.c:3010:10 [opt]
    frame #86: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x0000000125c0a678, rho=0x000000012430c200) at eval.c:1237:12 [opt]
    frame #87: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x0000000125c0b670, newrho=0x000000012430c200, sysparent=<unavailable>, rho=0x000000012430c040, arglist=<unavailable>, op=0x0000000125b23b18) at eval.c:2398:22 [opt]
    frame #88: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x0000000125c0b670, op=0x0000000125b23b18, arglist=0x000000012430c158, rho=0x000000012430c040, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #89: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x0000000125c0b670, op=0x0000000125b23b18, arglist=<unavailable>, rho=0x000000012430c040, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #90: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x0000000125c0b670, rho=0x000000012430c040) at eval.c:1285:12 [opt]
    frame #91: 0x0000000100a0b80c libR.dylib`Rf_evalList(el=0x0000000125c0b6a8, rho=0x000000012430c040, call=0x0000000125bfdae0, n=1) at eval.c:3680:12 [opt]
    frame #92: 0x0000000100a0ae60 libR.dylib`Rf_eval(e=0x0000000125bfdae0, rho=0x000000012430c040) at eval.c:1256:6 [opt]
    frame #93: 0x0000000100a0e748 libR.dylib`do_if(call=0x0000000125bfe838, op=0x000000012900a8d8, args=0x0000000125bfe6b0, rho=0x000000012430c040) at eval.c:2718:5 [opt]
    frame #94: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x0000000125bfe838, rho=0x000000012430c040) at eval.c:1237:12 [opt]
    frame #95: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x0000000125bfe870, op=0x0000000129015920, args=0x0000000125bfed40, rho=0x000000012430c040) at eval.c:3010:10 [opt]
    frame #96: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x0000000125bfe870, rho=0x000000012430c040) at eval.c:1237:12 [opt]
    frame #97: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x0000000125bd8448, newrho=0x000000012430c040, sysparent=<unavailable>, rho=0x000000012430bcc0, arglist=<unavailable>, op=0x0000000125b24720) at eval.c:2398:22 [opt]
    frame #98: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x0000000125bd8448, op=0x0000000125b24720, arglist=0x000000012430be48, rho=0x000000012430bcc0, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #99: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x0000000125bd8448, op=0x0000000125b24720, arglist=<unavailable>, rho=0x000000012430bcc0, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #100: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x0000000125bd8448, rho=0x000000012430bcc0) at eval.c:1285:12 [opt]
    frame #101: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x0000000125bd8480, op=0x0000000129015920, args=0x0000000125bd8f00, rho=0x000000012430bcc0) at eval.c:3010:10 [opt]
    frame #102: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x0000000125bd8480, rho=0x000000012430bcc0) at eval.c:1237:12 [opt]
    frame #103: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000012e3447e8, newrho=0x000000012430bcc0, sysparent=<unavailable>, rho=0x000000012430bb38, arglist=<unavailable>, op=0x0000000125b256e0) at eval.c:2398:22 [opt]
    frame #104: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000012e3447e8, op=0x0000000125b256e0, arglist=0x000000012430bc50, rho=0x000000012430bb38, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #105: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000012e3447e8, op=0x0000000125b256e0, arglist=<unavailable>, rho=0x000000012430bb38, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #106: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000012e3447e8, rho=0x000000012430bb38) at eval.c:1285:12 [opt]
    frame #107: 0x0000000100a0e748 libR.dylib`do_if(call=0x000000012e341978, op=0x000000012900a8d8, args=0x000000012e341908, rho=0x000000012430bb38) at eval.c:2718:5 [opt]
    frame #108: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000012e341978, rho=0x000000012430bb38) at eval.c:1237:12 [opt]
    frame #109: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x000000012e3419b0, op=0x0000000129015920, args=0x000000012e341b70, rho=0x000000012430bb38) at eval.c:3010:10 [opt]
    frame #110: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000012e3419b0, rho=0x000000012430bb38) at eval.c:1237:12 [opt]
    frame #111: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x0000000103e8d8e0, newrho=0x000000012430bb38, sysparent=<unavailable>, rho=0x000000012430b6d8, arglist=<unavailable>, op=0x000000012e337da0) at eval.c:2398:22 [opt]
    frame #112: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x0000000103e8d8e0, op=0x000000012e337da0, arglist=0x000000012430b860, rho=0x000000012430b6d8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #113: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x0000000103e8d8e0, op=0x000000012e337da0, arglist=<unavailable>, rho=0x000000012430b6d8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #114: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x0000000103e8d8e0, rho=0x000000012430b6d8) at eval.c:1285:12 [opt]
    frame #115: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x0000000103e8d950, op=0x0000000129015920, args=0x0000000103e8daa0, rho=0x000000012430b6d8) at eval.c:3010:10 [opt]
    frame #116: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x0000000103e8d950, rho=0x000000012430b6d8) at eval.c:1237:12 [opt]
    frame #117: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000031a3bb158, newrho=0x000000012430b6d8, sysparent=<unavailable>, rho=0x000000012fa12e48, arglist=<unavailable>, op=0x000000012d846c18) at eval.c:2398:22 [opt]
    frame #118: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000031a3bb158, op=0x000000012d846c18, arglist=0x000000012430b400, rho=0x000000012fa12e48, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #119: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000031a3bb158, op=0x000000012d846c18, arglist=<unavailable>, rho=0x000000012fa12e48, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #120: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000031a3bb158, rho=0x000000012fa12e48) at eval.c:1285:12 [opt]
    frame #121: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x000000012458c3c0) at eval.c:976:13 [opt]
    frame #122: 0x0000000100a0abd4 libR.dylib`Rf_eval(e=0x000000012905b2a8, rho=0x000000012458c510) at eval.c:1192:6 [opt]
    frame #123: 0x0000000100a0b6a8 libR.dylib`forcePromise(e=0x00000001244ef6d8) at eval.c:976:13 [opt]
    frame #124: 0x0000000100a1db50 libR.dylib`bcEval_loop [inlined] getvar(symbol=<unavailable>, rho=<unavailable>, dd=FALSE, keepmiss=FALSE, vcache=<unavailable>, sidx=<unavailable>) at eval.c:5857:3 [opt]
    frame #125: 0x0000000100a1da7c libR.dylib`bcEval_loop(ploc=0x000000016fdf7dc8) at eval.c:7871:20 [opt]
    frame #126: 0x0000000100a0b46c libR.dylib`bcEval(body=0x0000000107043fc0, rho=0x00000001244ef908) at eval.c:7524:16 [opt]
    frame #127: 0x0000000100a0ab6c libR.dylib`Rf_eval(e=0x0000000107043fc0, rho=0x00000001244ef908) at eval.c:1167:8 [opt]
    frame #128: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000031b30c7b8, newrho=0x00000001244ef908, sysparent=<unavailable>, rho=0x000000012458c510, arglist=<unavailable>, op=0x0000000107044110) at eval.c:2398:22 [opt]
    frame #129: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000031b30c7b8, op=0x0000000107044110, arglist=0x00000001244ef710, rho=0x000000012458c510, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #130: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000031b30c7b8, op=0x0000000107044110, arglist=<unavailable>, rho=0x000000012458c510, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #131: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000031b30c7b8, rho=0x000000012458c510) at eval.c:1285:12 [opt]
    frame #132: 0x0000000100a10fe8 libR.dylib`do_set(call=<unavailable>, op=0x0000000129015a70, args=0x000000031b30c898, rho=0x000000012458c510) at eval.c:3582:8 [opt]
    frame #133: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000031b30c780, rho=0x000000012458c510) at eval.c:1237:12 [opt]
    frame #134: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x000000031b3094a0, op=0x0000000129015920, args=0x000000031b30cda0, rho=0x000000012458c510) at eval.c:3010:10 [opt]
    frame #135: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000031b3094a0, rho=0x000000012458c510) at eval.c:1237:12 [opt]
    frame #136: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000031a3bb698, newrho=0x000000012458c510, sysparent=<unavailable>, rho=0x000000012fa12e48, arglist=<unavailable>, op=0x000000031b36d430) at eval.c:2398:22 [opt]
    frame #137: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000031a3bb698, op=0x000000031b36d430, arglist=0x000000012458c3f8, rho=0x000000012fa12e48, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #138: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000031a3bb698, op=0x000000031b36d430, arglist=<unavailable>, rho=0x000000012fa12e48, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #139: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000031a3bb698, rho=0x000000012fa12e48) at eval.c:1285:12 [opt]
    frame #140: 0x0000000100a0ffcc libR.dylib`do_begin(call=0x000000031a428940, op=0x0000000129015920, args=0x000000031a16bee8, rho=0x000000012fa12e48) at eval.c:3010:10 [opt]
    frame #141: 0x0000000100a0ad34 libR.dylib`Rf_eval(e=0x000000031a428940, rho=0x000000012fa12e48) at eval.c:1237:12 [opt]
    frame #142: 0x0000000100a12048 libR.dylib`do_eval(call=<unavailable>, op=0x000000012902c3e8, args=0x000000012f907b68, rho=0x000000012f907660) at eval.c:3956:13 [opt]
    frame #143: 0x0000000100a22b4c libR.dylib`bcEval_loop(ploc=0x000000016fdfa548) at eval.c:8141:14 [opt]
    frame #144: 0x0000000100a0b46c libR.dylib`bcEval(body=0x000000012277d190, rho=0x0000000125f970e0) at eval.c:7524:16 [opt]
    frame #145: 0x0000000100a0ab6c libR.dylib`Rf_eval(e=0x000000012277d190, rho=0x0000000125f970e0) at eval.c:1167:8 [opt]
    frame #146: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000031a16c038, newrho=0x0000000125f970e0, sysparent=<unavailable>, rho=0x000000031a250470, arglist=<unavailable>, op=0x000000012277cbe0) at eval.c:2398:22 [opt]
    frame #147: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000031a16c038, op=0x000000012277cbe0, arglist=0x0000000125f96eb0, rho=0x000000031a250470, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #148: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000031a16c038, op=0x000000012277cbe0, arglist=<unavailable>, rho=0x000000031a250470, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #149: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000031a16c038, rho=0x000000031a250470) at eval.c:1285:12 [opt]
    frame #150: 0x0000000100a1229c libR.dylib`do_eval(call=<unavailable>, op=<unavailable>, args=<unavailable>, rho=<unavailable>) at eval.c:3974:9 [opt]
    frame #151: 0x0000000100a22b4c libR.dylib`bcEval_loop(ploc=0x000000016fdfbd38) at eval.c:8141:14 [opt]
    frame #152: 0x0000000100a0b46c libR.dylib`bcEval(body=0x0000000122b98da0, rho=0x00000001690bef38) at eval.c:7524:16 [opt]
    frame #153: 0x0000000100a0ab6c libR.dylib`Rf_eval(e=0x0000000122b98da0, rho=0x00000001690bef38) at eval.c:1167:8 [opt]
    frame #154: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000031b9ab550, newrho=0x00000001690bef38, sysparent=<unavailable>, rho=0x0000000125beb590, arglist=<unavailable>, op=0x0000000122b98630) at eval.c:2398:22 [opt]
    frame #155: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000031b9ab550, op=0x0000000122b98630, arglist=0x0000000125f8ce78, rho=0x0000000125beb590, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #156: 0x0000000100a0cd60 libR.dylib`R_forceAndCall [inlined] Rf_applyClosure(call=0x000000031b9ab550, op=0x0000000122b98630, arglist=0x0000000125f8ce78, rho=0x0000000125beb590, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #157: 0x0000000100a0cd48 libR.dylib`R_forceAndCall(e=0x000000031b9ab550, n=1, rho=0x0000000125beb590) at eval.c:2465:8 [opt]
    frame #158: 0x000000010096ecd8 libR.dylib`do_lapply(call=<unavailable>, op=<unavailable>, args=<unavailable>, rho=0x0000000125beb590) at apply.c:75:8 [opt]
    frame #159: 0x0000000100a7b190 libR.dylib`do_internal(call=<unavailable>, op=<unavailable>, args=<unavailable>, env=0x0000000125beb590) at names.c:1409:11 [opt]
    frame #160: 0x0000000100a22d7c libR.dylib`bcEval_loop(ploc=0x000000016fdfd398) at eval.c:8161:15 [opt]
    frame #161: 0x0000000100a0b46c libR.dylib`bcEval(body=0x00000001692391a0, rho=0x000000031bf45cf0) at eval.c:7524:16 [opt]
    frame #162: 0x0000000100a0ab6c libR.dylib`Rf_eval(e=0x00000001692391a0, rho=0x000000031bf45cf0) at eval.c:1167:8 [opt]
    frame #163: 0x0000000100a0d72c libR.dylib`R_execClosure(call=0x000000031bf45ac0, newrho=0x000000031bf45cf0, sysparent=<unavailable>, rho=0x0000000129044cb8, arglist=<unavailable>, op=0x0000000169238c60) at eval.c:2398:22 [opt]
    frame #164: 0x0000000100a0c824 libR.dylib`applyClosure_core(call=0x000000031bf45ac0, op=0x0000000169238c60, arglist=0x000000031bf45c48, rho=0x0000000129044cb8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2311:16 [opt]
    frame #165: 0x0000000100a0ae08 libR.dylib`Rf_eval [inlined] Rf_applyClosure(call=0x000000031bf45ac0, op=0x0000000169238c60, arglist=<unavailable>, rho=0x0000000129044cb8, suppliedvars=<unavailable>, unpromise=TRUE) at eval.c:2333:16 [opt]
    frame #166: 0x0000000100a0adf4 libR.dylib`Rf_eval(e=0x000000031bf45ac0, rho=0x0000000129044cb8) at eval.c:1285:12 [opt]
    frame #167: 0x0000000100a67034 libR.dylib`Rf_ReplIteration(rho=0x0000000129044cb8, savestack=<unavailable>, browselevel=<unavailable>, state=0x000000016fdfdc50) at main.c:262:2 [opt]
    frame #168: 0x0000000100a68668 libR.dylib`R_ReplConsole(rho=0x0000000129044cb8, savestack=0, browselevel=0) at main.c:314:11 [opt]
    frame #169: 0x0000000100a685a4 libR.dylib`run_Rmainloop at main.c:1216:5 [opt]
    frame #170: 0x0000000100a68710 libR.dylib`Rf_mainloop at main.c:1223:5 [opt]
    frame #171: 0x0000000100003ea0 R`main + 32
    frame #172: 0x00000001911a60e0 dyld`start + 2360

@CGMossa
Copy link
Author

CGMossa commented Jul 7, 2024

> pl$n_unique(pl$all())
polars Expr: dtype_columns([Duration(Nanoseconds)]).n_unique()

I don't know what's going on.

This time I ran with debug symbols LIBR_POLARS_PROFILE=dev R --debugger=lldb.

Details

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x39f8)
  * frame #0: 0x0000000339032234 polars.so`_rjem_mallocx [inlined] tcaches_get(tsd=0x00000001335c8008, ind=1855) at tcache_inlines.h:184:6 [opt]
    frame #1: 0x0000000339032228 polars.so`_rjem_mallocx [inlined] tcache_get_from_ind(tsd=0x00000001335c8008, tcache_ind=1855, slow=false, is_alloc=true) at jemalloc.c:2354:13 [opt]
    frame #2: 0x0000000339032228 polars.so`_rjem_mallocx [inlined] imalloc_no_sample(sopts=<unavailable>, dopts=<unavailable>, tsd=0x00000001335c8008, size=48, usize=<unavailable>, ind=0) at jemalloc.c:2384:21 [opt]
    frame #3: 0x0000000339032210 polars.so`_rjem_mallocx [inlined] imalloc_body(sopts=<unavailable>, dopts=<unavailable>, tsd=<unavailable>) at jemalloc.c:2573:16 [opt]
    frame #4: 0x00000003390320f0 polars.so`_rjem_mallocx [inlined] imalloc(sopts=<unavailable>, dopts=<unavailable>) at jemalloc.c:2687:10 [opt]
    frame #5: 0x0000000339032094 polars.so`_rjem_mallocx(size=48, flags=<unavailable>) at jemalloc.c:3424:2 [opt]
    frame #6: 0x0000000334ffd23c polars.so`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::next::h1e9bd54e58483819 [inlined] r_polars::series::RPolarsSeries::map_elements::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h44c7d5840ea349ad at mod.rs:0:1 [opt]
    frame #7: 0x0000000335007c00 polars.so`r_polars::utils::robj_to_datatype::hb5cd6c946bcfe564 at mod.rs:747:24 [opt]
    frame #8: 0x0000000334fc0520 polars.so`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::he750ae5038ea9157 [inlined] r_polars::lazy::dsl::create_cols_from_datatypes::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h4e6f6caeeabdc0bc at mod.rs:1014:9 [opt]
    frame #9: 0x0000000334fc0514 polars.so`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::he750ae5038ea9157 [inlined] core::iter::adapters::map::map_try_fold::_$u7b$$u7b$closure$u7d$$u7d$::hc10ced461cbb7d53 at map.rs:96:28 [opt]
    frame #10: 0x0000000334fc0514 polars.so`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::he750ae5038ea9157 [inlined] _$LT$core..iter..adapters..enumerate..Enumerate$LT$I$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::enumerate::_$u7b$$u7b$closure$u7d$$u7d$::h15567a0dad38c874 at enumerate.rs:87:27 [opt]
    frame #11: 0x0000000334fc0510 polars.so`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::he750ae5038ea9157 [inlined] core::iter::traits::iterator::Iterator::try_fold::h5f1aebb7f59470c6 at iterator.rs:2410:21 [opt]
    frame #12: 0x0000000334fc04bc polars.so`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::he750ae5038ea9157 [inlined] _$LT$core..iter..adapters..enumerate..Enumerate$LT$I$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::hebec8ec106aa4e3d at enumerate.rs:93:9 [opt]
    frame #13: 0x0000000334fc04bc polars.so`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::he750ae5038ea9157 at map.rs:122:9 [opt]
    frame #14: 0x0000000335152750 polars.so`_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$GT$::from_iter::h1b635f4d0a81c727 [inlined] _$LT$core..iter..adapters..GenericShunt$LT$I$C$R$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::h66a6e03e93a8074e at mod.rs:201:9 [opt]
    frame #15: 0x0000000335152738 polars.so`_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$GT$::from_iter::h1b635f4d0a81c727 [inlined] core::iter::traits::iterator::Iterator::try_for_each::hc8f58b941b4abcae at iterator.rs:2472:9 [opt]
    frame #16: 0x0000000335152738 polars.so`_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$GT$::from_iter::h1b635f4d0a81c727 [inlined] _$LT$core..iter..adapters..GenericShunt$LT$I$C$R$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::next::hd3357fc3e69c77e9 at mod.rs:184:14 [opt]
    frame #17: 0x0000000335152738 polars.so`_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$GT$::from_iter::h1b635f4d0a81c727 [inlined] _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter_nested..SpecFromIterNested$LT$T$C$I$GT$$GT$::from_iter::hc8cfdd6b63940b8d at spec_from_iter_nested.rs:26:32 [opt]
    frame #18: 0x0000000335152738 polars.so`_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$GT$::from_iter::h1b635f4d0a81c727 at spec_from_iter.rs:33:9 [opt]
    frame #19: 0x000000033526ec2c polars.so`core::iter::adapters::try_process::h72e7ea9b633b942c [inlined] _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$core..iter..traits..collect..FromIterator$LT$T$GT$$GT$::from_iter::ha9df7c7d991a9ca9 at mod.rs:2972:9 [opt]
    frame #20: 0x000000033526ec10 polars.so`core::iter::adapters::try_process::h72e7ea9b633b942c [inlined] core::iter::traits::iterator::Iterator::collect::haa51444bab3042f5 at iterator.rs:2004:9 [opt]
    frame #21: 0x000000033526ec10 polars.so`core::iter::adapters::try_process::h72e7ea9b633b942c [inlined] _$LT$core..result..Result$LT$V$C$E$GT$$u20$as$u20$core..iter..traits..collect..FromIterator$LT$core..result..Result$LT$A$C$E$GT$$GT$$GT$::from_iter::_$u7b$$u7b$closure$u7d$$u7d$::h05545ce559a6c93d at result.rs:1935:51 [opt]
    frame #22: 0x000000033526ec10 polars.so`core::iter::adapters::try_process::h72e7ea9b633b942c at mod.rs:170:17 [opt]
    frame #23: 0x00000003350ea010 polars.so`r_polars::lazy::dsl::create_cols_from_datatypes::hc93d74026439c644 [inlined] _$LT$core..result..Result$LT$V$C$E$GT$$u20$as$u20$core..iter..traits..collect..FromIterator$LT$core..result..Result$LT$A$C$E$GT$$GT$$GT$::from_iter::hebd365b4ce24e3a3 at result.rs:1935:9 [opt]
    frame #24: 0x00000003350ea004 polars.so`r_polars::lazy::dsl::create_cols_from_datatypes::hc93d74026439c644 [inlined] core::iter::traits::iterator::Iterator::collect::h076c3d1b3766efc4 at iterator.rs:2004:9 [opt]
    frame #25: 0x00000003350ea004 polars.so`r_polars::lazy::dsl::create_cols_from_datatypes::hc93d74026439c644 [inlined] r_polars::lazy::dsl::create_cols_from_datatypes::_$u7b$$u7b$closure$u7d$$u7d$::hbd89be0d16a9d120 at mod.rs:1146:57 [opt]
    frame #26: 0x00000003350e9ef8 polars.so`r_polars::lazy::dsl::create_cols_from_datatypes::hc93d74026439c644 [inlined] core::result::Result$LT$T$C$E$GT$::and_then::h59c2fd0d27852418 at result.rs:1321:22 [opt]
    frame #27: 0x00000003350e9e38 polars.so`r_polars::lazy::dsl::create_cols_from_datatypes::hc93d74026439c644 at mod.rs:1127:49 [opt]
    frame #28: 0x00000003350ea2f4 polars.so`wrap__create_cols_from_datatypes [inlined] r_polars::lazy::dsl::wrap__create_cols_from_datatypes::_$u7b$$u7b$closure$u7d$$u7d$::hf03f008b51c95fbc at dsl.rs:2822:1 [opt]
    frame #29: 0x00000003350ea2e8 polars.so`wrap__create_cols_from_datatypes [inlined] core::ops::function::FnOnce::call_once::h120eed80c6676e8d at function.rs:250:5 [opt]
    frame #30: 0x00000003350ea2e8 polars.so`wrap__create_cols_from_datatypes [inlined] _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::hcaee62ea40ed3459 at unwind_safe.rs:272:9 [opt]
    frame #31: 0x00000003350ea2e8 polars.so`wrap__create_cols_from_datatypes [inlined] std::panicking::try::do_call::h22fe16f68be7340e at panicking.rs:559:40 [opt]
    frame #32: 0x00000003350ea2e8 polars.so`wrap__create_cols_from_datatypes [inlined] std::panicking::try::hd609c7a036896497 at panicking.rs:523:19 [opt]
    frame #33: 0x00000003350ea2e8 polars.so`wrap__create_cols_from_datatypes [inlined] std::panic::catch_unwind::h602ca5908e241885 at panic.rs:149:14 [opt]
    frame #34: 0x00000003350ea2e8 polars.so`wrap__create_cols_from_datatypes at dsl.rs:2822:1 [opt]

@eitsupi
Copy link
Collaborator

eitsupi commented Jul 7, 2024

I have very little bandwidth to look at this, but it seems to me that the following part is not working correctly.

pub fn robj_to_datatype(robj: extendr_api::Robj) -> RResult<RPolarsDataType> {
let rv = rdbg(&robj);
let res: ExtendrResult<ExternalPtr<RPolarsDataType>> = robj.try_into();
let ext_dt = res.bad_val(rv).mistyped(tn::<RPolarsDataType>())?;
Ok(RPolarsDataType(ext_dt.0.clone()))
}

Perhaps the effect of the breaking changes made in extendr on something like TryFrom?

@eitsupi
Copy link
Collaborator

eitsupi commented Jul 8, 2024

Maybe the external pointer is not handled properly. It may be related to #1161

@eitsupi
Copy link
Collaborator

eitsupi commented Jul 8, 2024

From the content of the error, I think that what was previously treated as an external pointer was now treated as an environment and was broken.

Extendr treats what is defined as a struct in Rust as an external pointer and environment at the same time, right?

@CGMossa
Copy link
Author

CGMossa commented Jul 8, 2024

I must say, I don't think we made an error in extendr, and the behavior we are seeing here is most likely due to faulty assumptions on what extendr does.

  • Clone on Robj doesn't clone the data behind the scenes, but it clones the Robj, hence increasing the reference count in our ownership / protection module
  • Robj that are not externalptr cannot resolve R_ExternalPtrAddr/external_ptr_addr as they don't have that property. So I don't know what is going on with the logic there.
  • We no longer error if you try to ExternalPtr an ExternalPtr object that does not have the right "type". So if you have tests where you get back an ExternalPtr from an Robj, just to cheekily provoke an error, you'll basically be met with invalid state variable.
    Here, let me say, that this behavior was changed by the advice of yutannihilation, and I tend to agree with it. I did have a prototype that added fully correct type-checking, but no-one wanted to approve it to extendr.

I think there are plenty of things here, that could have been relayed to us, and that we could have improved, such that r-polars wouldn't resort to all of this complex code working around extendr. I'm saddened by the state of affairs here..

@etiennebacher
Copy link
Collaborator

etiennebacher commented Jul 8, 2024

Thanks for the details, I'll try to take a look at this during the week.

I think there are plenty of things here, that could have been relayed to us, and that we could have improved, such that r-polars wouldn't resort to all of this complex code working around extendr. I'm saddened by the state of affairs here..

Most of the foundations on the Rust side were built by @sorhawell more than 1.5 years ago. Most of what @eitsupi and I did on the Rust side was upgrading polars and expanding the API, without going deep in the more low-level Rust code. I can't speak for @eitsupi but I don't have the knowledge at all to build or maintain those foundations, and even less to detect wrong patterns that should be reported upstream.

@eitsupi
Copy link
Collaborator

eitsupi commented Jul 8, 2024

I am not trying to say that extendr is wrong, just pointing out the part that might be a clue to fixing the broken functions.
I have no idea how to fix that.

@CGMossa
Copy link
Author

CGMossa commented Jul 8, 2024

Does r-polars require the ability to deepclone an ExternalPtr?

@eitsupi
Copy link
Collaborator

eitsupi commented Jul 8, 2024

@CGMossa I am sorry, but I do not understand the intent of your question.
I don't think anyone here can answer whether such a feature was used or if so, why it was even necessary.

Basically, the structs defined in r-polars are wrappers for polars structs, so there is basically no case where it itself must be copied.

@eitsupi
Copy link
Collaborator

eitsupi commented Jul 10, 2024

@CGMossa @JosiahParry I think the problem here (#1154 (comment)) is that the recommended way to convert something like Robj to a Rust struct is unclear.
I couldn't find any examples of using struct in the user guide.
Any ideas?

@CGMossa
Copy link
Author

CGMossa commented Jul 10, 2024

I'm a bit busy at the moment. But I will reply to this. And I think you're on to something, because I changed this particular thing.. To resolve some issues.

@CGMossa
Copy link
Author

CGMossa commented Jul 10, 2024

Okay, I'll try giving an answer here. The issue is that the ownership semantics between R and Rust was not really adhered to before. Fixing that have solved a long term bug that we had, plus it has enabled us to do provide a functionality for chaining commands...

First, we have unified ExternalPtr<T> and #[extendr]-impl. If you need to know how things work in one, you can just investigate the other. See docs here: https://extendr.github.io/extendr/extendr_api/wrapper/externalptr/struct.ExternalPtr.html

Once you have an ExternalPtr<T>, I'd call this an owned pointer, more like a Box. It is not possible to clone this, where you also clone the underlying data. Atleast, I have not implemented that. You're basically copying the weak-reference of this owned pointer/Box. So an Robj that is an ExternalPtr<T> behind the scenes, now supports

  • TryFrom<&Robj> for &ExternalPtr<T>
  • TryFrom<&mut Robj> for &mut ExternalPtr<T>

For historic reasons, we do support TryFrom<&Robj> for ExternalPtr<T>, but you can't do much with this path way. You can't return a referenced data (like an iterator something like that), because you'd be returning something from local owned data. Which is not possible in Rust (or even C... I think)

We've also made try_addr /try_addr_mut methods for ExternalPtr<T> that yields you these, but then it checks of C NULL at run-time.

Finally, it might have been possible to go from &T to Robj, that is simply incorrect, and we removed that.

But we added a mechanism to be able to return &Self from an #[extendr]-impl, so for example, this works:

#[derive(Debug)]
struct Person {
    name: String,
    age: u32,
}

#[extendr]
impl Person {
    fn new() -> Self {
        Self { name: "".to_string(), age: 0 }
    }
    fn older(&mut self, other: Self) -> &Self {
        if self.age > other.age {
            self
        } else {
            other
        }
    }
}
extendr_module! {
    mod classes;
    impl Person;
}

See also the extensive tests of this https://github.com/extendr/extendr/blob/master/tests/extendrtests/src/rust/src/externalptr.rs

Again, r-polars and the success of r-polars is a high priority to me. Let me know if I can answer more or contribute more.

@eitsupi
Copy link
Collaborator

eitsupi commented Jul 10, 2024

@CGMossa Thanks. I am not familiar with extendr's internal implementation so I am not sure, but I am glad you have identified the problem.

Could you make modifications to merge this PR so that it passes all tests?

@CGMossa
Copy link
Author

CGMossa commented Jul 10, 2024

@CGMossa Thanks. I am not familiar with extendr's internal implementation so I am not sure, but I am glad you have identified the problem.

Could you make modifications to merge this PR so that it passes all tests?

I haven't identified the problem. I'm just answered your question.

@eitsupi
Copy link
Collaborator

eitsupi commented Jul 10, 2024

Ok, thanks.
If no one can solve the problem, we probably have no problem without updating extendr to 0.7.0 now.
(Currently the only problem with CI is the warnings, and there is no problem running on R-devel.)

@eitsupi
Copy link
Collaborator

eitsupi commented Aug 8, 2024

@CGMossa @etiennebacher Any update on this?

@etiennebacher
Copy link
Collaborator

etiennebacher commented Aug 8, 2024

Nope, I don't plan to dedicate time to this since it is low-priority IMO (as you said above this is only bothering us on the R-devel CI for now and you're rewriting using savvy anyway).

@CGMossa
Copy link
Author

CGMossa commented Aug 8, 2024

I will happily give a status: I have a few maintenance PRs that I had hoped would get merged, so that we could make a patch release of extendr-*+libR-sys. Unfortunately, not all of these PR have merged yet.

Regarding fixing all of r-polars issues with extendr: I think it is very reasonable to use extendr with r-polars. I constantly explore some of the pain points listed in this repo, and I've suggested radical changes to extendr to accommodate you guys. These have been rejected internally. I do have a potential very radical idea to bring in multiple impl-blocks to #[extendr], but that is for the future.

I suspect that it would be easier to identify how to use extendr for r-polars, if r-polars was intentionally written to work with extendr or savvy. I think a lot of complexity are unnecessarily sprinkled around. If those were removed, it would be straight forward to propose PRs to r-polars.

For now, we are waiting for me to get more time, to either improve extendr and this PR. I ask you to kindly be patient, as I have most definitely not forgotten about this PR. Or r-polars.

Cheers

@eitsupi
Copy link
Collaborator

eitsupi commented Aug 9, 2024

Thanks for the response, I'm glad to hear it.

I agree that the current r-polars is too complex, and as @etiennebacher pointed out I am in the process of completely rewriting r-polars from scratch, so if no one can maintain the current code base, I think we can stop update the current code without putting any effort into this PR.
(I have called your guys in #1105 because I didn't expect to have so much trouble updating to the new extendr. If I had known this would be a difficult task I would have silently abandoned the current code.)

I have been very busy lately and have not had time to be active on GitHub, but I will resume rewriting r-polars as soon as I have time.

@ju6ge
Copy link
Contributor

ju6ge commented Aug 16, 2024

Hey Guys,

I am having a look at this, because I am very interested in getting r-polars running with the newest extendr version.

Many of the failing test mostly are due too different errors, which is not a problem. But the segfaulting behavior is problematic.

I am investigating from here:

expect_grepl_error(pl$head(df$get_column("a"), -2))

I have take a look at the entrypoint to the rust code:

#[extendr]
pub fn create_cols_from_datatypes(list_of_dtypes: Robj) -> RResult<RPolarsExpr> {
     # added debugging print
     println!("{list_of_dtypes:#?}");
    
    let dtypes = robj_to!(Vec, PLPolarsDataType, list_of_dtypes)?;
    Ok(RPolarsExpr(dsl::dtype_cols(dtypes)))
}

The content of list_of_dtypes is list!(ExternalPtr.set_class(["RPolarsSeries"], -2.0). This then leads to the segfault in

pub fn robj_to_datatype(robj: extendr_api::Robj) -> RResult<RPolarsDataType> {
let rv = rdbg(&robj);
let res: ExtendrResult<ExternalPtr<RPolarsDataType>> = robj.try_into();
let ext_dt = res.bad_val(rv).mistyped(tn::<RPolarsDataType>())?;
Ok(RPolarsDataType(ext_dt.0.clone()))
}

So an robj with type ExternalPtr<RPolarsSeries> is cast to ExternalPtr<RPolarsDataType> via try_into(). I have also confirmed in robj_to_datatype() that the series does reach the cast there. This does seem very fishy. But I have not been able to trace all of it, becaues the marcos make the code hard to follow. And I think I am missing some context.

Any pointers or suggestions where to look for further clues would be greatly appreciated.

Kind regards,
ju6ge

@ju6ge
Copy link
Contributor

ju6ge commented Aug 17, 2024

@CGMossa

  • We no longer error if you try to ExternalPtr an ExternalPtr object that does not have the right "type". So if you have tests where you get back an ExternalPtr from an Robj, just to cheekily provoke an error, you'll basically be met with invalid state variable.
    Here, let me say, that this behavior was changed by the advice of yutannihilation, and I tend to agree with it. I did have a prototype that added fully correct type-checking, but no-one wanted to approve it to extendr.

This is exactly what this code previously assumed!

pub fn robj_to_datatype(robj: extendr_api::Robj) -> RResult<RPolarsDataType> {
let rv = rdbg(&robj);
let res: ExtendrResult<ExternalPtr<RPolarsDataType>> = robj.try_into();
let ext_dt = res.bad_val(rv).mistyped(tn::<RPolarsDataType>())?;
Ok(RPolarsDataType(ext_dt.0.clone()))
}

So line 747 no longer errors which then leads to invalid memory accesses in line 748. Checking before trying to convert to ExternalPtr and manually creating the error resolves the situation. I created a new PR #1187. That fixes the testsuite.

Though I am still unsure that the changes are sufficient. There might me be more parts of the code that use the previous behavior and expect to return the error to R. So there might be more cases where users can run into segfaults that are not tested for already!

To be honest I am not satisfied that the responsibility of checking if the conversion will work onto the libraries building upon extendr. The only way I can see to check if the Robj is an external ptr with a certain type is to use the Debug impl of Robj and check against the string. (At least if I have not overlooked something in the extendr docs). Rust is built to provide strong type guarantees, and it is nice to export that behavior, instead of repeating the unnexpected behavior that are common in the C-World. So in my opinion this is very much a thing that extendr should solve. At the very least I would like a better way to check if the converesion will work before attempting it. Checking against a string is very unergonomic!!!

@CGMossa
Copy link
Author

CGMossa commented Aug 17, 2024

Hello @ju6ge. I thank you for digging into this, and precisely identifying the problem. I did try to dig, but r-polars is very complicated for me, and I decided instead, to list the things I found important to communicate about instead.

I totally agree that extendr should be more like Rust, and less like C. As I said, the desired feature for runtime type checking, is something I have prototyped. See this extendr/extendr#609.
The nugget is having the first field be a typeid, that can be retrieved using the magical macro addr_of from https://doc.rust-lang.org/std/ptr/macro.addr_of.html, where you basically "ignore" the rest of the struct that was retrieved from R.

Us over at extendr are more than happy to collaborate, and coordinate on features for r-polars. In general, we have benefitted a lot from each other, and long-term wishes from r-polars folks have been successfully implemented by us. And some things are still being discussed and prototyped.

From where I'm looking, I think we could definitely benefit from someone willing to communicate with us, and being involved with r-polars.

I would also say, the typeid check is not without issues: First, it is a performance issue, since it will be needed to be done every time you invoke an extendr-impl method from R. Second, it is a runtime check. That's not really that beneficial anyways. Lastly, there are some caveats about typeid not being consistent across compilations.. So what happens when you save a Rust object and then want to invoke it again? I don't know. There are too many open questions.

But if these can be chased down, and someone can argue for them, of course we'll accommodate that. And there are plenty of experiments and POCs that can be pulled, if there is something of interest.

@ju6ge
Copy link
Contributor

ju6ge commented Aug 17, 2024

@CGMossa no problem. My interest in r-polars is more from a user perspective, in the sense that I am writing a rust library that exports bindings to different languages (r,python and julia). In this context polars is a very interesting provider for a common dataframe implementation. For now I am not deeply involved with r-polars. Though I do intend to dig into stuff and make sure stuff keeps working and is updated if I can find the time.

I totally agree that extendr should be more like Rust, and less like C. As I said, the desired feature for runtime type checking, is something I have prototyped. See this extendr/extendr#609.

I would be totally in favor of seeing something like that. The issues is that R is not suited to doing deep type checking and is a dynamic language. If r-polars wants to be a good dataframe library in R it need to be able to interface with the the normal R datatypes naturally. So this leads to a mix of native rust types and r types that might be passed to a function. It is simply not an option to just work with the classes exposed via extendr and thus never maybe triggering a memory issue. Instead invalid calls need to be caught.
Do you have a working implementation of your MR for the current release of extendr? I would be interested in testing it.

I would also say, the typeid check is not without issues: First, it is a performance issue, since it will be needed to be done every time you invoke an extendr-impl method from R. Second, it is a runtime check. That's not really that beneficial anyways. Lastly, there are some caveats about typeid not being consistent across compilations.. So what happens when you save a Rust object and then want to invoke it again? I don't know. There are too many open questions.

Well, I think performance at the expense of safety is a lousy argument. If you might crash your program because things are not properly checked than that is a bigger concern than performance. Also I still have to check anyway now, I just have to do in explicitly so nothing was won here anyway in terms of performance. Checking on rust side also is probably faster than from the r side. Yes it is runtime, there is just no way around that with R since R is an interpreted language. I don't think compiled R is an argument here, because R can not take advantage of rust compiler checks anyway.

I have not dug into extendr internals, but I am unsure that it is really required to check type_id every time. Wouldn't that depend on where we expect a given type or not. For example if I call

x = Person$new("ju6ge", 9001)
x$name()

This translates to the call

Person$name <- function() .Call(wrap__RPerson__name, self)

Which directly corresponds to

#[extendr]
impl Person {
    fn name(&mut self) -> String {}
}

Why would we run into a type check in this situation?

Would it be possible to only run into type_checks when calling Robj::try_into(). Or maybe even just have Robj::is_external_ptr<T>() -> bool?

I hate that R has the concept of saving your variable session, that is such an anti feature in my opinion. It just leads to people writing broken code, because the forget to declare their variables, because they are present magically in their environment. Also global variables are commonly used. Sorry for the rant. Actually that should be more the problem of r-polars that yours, implementing support for persisting sessions could be handled on the R side of things. r-polars could probably serialize the data on session close. Then deserialize when opening a session. That way recompilations and changes in type_id would not create any incompatibilities.

I hope my view on things is useful.

Kind regards,
ju6ge

@CGMossa
Copy link
Author

CGMossa commented Aug 18, 2024

This sounds very good. Truthfully, I think extendr needs more users around it.

Just to answer this good point of yours: The issue is not with constructing the #[extendr]-impl, but using it. Let us look at

#[extendr]
impl Person {
    // redacted other impls
    fn name(&self) -> &str {
        self.name.as_str()
    }
}

which is invoked in R by way of wrap__Person__name:

pub extern "C" fn wrap__Person__name(_self: extendr_api::SEXP) -> extendr_api::SEXP {
  let result = unsafe {
        std::panic::catch_unwind(std::panic::AssertUnwindSafe(
            move || -> std::result::Result<extendr_api::Robj, extendr_api::Error> {
                let mut _self_robj = extendr_api::robj::Robj::from_sexp(_self);
                Ok(extendr_api::Robj::from(
                    extendr_api::unwrap_or_throw_error(<&Person>::try_from(&_self_robj)).name(),
                ))
            },
        ))
    };
  // redacted treatment of this result object
}

(I've edited the version above for clarity, see below for full expansion)
Here you see <&Person>::try_from(&_self_robj). This is because R only allows us to run functions that take in SEXP, and at every invocation, we have to check if the SEXP admits an externalptr, then check if the externalptr within is the right type-id.

Again, I'm willing to put up another PR (I'm a bit booked at the moment, but definitely willing) that has this in it, for actual users, and actual debates and communications on it.

Details: Full expansion of `wrap__Person__new`

```rust #[no_mangle] #[allow(non_snake_case, clippy::not_unsafe_ptr_arg_deref)] pub extern "C" fn wrap__Person__name(_self: extendr_api::SEXP) -> extendr_api::SEXP { use extendr_api::robj::*; let wrap_result_state: std::result::Result< std::result::Result, Box, > = unsafe { std::panic::catch_unwind(std::panic::AssertUnwindSafe( move || -> std::result::Result { let mut _self_robj = extendr_api::robj::Robj::from_sexp(_self); Ok(extendr_api::Robj::from( extendr_api::unwrap_or_throw_error(<&Person>::try_from(&_self_robj)).name(), )) }, )) }; match wrap_result_state { Ok(Ok(zz)) => { return unsafe { zz.get() }; } Ok(Err(conversion_err)) => { let err_string = conversion_err.to_string(); drop(conversion_err); extendr_api::throw_r_error(&err_string); } Err(unwind_err) => { drop(unwind_err); let err_string = { let res = $crate::fmt::format($crate::__export::format_args!( "User function panicked: {}", "name" )); res }; extendr_api::handle_panic(err_string.as_str(), || { #[cold] #[track_caller] #[inline(never)] const fn panic_cold_explicit() -> ! { $crate::panicking::panic_explicit() } panic_cold_explicit(); }); } } { $crate::panicking::panic_fmt($crate::const_format_args!( "internal error: entered unreachable code: {}", $crate::format_args!("internal extendr error, this should never happen.") )); } } ```

Thus, on the comment

Would it be possible to only run into type_checks when calling Robj::try_into(). Or maybe even just have Robj::is_external_ptr() -> bool?
I would say no, to the #[extendr]-impl part. It can't be non-invasive there. However, for the
ExternalPtr<T> part, maybe I can make a TypedExternalPtr<T> (even though pointers are typed, but I guess not in this case)? Then if one manually drags around a Rust type in R, they can have type checking.

The things I listed are not opinions that I myself hold on type-checking #[extendr]-impl blocks, but what the broader extendr community holds. I'm really just interested in building the abstractions that people desire. Frankly, Rust offers all the beauty necessary anyway, so joyful programming, comes from there only. I would invite you to post issues and discussions over at extendr-repo, or even join our Discord. Your opinion as a user as a substantial contribution, and almost necessary I'd say.

@ju6ge
Copy link
Contributor

ju6ge commented Aug 18, 2024

The things I listed are not opinions that I myself hold on type-checking #[extendr]-impl blocks, but what the broader extendr community holds. I'm really just interested in building the abstractions that people desire. Frankly, Rust offers all the beauty necessary anyway, so joyful programming, comes from there only. I would invite you to post issues and discussions over at extendr-repo, or even join our Discord. Your opinion as a user as a substantial contribution, and almost necessary I'd say.

Thanks for your input, I will definitly consider communicating directly with extendr, though discord is probably not for me. I just don't like chat programs as an organizational tool for coding. Information is not very discoverable there. But opening issues on github and testing MR requests is very much a thing I can do. I can give my feedback and opinions there.

Just to answer this good point of yours: The issue is not with constructing the #[extendr]-impl, but using it. Let us look at

Thanks for your explanation, so I guess my assumption was wrong about R handling the passing the data to C directly. So R passes SEXP, and extendr needs to handle how to unwrap that to rust data. And it is a valid assumption that when calling x$name(), the type that is inferred from the function call should be expected in the self parameter as well. The case that is not covered though, is that libraries using extendr have functions calls that take Robj as parameter. In that case it is very possible that the library expects the data to be of a type it has defined, but it can not be guaranteed that a user of the library is passing the expected type into the functions. There needs to be a way to check the type and trigger an error if the type does not match.

If you find the time to open a new PR on extendr that would be awesome. Feel free to tag me and to link to this PR thread. If I have time next week I can try to use the version from the old PR and play around with it anyway.

I think the discussion here can be considered complete. Discussion of this particular MR can be moved to #1187. Should we close the MR?

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

Successfully merging this pull request may close these issues.

Update extendr
4 participants