Skip to content

Commit 0b2c8cb

Browse files
authored
Merge pull request #42 from stepinto/fix_return_in_closure_0913
2 parents faf97e6 + 4183cde commit 0b2c8cb

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/implementation/codegen.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use syn::{
88
spanned::Spanned,
99
visit::{visit_return_type, Visit},
1010
visit_mut::{self as visitor, visit_block_mut, visit_expr_mut, VisitMut},
11-
Attribute, Expr, ExprCall, ReturnType, TypeImplTrait,
11+
Attribute, Expr, ExprCall, ExprClosure, ReturnType, TypeImplTrait,
1212
};
1313

1414
use crate::implementation::{Contract, ContractMode, ContractType, FuncWithContracts};
@@ -379,6 +379,10 @@ impl VisitMut for ReturnReplacer {
379379

380380
visit_expr_mut(self, node);
381381
}
382+
383+
fn visit_expr_closure_mut(&mut self, _node: &mut ExprClosure) {
384+
// Do not replace return statements inside closures. Skip calling the base visitor.
385+
}
382386
}
383387

384388
struct ImplDetector {

tests/issues.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,25 @@ fn gl_issue_18() {
9696

9797
assert_eq!(1, euclidean(3, 4));
9898
}
99+
100+
#[allow(unused)] // compile-only test
101+
#[test]
102+
fn gl_issue_41() {
103+
use contracts::requires;
104+
105+
fn foo(f: impl Fn(i32) -> i32) -> i32 {
106+
// no-op
107+
f(-10)
108+
}
109+
110+
#[requires(true)]
111+
fn bar() {
112+
let y = foo(|x: i32| {
113+
if x < 0 {
114+
return 0;
115+
}
116+
x
117+
});
118+
assert_eq!(y, 0);
119+
}
120+
}

0 commit comments

Comments
 (0)