From 22eeee70ec6f42b06bf7762a2852a4ed0cfc4908 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 10:36:05 +0100 Subject: [PATCH 1/7] Return false for lambdas in IsUserOperatorCall --- cpp2rust/converter/converter_lib.cpp | 2 +- tests/unit/lambda_as_template_argument.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 1aa18fea3..58763d974 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -1335,7 +1335,7 @@ bool HasStaticLocal(const clang::Stmt *stmt) { bool IsUserOperatorCall(const clang::CXXOperatorCallExpr *expr) { const auto *callee = expr->getDirectCallee(); - if (!callee) { + if (!callee || AsLambdaOperatorCall(callee)) { return false; } if (callee->isDefaulted() && IsComparisonOperator(callee)) { diff --git a/tests/unit/lambda_as_template_argument.cpp b/tests/unit/lambda_as_template_argument.cpp index 9242ee4c9..ad60d7c7b 100644 --- a/tests/unit/lambda_as_template_argument.cpp +++ b/tests/unit/lambda_as_template_argument.cpp @@ -7,6 +7,11 @@ template double apply_double(F fn, double x) { return fn(x); } template int apply_twice(F fn, int x) { return fn(fn(x)); } +template bool none_match(Pred pred, int a, int b) { + auto neg_pred = [&](int x) { return !pred(x); }; + return neg_pred(a) && neg_pred(b); +} + int main() { int factor = 3; auto scale = [factor](int x) { return x * factor; }; @@ -24,5 +29,9 @@ int main() { assert(apply_int(offset, 4) == 7); assert(apply_double(offset, 1.5) == 4.5); + auto is_even = [](int x) { return x % 2 == 0; }; + assert(none_match(is_even, 1, 3)); + assert(!none_match(is_even, 1, 4)); + return 0; } From d26d8cb4c4ea405bbb5232f48979d3634370641a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 12:25:49 +0100 Subject: [PATCH 2/7] Fix generic lambdas inside lambdas and with no specializations --- libcc2rs-macros/src/lambda.rs | 12 +++++++++++- tests/unit/lambda_generic.cpp | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/libcc2rs-macros/src/lambda.rs b/libcc2rs-macros/src/lambda.rs index 782797482..dd1bcc277 100644 --- a/libcc2rs-macros/src/lambda.rs +++ b/libcc2rs-macros/src/lambda.rs @@ -25,6 +25,13 @@ impl Parse for Lambda { input.parse::()?; } let captures = input.parse()?; + if is_generic && input.is_empty() { + return Ok(Lambda { + is_generic, + captures, + closures: Vec::new(), + }); + } input.parse::()?; let mut closures = vec![input.parse()?]; while input.parse::>()?.is_some() && !input.is_empty() { @@ -60,8 +67,11 @@ fn rewrite_nested_lambda( tokens: proc_macro2::TokenStream, names: &HashSet, ) -> Result { - let mut tokens = tokens.into_iter(); + let mut tokens = tokens.into_iter().peekable(); let mut out = Vec::new(); + if is_ident(tokens.peek(), "Generic") { + out.extend(tokens.by_ref().take(2)); + } if let Some(TokenTree::Group(captures)) = tokens.next() { let mut group = Group::new( captures.delimiter(), diff --git a/tests/unit/lambda_generic.cpp b/tests/unit/lambda_generic.cpp index 389826471..f6f38e1be 100644 --- a/tests/unit/lambda_generic.cpp +++ b/tests/unit/lambda_generic.cpp @@ -27,5 +27,14 @@ int main() { assert(mixed(2, 3) == 16); assert(mixed(2, 0.5) == 11.0); + auto unused = [](auto x) { return x; }; + (void)unused; + + auto outer = [base](int y) { + auto inner = [](auto z) { return z + 1; }; + return inner(y) + base; + }; + assert(outer(5) == 16); + return 0; } From 9ca92514c08c19a108a486c07c9d8a06b611b7d9 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 12:33:42 +0100 Subject: [PATCH 3/7] Fix global lambda decalration --- cpp2rust/converter/converter.cpp | 1 + cpp2rust/converter/converter.h | 13 +++---------- tests/unit/lambda_namespace_scope.cpp | 6 ++++++ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index b63c7fcb3..b47f1c21b 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -4030,6 +4030,7 @@ void Converter::ConvertLambdaClosure(const clang::CXXRecordDecl *decl, } EmitFunctionPreamble(call_operator); PushCurrFunction push_fn(*this, call_operator); + PushConstInitializer function_body(*this, false); ConvertFunctionBody(curr_function_); } diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 179207599..1c4065a97 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -854,18 +854,11 @@ class Converter : public clang::RecursiveASTVisitor { struct PushConstInitializer { Converter &c; bool prev; - bool enabled; PushConstInitializer(Converter &c, bool enabled) - : c(c), prev(c.in_const_initializer_), enabled(enabled) { - if (enabled) { - c.in_const_initializer_ = true; - } - } - ~PushConstInitializer() { - if (enabled) { - c.in_const_initializer_ = prev; - } + : c(c), prev(c.in_const_initializer_) { + c.in_const_initializer_ = enabled; } + ~PushConstInitializer() { c.in_const_initializer_ = prev; } }; std::vector curr_for_inc_; std::vector curr_init_type_; diff --git a/tests/unit/lambda_namespace_scope.cpp b/tests/unit/lambda_namespace_scope.cpp index a39813351..2d1793c04 100644 --- a/tests/unit/lambda_namespace_scope.cpp +++ b/tests/unit/lambda_namespace_scope.cpp @@ -10,6 +10,10 @@ auto bump = []() { template int apply(F f, int x) { return f(x); } +int by_ref(const int &v) { return v * 2; } + +auto twice_next = [](int x) { return by_ref(x + 1); }; + int main() { assert(inc(41) == 42); @@ -25,5 +29,7 @@ int main() { int (*fp)(int) = inc; assert(fp(-1) == 0); + assert(twice_next(4) == 10); + return 0; } From b878357f47d5a9fa07f689b311c06ec5c2473fc7 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 13:02:46 +0100 Subject: [PATCH 4/7] Convert lambda parameters using ConvertVarDeclSkipInit --- cpp2rust/converter/converter.cpp | 6 ++++-- tests/unit/lambda_basic.cpp | 13 +++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index b47f1c21b..e0058365d 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -4016,10 +4016,12 @@ void Converter::ConvertLambdaCapture(const clang::FieldDecl *field, void Converter::ConvertLambdaClosure(const clang::CXXRecordDecl *decl, clang::CXXMethodDecl *call_operator) { StrCat('|'); + in_function_formals_ = true; for (auto p : call_operator->parameters()) { - StrCat(GetNamedDeclAsString(p), token::kColon, ToString(p->getType()), - token::kComma); + ConvertVarDeclSkipInit(p); + StrCat(token::kComma); } + in_function_formals_ = false; StrCat('|'); ConvertFunctionReturnType(call_operator); PushBrace body(*this); diff --git a/tests/unit/lambda_basic.cpp b/tests/unit/lambda_basic.cpp index 5310cd194..8ff29d632 100644 --- a/tests/unit/lambda_basic.cpp +++ b/tests/unit/lambda_basic.cpp @@ -22,5 +22,18 @@ int main() { auto implicit = [=](int x) { return x + k; }; assert(implicit(1) == 4); + auto bump = [](int x) { + x += 1; + return x; + }; + assert(bump(1) == 2); + + auto through_ptr = [](int x) { + int *p = &x; + *p = *p * 2; + return x; + }; + assert(through_ptr(4) == 8); + return 0; } From 9b122344752d4a21612a9ba897517cd8165a9e2f Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 13:03:03 +0100 Subject: [PATCH 5/7] Push unboxed conversion for lambda call operator --- cpp2rust/converter/models/converter_refcount.cpp | 2 ++ tests/unit/lambda_basic.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 9a5f74873..b71214cfd 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1323,6 +1323,8 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) { if (auto *opcall = clang::dyn_cast(expr); opcall && !IsUserOperatorCall(opcall) && !Mapper::Contains(ctx_, expr->getCallee())) { + PushConversionKind push(*this, ConversionKind::Unboxed, + opcall->getOperator() == clang::OO_Call); return ConvertCXXOperatorCallExpr(opcall); } diff --git a/tests/unit/lambda_basic.cpp b/tests/unit/lambda_basic.cpp index 8ff29d632..54451ae5a 100644 --- a/tests/unit/lambda_basic.cpp +++ b/tests/unit/lambda_basic.cpp @@ -35,5 +35,11 @@ int main() { }; assert(through_ptr(4) == 8); + int seed = 5; + int boxed = through_ptr(seed); + int *boxed_ptr = &boxed; + assert(*boxed_ptr == 10); + assert(seed == 5); + return 0; } From 9c6c06c82bd8ff31e0fd4d44653fa6c30f2aea1a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 13:39:00 +0100 Subject: [PATCH 6/7] Use move_from for lambda always --- cpp2rust/converter/converter_lib.cpp | 3 +-- tests/unit/lambda_as_field.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 58763d974..2459aa7b0 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -1252,8 +1252,7 @@ const clang::LambdaCapture *AsLambdaCapture(const clang::FieldDecl *field) { bool IsLambdaCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor) { auto decl = ctor->getParent(); - return ctor->isCopyOrMoveConstructor() && decl->isLambda() && - !decl->captures().empty(); + return ctor->isCopyOrMoveConstructor() && decl->isLambda(); } bool LambdaNeedsDestruction(const clang::CXXRecordDecl *decl) { diff --git a/tests/unit/lambda_as_field.cpp b/tests/unit/lambda_as_field.cpp index f74839788..6d7d294c4 100644 --- a/tests/unit/lambda_as_field.cpp +++ b/tests/unit/lambda_as_field.cpp @@ -1,6 +1,7 @@ // ADDITIONAL_COMPILE_FLAGS: -std=c++23 // no-compile #include +#include template struct Guard { F f; @@ -16,6 +17,13 @@ template struct Holder { } }; +template struct Moving { + F f; + int moves = 0; + Moving(F f) : f(f) {} + Moving(Moving &&o) : f(std::move(o.f)), moves(o.moves + 1) {} +}; + template auto wrap(T fn) { return [fn](int x) { return fn(x) + 1; }; } @@ -54,5 +62,10 @@ int main() { auto ww = wrap(w); assert(ww(2) == 202); + Moving m{[](int x) { return x * 2; }}; + Moving m2(std::move(m)); + assert(m2.f(3) == 6); + assert(m2.moves == 1); + return 0; } From 31ee46851468848043afb5599980ddf977a42686 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Fri, 9 Oct 2026 18:13:31 +0100 Subject: [PATCH 7/7] Update tests --- tests/unit/out/refcount/fn_ptr_default_arg.rs | 2 +- .../refcount/lambda_as_template_argument.rs | 35 +++++++++++++++---- tests/unit/out/refcount/lambda_basic.rs | 35 ++++++++++++++++--- .../out/refcount/lambda_capture_implicit.rs | 6 ++-- tests/unit/out/refcount/lambda_capture_ref.rs | 8 ++--- .../unit/out/refcount/lambda_capture_this.rs | 4 +-- .../unit/out/refcount/lambda_capture_value.rs | 12 +++---- tests/unit/out/refcount/lambda_generic.rs | 35 +++++++++++++------ .../refcount/lambda_generic_explicit_args.rs | 4 +-- .../out/refcount/lambda_generic_to_fn_ptr.rs | 8 ++--- tests/unit/out/refcount/lambda_mutable.rs | 2 +- .../out/refcount/lambda_namespace_scope.rs | 27 +++++++++++--- tests/unit/out/refcount/lambda_nested.rs | 4 +-- .../out/refcount/lambda_self_recursive.rs | 10 +++--- tests/unit/out/refcount/stable_sort.rs | 2 +- tests/unit/out/unsafe/fn_ptr_default_arg.rs | 2 +- .../out/unsafe/lambda_as_template_argument.rs | 32 +++++++++++++---- tests/unit/out/unsafe/lambda_basic.rs | 31 +++++++++++++--- .../out/unsafe/lambda_capture_implicit.rs | 6 ++-- tests/unit/out/unsafe/lambda_capture_ref.rs | 8 ++--- tests/unit/out/unsafe/lambda_capture_this.rs | 4 +-- tests/unit/out/unsafe/lambda_capture_value.rs | 12 +++---- tests/unit/out/unsafe/lambda_generic.rs | 34 ++++++++++++------ .../unsafe/lambda_generic_explicit_args.rs | 4 +-- .../out/unsafe/lambda_generic_to_fn_ptr.rs | 16 ++++----- tests/unit/out/unsafe/lambda_mutable.rs | 2 +- .../unit/out/unsafe/lambda_namespace_scope.rs | 27 +++++++++++--- tests/unit/out/unsafe/lambda_nested.rs | 8 ++--- .../unit/out/unsafe/lambda_self_recursive.rs | 33 ++++++++--------- tests/unit/out/unsafe/stable_sort.rs | 4 +-- 30 files changed, 285 insertions(+), 132 deletions(-) diff --git a/tests/unit/out/refcount/fn_ptr_default_arg.rs b/tests/unit/out/refcount/fn_ptr_default_arg.rs index 331d8e471..4f5afdbd1 100644 --- a/tests/unit/out/refcount/fn_ptr_default_arg.rs +++ b/tests/unit/out/refcount/fn_ptr_default_arg.rs @@ -24,7 +24,7 @@ fn main_0() -> i32 { assert!((({ apply_1(5, None,) }) == 5)); assert!((({ apply_1(5, Some(FnPtr:: i32>::null()),) }) == 5)); assert!((({ apply_1(5, Some(FnPtr:: i32>::new(identity_0)),) }) == 5)); - let mut negate: FnPtr i32> = FnPtr:: i32>::new(|x: i32| -> i32 { + let mut negate: FnPtr i32> = FnPtr:: i32>::new(|mut x: i32| -> i32 { { return -x; } diff --git a/tests/unit/out/refcount/lambda_as_template_argument.rs b/tests/unit/out/refcount/lambda_as_template_argument.rs index 1733f28f8..00dc2e5d0 100644 --- a/tests/unit/out/refcount/lambda_as_template_argument.rs +++ b/tests/unit/out/refcount/lambda_as_template_argument.rs @@ -38,6 +38,18 @@ pub fn apply_twice_6(fn_: FnPtr i32>, mut x: i32) -> i32 { }) .clone(); } +pub fn none_match_7(pred: FnPtr bool>, mut a: i32, mut b: i32) -> bool { + let pred: Value bool>> = Rc::new(RefCell::new(pred)); + let neg_pred: Value bool>> = Rc::new(RefCell::new(lambda!( + { + let pred: Ptr bool>> = pred.as_pointer(); + }, + |mut x: i32| -> bool { + return !({ (*pred.upgrade().deref()).call(x) }); + } + ))); + return ({ (*neg_pred.borrow()).call(a) }) && ({ (*neg_pred.borrow()).call(b) }); +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -48,7 +60,7 @@ fn main_0() -> i32 { { let factor: Value = Rc::new(RefCell::new((*factor.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x * (*factor.borrow())); } ))); @@ -56,7 +68,7 @@ fn main_0() -> i32 { assert!( (({ apply_int_0( - FnPtr:: i32>::new(|x: i32| -> i32 { + FnPtr:: i32>::new(|mut x: i32| -> i32 { { return -x; } @@ -70,10 +82,10 @@ fn main_0() -> i32 { { let factor: Value = Rc::new(RefCell::new((*factor.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x * (*factor.borrow())); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return (x * ((*factor.borrow()) as f64)); } ))); @@ -82,7 +94,7 @@ fn main_0() -> i32 { assert!( (({ apply_int_2( - lambda!(Generic, {}, |x: i32| -> i32 { + lambda!(Generic, {}, |mut x: i32| -> i32 { return -x; }), 9, @@ -94,15 +106,24 @@ fn main_0() -> i32 { { let factor: Value = Rc::new(RefCell::new((*factor.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + (*factor.borrow())); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return (x + ((*factor.borrow()) as f64)); } ))); assert!((({ apply_int_3((*offset.borrow()).copy_from(), 4,) }) == 7)); assert!((({ apply_double_5((*offset.borrow()).copy_from(), 1.5_f64,) }) == 4.5_f64)); + let is_even: Value bool>> = Rc::new(RefCell::new( + FnPtr:: bool>::new(|mut x: i32| -> bool { + { + return ((x % 2) == 0); + } + }), + )); + assert!(({ none_match_7((*is_even.borrow()).copy_from(), 1, 3,) })); + assert!(!({ none_match_7((*is_even.borrow()).copy_from(), 1, 4,) })); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/refcount/lambda_basic.rs b/tests/unit/out/refcount/lambda_basic.rs index 527c43d09..261c58427 100644 --- a/tests/unit/out/refcount/lambda_basic.rs +++ b/tests/unit/out/refcount/lambda_basic.rs @@ -19,7 +19,7 @@ fn main_0() -> i32 { }))); assert!((({ (*zero.borrow()).call() }) == 42)); let one: Value i32>> = Rc::new(RefCell::new(FnPtr:: i32>::new( - |x: i32| -> i32 { + |mut x: i32| -> i32 { { return (x + 1); } @@ -28,7 +28,7 @@ fn main_0() -> i32 { assert!((({ (*one.borrow()).call(1,) }) == 2)); let three: Value i32>> = Rc::new(RefCell::new(FnPtr:: i32>::new( - |x: i32, y: i32, z: i32| -> i32 { + |mut x: i32, mut y: i32, mut z: i32| -> i32 { { return (((x * 100) + (y * 10)) + z); } @@ -38,7 +38,7 @@ fn main_0() -> i32 { let mut k: i32 = 3; let mut m: i32 = 4; let constants: Value i32>> = Rc::new(RefCell::new( - FnPtr:: i32>::new(|x: i32| -> i32 { + FnPtr:: i32>::new(|mut x: i32| -> i32 { { return ((x + 3) + 4); } @@ -47,7 +47,7 @@ fn main_0() -> i32 { assert!((({ (*constants.borrow()).call(1,) }) == 8)); let mut n: i32 = (k + m); let derived: Value i32>> = Rc::new(RefCell::new( - FnPtr:: i32>::new(|x: i32| -> i32 { + FnPtr:: i32>::new(|mut x: i32| -> i32 { { return (x + (3 + 4)); } @@ -55,13 +55,38 @@ fn main_0() -> i32 { )); assert!((({ (*derived.borrow()).call(1,) }) == 8)); let implicit: Value i32>> = Rc::new(RefCell::new( - FnPtr:: i32>::new(|x: i32| -> i32 { + FnPtr:: i32>::new(|mut x: i32| -> i32 { { return (x + 3); } }), )); assert!((({ (*implicit.borrow()).call(1,) }) == 4)); + let bump: Value i32>> = Rc::new(RefCell::new(FnPtr:: i32>::new( + |mut x: i32| -> i32 { + { + x += 1; + return x; + } + }, + ))); + assert!((({ (*bump.borrow()).call(1,) }) == 2)); + let through_ptr: Value i32>> = Rc::new(RefCell::new( + FnPtr:: i32>::new(|x: i32| -> i32 { + { + let x: Value = Rc::new(RefCell::new(x)); + let mut p: Ptr = (x.as_pointer()); + p.write({ ((p.read()) * 2) }); + return (*x.borrow()); + } + }), + )); + assert!((({ (*through_ptr.borrow()).call(4,) }) == 8)); + let mut seed: i32 = 5; + let boxed: Value = Rc::new(RefCell::new(({ (*through_ptr.borrow()).call(seed) }))); + let mut boxed_ptr: Ptr = (boxed.as_pointer()); + assert!(((boxed_ptr.read()) == 10)); + assert!((seed == 5)); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/refcount/lambda_capture_implicit.rs b/tests/unit/out/refcount/lambda_capture_implicit.rs index 4f287e427..17d3088ee 100644 --- a/tests/unit/out/refcount/lambda_capture_implicit.rs +++ b/tests/unit/out/refcount/lambda_capture_implicit.rs @@ -20,7 +20,7 @@ fn main_0() -> i32 { let b: Value = Rc::new(RefCell::new((*b.borrow()))); let c: Value = Rc::new(RefCell::new((*c.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((((*a.borrow()) + (*b.borrow())) + (*c.borrow())) + x); } ))); @@ -33,7 +33,7 @@ fn main_0() -> i32 { let b: Ptr = b.as_pointer(); let c: Ptr = c.as_pointer(); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((((a.read()) + (b.read())) + (c.read())) + x); } ))); @@ -46,7 +46,7 @@ fn main_0() -> i32 { let a: Value = Rc::new(RefCell::new((*a.borrow()))); let b: Value = Rc::new(RefCell::new((*b.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { { let __rhs = x; c.with_mut(|__v| *__v = *__v + __rhs) diff --git a/tests/unit/out/refcount/lambda_capture_ref.rs b/tests/unit/out/refcount/lambda_capture_ref.rs index 265efb0fa..fce86f3a0 100644 --- a/tests/unit/out/refcount/lambda_capture_ref.rs +++ b/tests/unit/out/refcount/lambda_capture_ref.rs @@ -24,7 +24,7 @@ fn main_0() -> i32 { { let base: Ptr = base.as_pointer(); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + (base.read())); } ))); @@ -60,7 +60,7 @@ fn main_0() -> i32 { { let arr: Ptr = arr.as_pointer(); }, - |i: usize, j: usize| { + |mut i: usize, mut j: usize| { let mut t: u16 = (elem!((arr), j).read()); elem!((arr), j).write({ (elem!((arr), i).read()) }); elem!((arr), i).write(t); @@ -74,7 +74,7 @@ fn main_0() -> i32 { { let t: Ptr = total.as_pointer(); }, - |x: i32| { + |mut x: i32| { { let __rhs = { x }; t.with_mut(|__v| *__v = *__v + __rhs) @@ -88,7 +88,7 @@ fn main_0() -> i32 { { let y: Ptr = field_ptr!(s.as_pointer(), y); }, - |v: i32| { + |mut v: i32| { y.write({ v }); } ))); diff --git a/tests/unit/out/refcount/lambda_capture_this.rs b/tests/unit/out/refcount/lambda_capture_this.rs index 1d310cb29..ac948e8da 100644 --- a/tests/unit/out/refcount/lambda_capture_this.rs +++ b/tests/unit/out/refcount/lambda_capture_this.rs @@ -49,7 +49,7 @@ impl SImpl for Ptr { { let this_: Value> = Rc::new(RefCell::new((*self).clone())); }, - |k: i32| { + |mut k: i32| { { let __rhs = k; field!((*this_.borrow()).clone(), n).with_mut(|__v| *__v = *__v + __rhs) @@ -64,7 +64,7 @@ impl SImpl for Ptr { { let this_: Value> = Rc::new(RefCell::new((*self).clone())); }, - |k: i32| { + |mut k: i32| { ({ SImpl::add(&(*this_.borrow()).clone(), k) }); } ))); diff --git a/tests/unit/out/refcount/lambda_capture_value.rs b/tests/unit/out/refcount/lambda_capture_value.rs index a2d060a01..33cfafda7 100644 --- a/tests/unit/out/refcount/lambda_capture_value.rs +++ b/tests/unit/out/refcount/lambda_capture_value.rs @@ -27,7 +27,7 @@ fn main_0() -> i32 { { let factor: Value = Rc::new(RefCell::new((*factor.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x * (*factor.borrow())); } ))); @@ -62,7 +62,7 @@ fn main_0() -> i32 { { let y: Value = Rc::new(RefCell::new((base + 1))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + (*y.borrow())); } ))); @@ -72,7 +72,7 @@ fn main_0() -> i32 { { let k: Value = Rc::new(RefCell::new((*k.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + 3); } ))); @@ -81,7 +81,7 @@ fn main_0() -> i32 { { let k: Value = Rc::new(RefCell::new((*k.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + ({ read_0(k.as_pointer()) })); } ))); @@ -90,7 +90,7 @@ fn main_0() -> i32 { { let k: Value = Rc::new(RefCell::new((*k.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + ({ read_0(k.as_pointer()) })); } ))); @@ -99,7 +99,7 @@ fn main_0() -> i32 { { let k: Ptr = k.as_pointer(); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + 3); } ))); diff --git a/tests/unit/out/refcount/lambda_generic.rs b/tests/unit/out/refcount/lambda_generic.rs index e94e309b3..952726830 100644 --- a/tests/unit/out/refcount/lambda_generic.rs +++ b/tests/unit/out/refcount/lambda_generic.rs @@ -14,10 +14,10 @@ fn main_0() -> i32 { let twice: Value> = Rc::new(RefCell::new(lambda!( Generic, {}, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + x); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return (x + x); } ))); @@ -29,10 +29,10 @@ fn main_0() -> i32 { { let base: Value = Rc::new(RefCell::new((*base.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x + (*base.borrow())); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return (x + ((*base.borrow()) as f64)); } ))); @@ -48,13 +48,13 @@ fn main_0() -> i32 { { let total: Ptr = total.as_pointer(); }, - |x: i32, y: i32| { + |mut x: i32, mut y: i32| { { let __rhs = (x * y); total.with_mut(|__v| *__v = *__v + __rhs) }; }, - |x: u32, y: u32| { + |mut x: u32, mut y: u32| { total.write({ (((total.read()) as u32).wrapping_add((x).wrapping_mul(y))) as i32 }); } ))); @@ -68,10 +68,10 @@ fn main_0() -> i32 { let sub: Value> = Rc::new(RefCell::new(lambda!( Generic, {}, - |x: i32, y: i32| -> i32 { + |mut x: i32, mut y: i32| -> i32 { return (x - y); }, - |x: f64, y: f64| -> f64 { + |mut x: f64, mut y: f64| -> f64 { return (x - y); } ))); @@ -88,10 +88,10 @@ fn main_0() -> i32 { { let base: Value = Rc::new(RefCell::new((*base.borrow()))); }, - |x: i32, y: i32| -> i32 { + |mut x: i32, mut y: i32| -> i32 { return ((x * y) + (*base.borrow())); }, - |x: i32, y: f64| -> f64 { + |mut x: i32, mut y: f64| -> f64 { return (((x as f64) * y) + ((*base.borrow()) as f64)); } ))); @@ -103,6 +103,21 @@ fn main_0() -> i32 { .call(2, 0.5_f64) }) == 11_f64) ); + let unused: Value> = Rc::new(RefCell::new(lambda!(Generic, {}))); + &(*unused.borrow_mut()); + let outer: Value i32>> = Rc::new(RefCell::new(lambda!( + { + let base: Value = Rc::new(RefCell::new((*base.borrow()))); + }, + |mut y: i32| -> i32 { + let inner: Value> = + Rc::new(RefCell::new(lambda!(Generic, {}, |mut z: i32| -> i32 { + return (z + 1); + }))); + return (({ (*inner.borrow()).spec:: i32>(0).call(y) }) + (*base.borrow())); + } + ))); + assert!((({ (*outer.borrow()).call(5,) }) == 16)); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/refcount/lambda_generic_explicit_args.rs b/tests/unit/out/refcount/lambda_generic_explicit_args.rs index 4dfae14d3..ef5613d0b 100644 --- a/tests/unit/out/refcount/lambda_generic_explicit_args.rs +++ b/tests/unit/out/refcount/lambda_generic_explicit_args.rs @@ -94,10 +94,10 @@ fn main_0() -> i32 { let cast_to: Value> = Rc::new(RefCell::new(lambda!( Generic, {}, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x as i32) / 2); }, - |x: i32| -> f64 { + |mut x: i32| -> f64 { return ((x as f64) / 2_f64); } ))); diff --git a/tests/unit/out/refcount/lambda_generic_to_fn_ptr.rs b/tests/unit/out/refcount/lambda_generic_to_fn_ptr.rs index 3616dd703..281bce922 100644 --- a/tests/unit/out/refcount/lambda_generic_to_fn_ptr.rs +++ b/tests/unit/out/refcount/lambda_generic_to_fn_ptr.rs @@ -14,10 +14,10 @@ fn main_0() -> i32 { let negate: Value> = Rc::new(RefCell::new(lambda!( Generic, {}, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return -x; }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return -x; } ))); @@ -28,10 +28,10 @@ fn main_0() -> i32 { let square: Value> = Rc::new(RefCell::new(lambda!( Generic, {}, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return (x * x); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return (x * x); } ))); diff --git a/tests/unit/out/refcount/lambda_mutable.rs b/tests/unit/out/refcount/lambda_mutable.rs index 8222bd58d..1353a74f2 100644 --- a/tests/unit/out/refcount/lambda_mutable.rs +++ b/tests/unit/out/refcount/lambda_mutable.rs @@ -29,7 +29,7 @@ fn main_0() -> i32 { { let total: Value = Rc::new(RefCell::new((*total.borrow()))); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { (*total.borrow_mut()) += x; return (*total.borrow()); } diff --git a/tests/unit/out/refcount/lambda_namespace_scope.rs b/tests/unit/out/refcount/lambda_namespace_scope.rs index a713d8b17..9f25448a9 100644 --- a/tests/unit/out/refcount/lambda_namespace_scope.rs +++ b/tests/unit/out/refcount/lambda_namespace_scope.rs @@ -11,7 +11,7 @@ thread_local!( ); thread_local!( pub static inc_1: Value i32>> = Rc::new(RefCell::new( - FnPtr:: i32>::new(|x: i32| -> i32 { + FnPtr:: i32>::new(|mut x: i32| -> i32 { { return (x + 1); } @@ -31,6 +31,22 @@ pub fn apply_3(f: FnPtr i32>, mut x: i32) -> i32 { let f: Value i32>> = Rc::new(RefCell::new(f)); return ({ (*f.borrow()).call(x) }); } +pub fn by_ref_4(v: Ptr) -> i32 { + return ((v.read()) * 2); +} +thread_local!( + pub static twice_next_5: Value i32>> = + Rc::new(RefCell::new(FnPtr:: i32>::new( + |mut x: i32| -> i32 { + { + return ({ + let _v: Value = Rc::new(RefCell::new((x + 1))); + by_ref_4(_v.as_pointer()) + }); + } + }, + ))); +); pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -40,16 +56,19 @@ fn main_0() -> i32 { ({ (*bump_2.with(Value::clone).borrow()).call() }); assert!((({ (*bump_2.with(Value::clone).borrow()).call() }) == 2)); assert!((counter_0.with(|rc| *rc.borrow()) == 2)); - assert!((({ apply_3((*inc_1.with(Value::clone).borrow()).clone(), 1,) }) == 2)); - let copy: Value i32>> = - Rc::new(RefCell::new((*inc_1.with(Value::clone).borrow()).clone())); + assert!((({ apply_3((*inc_1.with(Value::clone).borrow()).copy_from(), 1,) }) == 2)); + let copy: Value i32>> = Rc::new(RefCell::new( + (*inc_1.with(Value::clone).borrow()).copy_from(), + )); assert!((({ (*copy.borrow()).call(9,) }) == 10)); let mut fp: FnPtr i32> = (*inc_1.with(Value::clone).borrow()).clone(); assert!((({ fp.call(-1_i32,) }) == 0)); + assert!((({ (*twice_next_5.with(Value::clone).borrow()).call(4,) }) == 10)); return 0; } pub fn __cpp2rust_init_globals() { let _ = counter_0.with(|_| ()); let _ = inc_1.with(|_| ()); let _ = bump_2.with(|_| ()); + let _ = twice_next_5.with(|_| ()); } diff --git a/tests/unit/out/refcount/lambda_nested.rs b/tests/unit/out/refcount/lambda_nested.rs index 819a1efa7..2ed38f2dd 100644 --- a/tests/unit/out/refcount/lambda_nested.rs +++ b/tests/unit/out/refcount/lambda_nested.rs @@ -29,7 +29,7 @@ fn main_0() -> i32 { let x: Ptr = (x).clone(); let y: Value = Rc::new(RefCell::new((*y.borrow()))); }, - |z: i32| -> i32 { + |mut z: i32| -> i32 { return (((x.read()) + (*y.borrow())) + z); } ))); @@ -59,7 +59,7 @@ impl SImpl for Ptr { let this_: Value> = Rc::new(RefCell::new((*this_.borrow()).clone())); let y: Value = Rc::new(RefCell::new((*y.borrow()))); }, - |z: i32| -> i32 { + |mut z: i32| -> i32 { return (((*this_.borrow()).clone().with(|__s| __s.v) + (*y.borrow())) + z); } ))); diff --git a/tests/unit/out/refcount/lambda_self_recursive.rs b/tests/unit/out/refcount/lambda_self_recursive.rs index 4753be5a1..324bd6db0 100644 --- a/tests/unit/out/refcount/lambda_self_recursive.rs +++ b/tests/unit/out/refcount/lambda_self_recursive.rs @@ -15,7 +15,7 @@ fn main_0() -> i32 { Rc::new(RefCell::new(lambda!(Generic, {}, |self_: FnPtr< Generic, >, - n: i32| + mut n: i32| -> i32 { let self_: Value> = Rc::new(RefCell::new(self_)); if (n <= 1) { @@ -23,7 +23,7 @@ fn main_0() -> i32 { } return (n * ({ - let _self_: FnPtr = (*self_.borrow()).clone(); + let _self_: FnPtr = (*self_.borrow()).copy_from(); (*self_.borrow()) .spec::, i32) -> i32>(0) .call(_self_, (n - 1)) @@ -31,7 +31,7 @@ fn main_0() -> i32 { }))); assert!( (({ - let _self_: FnPtr = (*fact.borrow()).clone(); + let _self_: FnPtr = (*fact.borrow()).copy_from(); (*fact.borrow()) .spec::, i32) -> i32>(0) .call(_self_, 5) @@ -43,7 +43,7 @@ fn main_0() -> i32 { { let calls: Ptr = calls.as_pointer(); }, - |self_: Ptr>, n: i32| -> i32 { + |self_: Ptr>, mut n: i32| -> i32 { calls.with_mut(|__v| __v.postfix_inc()); if (n <= 2) { return 1; @@ -78,7 +78,7 @@ fn main_0() -> i32 { { let depth: Ptr = depth.as_pointer(); }, - |self_: Ptr>, n: i32| { + |self_: Ptr>, mut n: i32| { if (n == 0) { return; } diff --git a/tests/unit/out/refcount/stable_sort.rs b/tests/unit/out/refcount/stable_sort.rs index 0092d266b..4af2f4243 100644 --- a/tests/unit/out/refcount/stable_sort.rs +++ b/tests/unit/out/refcount/stable_sort.rs @@ -14,7 +14,7 @@ fn main_0() -> i32 { let arr1: Value> = Rc::new(RefCell::new(Box::new([5, 2, 8, 1, 3]))); { let fun = |x: Ptr, y: Ptr| { - FnPtr:: bool>::new(|x: i32, y: i32| -> bool { + FnPtr:: bool>::new(|mut x: i32, mut y: i32| -> bool { { return (x < y); } diff --git a/tests/unit/out/unsafe/fn_ptr_default_arg.rs b/tests/unit/out/unsafe/fn_ptr_default_arg.rs index c85d203f4..f10f9084e 100644 --- a/tests/unit/out/unsafe/fn_ptr_default_arg.rs +++ b/tests/unit/out/unsafe/fn_ptr_default_arg.rs @@ -26,7 +26,7 @@ unsafe fn main_0() -> i32 { assert!(((unsafe { apply_1(5, None,) }) == (5))); assert!(((unsafe { apply_1(5, Some(None),) }) == (5))); assert!(((unsafe { apply_1(5, Some(Some(identity_0)),) }) == (5))); - let mut negate: Option i32> = Some(|x: i32| -> i32 { + let mut negate: Option i32> = Some(|mut x: i32| -> i32 { unsafe { return -x; } diff --git a/tests/unit/out/unsafe/lambda_as_template_argument.rs b/tests/unit/out/unsafe/lambda_as_template_argument.rs index 8e9afd495..77cd23970 100644 --- a/tests/unit/out/unsafe/lambda_as_template_argument.rs +++ b/tests/unit/out/unsafe/lambda_as_template_argument.rs @@ -30,6 +30,17 @@ pub unsafe fn apply_twice_6(mut fn_: FnPtr i32>, mut x: i32) -> i32 { fn_.call(_x) }); } +pub unsafe fn none_match_7(mut pred: FnPtr bool>, mut a: i32, mut b: i32) -> bool { + let mut neg_pred: FnPtr bool> = lambda_unsafe!( + { + let pred: *mut FnPtr bool> = &mut pred; + }, + |mut x: i32| -> bool { + return !(unsafe { (*pred).call(x) }); + } + ); + return (unsafe { neg_pred.call(a) }) && (unsafe { neg_pred.call(b) }); +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -42,7 +53,7 @@ unsafe fn main_0() -> i32 { { let factor: i32 = factor; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) * (factor)); } ); @@ -50,7 +61,7 @@ unsafe fn main_0() -> i32 { assert!( ((unsafe { apply_int_0( - FnPtr:: i32>::new(|x: i32| -> i32 { + FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return -x; } @@ -64,10 +75,10 @@ unsafe fn main_0() -> i32 { { let factor: i32 = factor; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) * (factor)); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return ((x) * (factor as f64)); } ); @@ -76,7 +87,7 @@ unsafe fn main_0() -> i32 { assert!( ((unsafe { apply_int_2( - lambda_unsafe!(Generic, {}, |x: i32| -> i32 { + lambda_unsafe!(Generic, {}, |mut x: i32| -> i32 { return -x; }), 9, @@ -88,15 +99,22 @@ unsafe fn main_0() -> i32 { { let factor: i32 = factor; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (factor)); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return ((x) + (factor as f64)); } ); assert!(((unsafe { apply_int_3(offset.copy_from(), 4,) }) == (7))); assert!(((unsafe { apply_double_5(offset.copy_from(), 1.5_f64,) }) == (4.5_f64))); + let mut is_even: FnPtr bool> = FnPtr:: bool>::new(|mut x: i32| -> bool { + unsafe { + return (((x) % (2)) == (0)); + } + }); + assert!((unsafe { none_match_7(is_even.copy_from(), 1, 3,) })); + assert!(!(unsafe { none_match_7(is_even.copy_from(), 1, 4,) })); return 0; } pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/lambda_basic.rs b/tests/unit/out/unsafe/lambda_basic.rs index b2d3f2b07..f432052e3 100644 --- a/tests/unit/out/unsafe/lambda_basic.rs +++ b/tests/unit/out/unsafe/lambda_basic.rs @@ -19,14 +19,14 @@ unsafe fn main_0() -> i32 { } }); assert!(((unsafe { zero.call() }) == (42))); - let mut one: FnPtr i32> = FnPtr:: i32>::new(|x: i32| -> i32 { + let mut one: FnPtr i32> = FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return ((x) + (1)); } }); assert!(((unsafe { one.call(1,) }) == (2))); let mut three: FnPtr i32> = - FnPtr:: i32>::new(|x: i32, y: i32, z: i32| -> i32 { + FnPtr:: i32>::new(|mut x: i32, mut y: i32, mut z: i32| -> i32 { unsafe { return ((((x) * (100)) + ((y) * (10))) + (z)); } @@ -34,25 +34,46 @@ unsafe fn main_0() -> i32 { assert!(((unsafe { three.call(1, 2, 3,) }) == (123))); let k: i32 = 3; let m: i32 = 4; - let mut constants: FnPtr i32> = FnPtr:: i32>::new(|x: i32| -> i32 { + let mut constants: FnPtr i32> = FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return (((x) + (3)) + (4)); } }); assert!(((unsafe { constants.call(1,) }) == (8))); let n: i32 = ((k) + (m)); - let mut derived: FnPtr i32> = FnPtr:: i32>::new(|x: i32| -> i32 { + let mut derived: FnPtr i32> = FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return ((x) + ((3) + (4))); } }); assert!(((unsafe { derived.call(1,) }) == (8))); - let mut implicit: FnPtr i32> = FnPtr:: i32>::new(|x: i32| -> i32 { + let mut implicit: FnPtr i32> = FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return ((x) + (3)); } }); assert!(((unsafe { implicit.call(1,) }) == (4))); + let mut bump: FnPtr i32> = FnPtr:: i32>::new(|mut x: i32| -> i32 { + unsafe { + x += 1; + return x; + } + }); + assert!(((unsafe { bump.call(1,) }) == (2))); + let mut through_ptr: FnPtr i32> = + FnPtr:: i32>::new(|mut x: i32| -> i32 { + unsafe { + let mut p: *mut i32 = (&mut x as *mut i32); + (*p) = ((*p) * (2)); + return x; + } + }); + assert!(((unsafe { through_ptr.call(4,) }) == (8))); + let mut seed: i32 = 5; + let mut boxed: i32 = (unsafe { through_ptr.call(seed) }); + let mut boxed_ptr: *mut i32 = (&mut boxed as *mut i32); + assert!(((*boxed_ptr) == (10))); + assert!(((seed) == (5))); return 0; } pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/lambda_capture_implicit.rs b/tests/unit/out/unsafe/lambda_capture_implicit.rs index b6c4ed0d8..b5dc9cf47 100644 --- a/tests/unit/out/unsafe/lambda_capture_implicit.rs +++ b/tests/unit/out/unsafe/lambda_capture_implicit.rs @@ -22,7 +22,7 @@ unsafe fn main_0() -> i32 { let b: i32 = b; let c: i32 = c; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((((a) + (b)) + (c)) + (x)); } ); @@ -35,7 +35,7 @@ unsafe fn main_0() -> i32 { let b: *mut i32 = &mut b; let c: *mut i32 = &mut c; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((((*a) + (*b)) + (*c)) + (x)); } ); @@ -48,7 +48,7 @@ unsafe fn main_0() -> i32 { let a: i32 = a; let b: i32 = b; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { (*c) += x; return (((a) + (b)) + (*c)); } diff --git a/tests/unit/out/unsafe/lambda_capture_ref.rs b/tests/unit/out/unsafe/lambda_capture_ref.rs index 89e896634..e28dfdd80 100644 --- a/tests/unit/out/unsafe/lambda_capture_ref.rs +++ b/tests/unit/out/unsafe/lambda_capture_ref.rs @@ -24,7 +24,7 @@ unsafe fn main_0() -> i32 { { let base: *mut i32 = &mut base; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (*base)); } ); @@ -60,7 +60,7 @@ unsafe fn main_0() -> i32 { { let arr: *mut [u16; 4] = &mut arr; }, - |i: usize, j: usize| { + |mut i: usize, mut j: usize| { let mut t: u16 = (*arr)[(j)]; (*arr)[(j)] = (*arr)[(i)]; (*arr)[(i)] = t; @@ -74,7 +74,7 @@ unsafe fn main_0() -> i32 { { let t: *mut i32 = &mut total; }, - |x: i32| { + |mut x: i32| { (*t) += x; } ); @@ -85,7 +85,7 @@ unsafe fn main_0() -> i32 { { let y: *mut i32 = &mut s.y; }, - |v: i32| { + |mut v: i32| { (*y) = v; } ); diff --git a/tests/unit/out/unsafe/lambda_capture_this.rs b/tests/unit/out/unsafe/lambda_capture_this.rs index d54d64ec0..cfa908778 100644 --- a/tests/unit/out/unsafe/lambda_capture_this.rs +++ b/tests/unit/out/unsafe/lambda_capture_this.rs @@ -24,7 +24,7 @@ impl S { { let this_: *mut S = (self as *mut S); }, - |k: i32| { + |mut k: i32| { (*this_).n += k; } ); @@ -36,7 +36,7 @@ impl S { { let this_: *mut S = (self as *mut S); }, - |k: i32| { + |mut k: i32| { (unsafe { S::add(&mut (*this_), k) }); } ); diff --git a/tests/unit/out/unsafe/lambda_capture_value.rs b/tests/unit/out/unsafe/lambda_capture_value.rs index 2cd64b629..9de3150fa 100644 --- a/tests/unit/out/unsafe/lambda_capture_value.rs +++ b/tests/unit/out/unsafe/lambda_capture_value.rs @@ -27,7 +27,7 @@ unsafe fn main_0() -> i32 { { let factor: i32 = factor; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) * (factor)); } ); @@ -62,7 +62,7 @@ unsafe fn main_0() -> i32 { { let y: i32 = ((base) + (1)); }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (y)); } ); @@ -72,7 +72,7 @@ unsafe fn main_0() -> i32 { { let k: i32 = k; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (3)); } ); @@ -81,7 +81,7 @@ unsafe fn main_0() -> i32 { { let k: i32 = k; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (unsafe { read_0(&k) })); } ); @@ -90,7 +90,7 @@ unsafe fn main_0() -> i32 { { let k: i32 = k; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (unsafe { read_0(&k) })); } ); @@ -99,7 +99,7 @@ unsafe fn main_0() -> i32 { { let k: *const i32 = &k; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (3)); } ); diff --git a/tests/unit/out/unsafe/lambda_generic.rs b/tests/unit/out/unsafe/lambda_generic.rs index 4bcaa4021..ba809f8ca 100644 --- a/tests/unit/out/unsafe/lambda_generic.rs +++ b/tests/unit/out/unsafe/lambda_generic.rs @@ -16,10 +16,10 @@ unsafe fn main_0() -> i32 { let mut twice: FnPtr = lambda_unsafe!( Generic, {}, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (x)); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return ((x) + (x)); } ); @@ -31,10 +31,10 @@ unsafe fn main_0() -> i32 { { let base: i32 = base; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) + (base)); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return ((x) + (base as f64)); } ); @@ -46,10 +46,10 @@ unsafe fn main_0() -> i32 { { let total: *mut i32 = &mut total; }, - |x: i32, y: i32| { + |mut x: i32, mut y: i32| { (*total) += ((x) * (y)); }, - |x: u32, y: u32| { + |mut x: u32, mut y: u32| { (*total) = (((*total) as u32).wrapping_add((x).wrapping_mul(y))) as i32; } ); @@ -59,10 +59,10 @@ unsafe fn main_0() -> i32 { let mut sub: FnPtr = lambda_unsafe!( Generic, {}, - |x: i32, y: i32| -> i32 { + |mut x: i32, mut y: i32| -> i32 { return ((x) - (y)); }, - |x: f64, y: f64| -> f64 { + |mut x: f64, mut y: f64| -> f64 { return ((x) - (y)); } ); @@ -73,15 +73,29 @@ unsafe fn main_0() -> i32 { { let base: i32 = base; }, - |x: i32, y: i32| -> i32 { + |mut x: i32, mut y: i32| -> i32 { return (((x) * (y)) + (base)); }, - |x: i32, y: f64| -> f64 { + |mut x: i32, mut y: f64| -> f64 { return (((x as f64) * (y)) + (base as f64)); } ); assert!(((unsafe { mixed.spec:: i32>(0).call(2, 3,) }) == (16))); assert!(((unsafe { mixed.spec:: f64>(1).call(2, 0.5_f64,) }) == (11_f64))); + let mut unused: FnPtr = lambda_unsafe!(Generic, {}); + &(unused); + let mut outer: FnPtr i32> = lambda_unsafe!( + { + let base: i32 = base; + }, + |mut y: i32| -> i32 { + let mut inner: FnPtr = lambda_unsafe!(Generic, {}, |mut z: i32| -> i32 { + return ((z) + (1)); + }); + return ((unsafe { inner.spec:: i32>(0).call(y) }) + (base)); + } + ); + assert!(((unsafe { outer.call(5,) }) == (16))); return 0; } pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/lambda_generic_explicit_args.rs b/tests/unit/out/unsafe/lambda_generic_explicit_args.rs index 2c9b02f55..269030b44 100644 --- a/tests/unit/out/unsafe/lambda_generic_explicit_args.rs +++ b/tests/unit/out/unsafe/lambda_generic_explicit_args.rs @@ -82,10 +82,10 @@ unsafe fn main_0() -> i32 { let mut cast_to: FnPtr = lambda_unsafe!( Generic, {}, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x as i32) / (2)); }, - |x: i32| -> f64 { + |mut x: i32| -> f64 { return ((x as f64) / (2_f64)); } ); diff --git a/tests/unit/out/unsafe/lambda_generic_to_fn_ptr.rs b/tests/unit/out/unsafe/lambda_generic_to_fn_ptr.rs index 78dd373ec..8bbc76533 100644 --- a/tests/unit/out/unsafe/lambda_generic_to_fn_ptr.rs +++ b/tests/unit/out/unsafe/lambda_generic_to_fn_ptr.rs @@ -16,17 +16,17 @@ unsafe fn main_0() -> i32 { let mut negate: FnPtr = lambda_unsafe!( Generic, {}, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return -x; }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return -x; } ); - let mut fi: Option i32> = Some(|x: i32| -> i32 { + let mut fi: Option i32> = Some(|mut x: i32| -> i32 { return -x; }); - let mut fd: Option f64> = Some(|x: f64| -> f64 { + let mut fd: Option f64> = Some(|mut x: f64| -> f64 { return -x; }); assert!(((unsafe { (fi).unwrap()(3,) }) == (-3_i32))); @@ -34,17 +34,17 @@ unsafe fn main_0() -> i32 { let mut square: FnPtr = lambda_unsafe!( Generic, {}, - |x: i32| -> i32 { + |mut x: i32| -> i32 { return ((x) * (x)); }, - |x: f64| -> f64 { + |mut x: f64| -> f64 { return ((x) * (x)); } ); - let mut si: Option i32> = Some(|x: i32| -> i32 { + let mut si: Option i32> = Some(|mut x: i32| -> i32 { return ((x) * (x)); }); - let mut sd: Option f64> = Some(|x: f64| -> f64 { + let mut sd: Option f64> = Some(|mut x: f64| -> f64 { return ((x) * (x)); }); assert!(((unsafe { (si).unwrap()(3,) }) == (9))); diff --git a/tests/unit/out/unsafe/lambda_mutable.rs b/tests/unit/out/unsafe/lambda_mutable.rs index b0ea9c84c..bd1d22c15 100644 --- a/tests/unit/out/unsafe/lambda_mutable.rs +++ b/tests/unit/out/unsafe/lambda_mutable.rs @@ -31,7 +31,7 @@ unsafe fn main_0() -> i32 { { let total: i32 = total; }, - |x: i32| -> i32 { + |mut x: i32| -> i32 { total += x; return total; } diff --git a/tests/unit/out/unsafe/lambda_namespace_scope.rs b/tests/unit/out/unsafe/lambda_namespace_scope.rs index 43e9cc7d5..c8d2c6e01 100644 --- a/tests/unit/out/unsafe/lambda_namespace_scope.rs +++ b/tests/unit/out/unsafe/lambda_namespace_scope.rs @@ -9,7 +9,7 @@ use std::rc::Rc; pub static mut counter_0: std::cell::LazyCell = std::cell::LazyCell::new(|| unsafe { 0 }); pub static mut inc_1: std::cell::LazyCell i32>> = std::cell::LazyCell::new(|| unsafe { - FnPtr:: i32>::new(|x: i32| -> i32 { + FnPtr:: i32>::new(|mut x: i32| -> i32 { unsafe { return ((x) + (1)); } @@ -27,6 +27,20 @@ pub static mut bump_2: std::cell::LazyCell i32>> = pub unsafe fn apply_3(mut f: FnPtr i32>, mut x: i32) -> i32 { return (unsafe { f.call(x) }); } +pub unsafe fn by_ref_4(v: *const i32) -> i32 { + return ((*v) * (2)); +} +pub static mut twice_next_5: std::cell::LazyCell i32>> = + std::cell::LazyCell::new(|| unsafe { + FnPtr:: i32>::new(|mut x: i32| -> i32 { + unsafe { + return (unsafe { + let mut _v: i32 = ((x) + (1)); + by_ref_4(&mut _v) + }); + } + }) + }); pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -43,24 +57,29 @@ unsafe fn main_0() -> i32 { assert!( ((unsafe { apply_3( - (*std::cell::LazyCell::force_mut(&mut *&raw mut inc_1)).clone(), + (*std::cell::LazyCell::force_mut(&mut *&raw mut inc_1)).copy_from(), 1, ) }) == (2)) ); let mut copy: FnPtr i32> = - (*std::cell::LazyCell::force_mut(&mut *&raw mut inc_1)).clone(); + (*std::cell::LazyCell::force_mut(&mut *&raw mut inc_1)).copy_from(); assert!(((unsafe { copy.call(9,) }) == (10))); - let mut fp: Option i32> = Some(|x: i32| -> i32 { + let mut fp: Option i32> = Some(|mut x: i32| -> i32 { unsafe { return ((x) + (1)); } }); assert!(((unsafe { (fp).unwrap()(-1_i32,) }) == (0))); + assert!( + ((unsafe { (*std::cell::LazyCell::force_mut(&mut *&raw mut twice_next_5)).call(4,) }) + == (10)) + ); return 0; } pub unsafe fn __cpp2rust_init_globals() { std::cell::LazyCell::force(&*&raw const counter_0); std::cell::LazyCell::force(&*&raw const inc_1); std::cell::LazyCell::force(&*&raw const bump_2); + std::cell::LazyCell::force(&*&raw const twice_next_5); } diff --git a/tests/unit/out/unsafe/lambda_nested.rs b/tests/unit/out/unsafe/lambda_nested.rs index dc19d51db..3afc6a35e 100644 --- a/tests/unit/out/unsafe/lambda_nested.rs +++ b/tests/unit/out/unsafe/lambda_nested.rs @@ -17,13 +17,13 @@ impl S { { let this_: *mut S = (self as *mut S); }, - |y: i32| -> i32 { + |mut y: i32| -> i32 { let mut inner: FnPtr i32> = lambda_unsafe!( { let this_: *mut S = this_; let y: i32 = y; }, - |z: i32| -> i32 { + |mut z: i32| -> i32 { return ((((*this_).v) + (y)) + (z)); } ); @@ -45,13 +45,13 @@ unsafe fn main_0() -> i32 { { let x: *mut i32 = &mut x; }, - |y: i32| -> i32 { + |mut y: i32| -> i32 { let mut inner: FnPtr i32> = lambda_unsafe!( { let x: *mut i32 = x; let y: i32 = y; }, - |z: i32| -> i32 { + |mut z: i32| -> i32 { return (((*x) + (y)) + (z)); } ); diff --git a/tests/unit/out/unsafe/lambda_self_recursive.rs b/tests/unit/out/unsafe/lambda_self_recursive.rs index 7f95fb6c6..22439f3b0 100644 --- a/tests/unit/out/unsafe/lambda_self_recursive.rs +++ b/tests/unit/out/unsafe/lambda_self_recursive.rs @@ -13,22 +13,23 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - let mut fact: FnPtr = - lambda_unsafe!(Generic, {}, |self_: FnPtr, n: i32| -> i32 { - if ((n) <= (1)) { - return 1; - } - return ((n) - * (unsafe { - let _self_: FnPtr = self_.clone(); - self_ - .spec::, i32) -> i32>(0) - .call(_self_, ((n) - (1))) - })); - }); + let mut fact: FnPtr = lambda_unsafe!(Generic, {}, |mut self_: FnPtr, + mut n: i32| + -> i32 { + if ((n) <= (1)) { + return 1; + } + return ((n) + * (unsafe { + let _self_: FnPtr = self_.copy_from(); + self_ + .spec::, i32) -> i32>(0) + .call(_self_, ((n) - (1))) + })); + }); assert!( ((unsafe { - let _self_: FnPtr = fact.clone(); + let _self_: FnPtr = fact.copy_from(); fact.spec::, i32) -> i32>(0) .call(_self_, 5) }) == (120)) @@ -39,7 +40,7 @@ unsafe fn main_0() -> i32 { { let calls: *mut i32 = &mut calls; }, - |self_: *mut FnPtr, n: i32| -> i32 { + |self_: *mut FnPtr, mut n: i32| -> i32 { (*calls).postfix_inc(); if ((n) <= (2)) { return 1; @@ -73,7 +74,7 @@ unsafe fn main_0() -> i32 { { let depth: *mut i32 = &mut depth; }, - |self_: *const FnPtr, n: i32| { + |self_: *const FnPtr, mut n: i32| { if ((n) == (0)) { return; } diff --git a/tests/unit/out/unsafe/stable_sort.rs b/tests/unit/out/unsafe/stable_sort.rs index fa9f82ef8..69e4d22ed 100644 --- a/tests/unit/out/unsafe/stable_sort.rs +++ b/tests/unit/out/unsafe/stable_sort.rs @@ -20,7 +20,7 @@ unsafe fn main_0() -> i32 { .offset((5) as isize) .offset_from(arr1.as_mut_ptr()) as usize; ::std::slice::from_raw_parts_mut(arr1.as_mut_ptr(), len).sort_by(|x, y| { - if FnPtr:: bool>::new(|x: i32, y: i32| -> bool { + if FnPtr:: bool>::new(|mut x: i32, mut y: i32| -> bool { unsafe { return ((x) < (y)); } @@ -28,7 +28,7 @@ unsafe fn main_0() -> i32 { .call(*x, *y) { std::cmp::Ordering::Less - } else if FnPtr:: bool>::new(|x: i32, y: i32| -> bool { + } else if FnPtr:: bool>::new(|mut x: i32, mut y: i32| -> bool { unsafe { return ((x) < (y)); }