cgen: fix closure code gen with if statement in definition (#12028)
							parent
							
								
									cb149bfa00
								
							
						
					
					
						commit
						60ecbec8ea
					
				| 
						 | 
				
			
			@ -425,20 +425,17 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// it may be possible to optimize `memdup` out if the closure never leaves current scope
 | 
			
		||||
	ctx_var := g.new_tmp_var()
 | 
			
		||||
	cur_line := g.go_before_stmt(0)
 | 
			
		||||
	ctx_struct := closure_ctx_struct(node.decl)
 | 
			
		||||
	g.writeln('$ctx_struct* $ctx_var = ($ctx_struct*) memdup(&($ctx_struct){')
 | 
			
		||||
	// TODO in case of an assignment, this should only call "__closure_set_data" and "__closure_set_function" (and free the former data)
 | 
			
		||||
	g.write('__closure_create($node.decl.name, ${node.decl.params.len + 1}, ')
 | 
			
		||||
	g.writeln('($ctx_struct*) memdup(&($ctx_struct){')
 | 
			
		||||
	g.indent++
 | 
			
		||||
	for var in node.inherited_vars {
 | 
			
		||||
		g.writeln('.$var.name = $var.name,')
 | 
			
		||||
	}
 | 
			
		||||
	g.indent--
 | 
			
		||||
	g.writeln('}, sizeof($ctx_struct));')
 | 
			
		||||
	g.write('}, sizeof($ctx_struct)))')
 | 
			
		||||
	g.empty_line = false
 | 
			
		||||
	g.write(cur_line)
 | 
			
		||||
	// TODO in case of an assignment, this should only call "__closure_set_data" and "__closure_set_function" (and free the former data)
 | 
			
		||||
	g.write('__closure_create($node.decl.name, ${node.decl.params.len + 1}, $ctx_var)')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,3 +151,20 @@ fn test_go_call_closure() {
 | 
			
		|||
	assert <-ch == 15
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
fn test_closures_with_ifstmt() {
 | 
			
		||||
	a := 1
 | 
			
		||||
	f := fn [a] (x int) int {
 | 
			
		||||
		if a > x { return 1
 | 
			
		||||
		 } else { return -1
 | 
			
		||||
		 }
 | 
			
		||||
	}
 | 
			
		||||
	g := fn [a] () int {
 | 
			
		||||
		if true {
 | 
			
		||||
			return 1
 | 
			
		||||
		}
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	assert f(0) == 1
 | 
			
		||||
	assert g() == 1
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue