Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision c28a038d643e82580facb0e038d69d9bfca11e42)
+++ src/Parser/DeclarationNode.cc	(revision c453ac472f138ea3361af34d8337b990d1a6a916)
@@ -723,20 +723,10 @@
 }
 
-DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, StatementNode * with ) {
+DeclarationNode * DeclarationNode::addFunctionBody( StatementNode * body, ExpressionNode * withExprs ) {
 	assert( type );
 	assert( type->kind == TypeData::Function );
 	assert( ! type->function.body );
-	if ( with ) {
-		// convert
-		//  void f(S s) with (s) { x = 0; }
-		// to
-		//  void f(S s) { with(s) { x = 0; } }
-		WithStmt * withStmt = strict_dynamic_cast< WithStmt * >( with->build() );
-		withStmt->stmt = body->build();
-		delete body;
-		delete with;
-		body = new StatementNode( new CompoundStmt( { withStmt } ) );
-	}
 	type->function.body = body;
+	type->function.withExprs = withExprs;
 	return this;
 }
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision c28a038d643e82580facb0e038d69d9bfca11e42)
+++ src/Parser/ParseNode.h	(revision c453ac472f138ea3361af34d8337b990d1a6a916)
@@ -262,5 +262,5 @@
 	DeclarationNode * addBitfield( ExpressionNode * size );
 	DeclarationNode * addVarArgs();
-	DeclarationNode * addFunctionBody( StatementNode * body, StatementNode * with = nullptr );
+	DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
 	DeclarationNode * addOldDeclList( DeclarationNode * list );
 	DeclarationNode * setBase( TypeData * newType );
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision c28a038d643e82580facb0e038d69d9bfca11e42)
+++ src/Parser/TypeData.cc	(revision c453ac472f138ea3361af34d8337b990d1a6a916)
@@ -864,4 +864,5 @@
 		CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt );
 		decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec );
+		buildList( td->function.withExprs, decl->withExprs );
 		return decl->set_asmName( asmName );
 	} else if ( td->kind == TypeData::Aggregate ) {
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision c28a038d643e82580facb0e038d69d9bfca11e42)
+++ src/Parser/parser.yy	(revision c453ac472f138ea3361af34d8337b990d1a6a916)
@@ -259,5 +259,6 @@
 %type<sn> iteration_statement			jump_statement
 %type<sn> expression_statement			asm_statement
-%type<sn> with_statement				with_clause_opt
+%type<sn> with_statement
+%type<en> with_clause_opt
 %type<sn> exception_statement			handler_clause				finally_clause
 %type<catch_kind> handler_key
@@ -2417,5 +2418,5 @@
 		{ $$ = nullptr; }
 	| WITH '(' tuple_expression_list ')'
-		{ $$ = new StatementNode( build_with( $3, nullptr ) ); }
+		{ $$ = $3; }
 	;
 
