Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 6d2f9932f708a931b67cad20e3b98699ef12b445)
+++ src/ResolvExpr/Resolver.cc	(revision 0a60c04526af6aea8c30851e97e6dac612ea2a7b)
@@ -26,4 +26,5 @@
 #include "Common/utility.h"              // for ValueGuard, group_iterate
 #include "CurrentObject.h"               // for CurrentObject
+#include "InitTweak/GenInit.h"
 #include "InitTweak/InitTweak.h"         // for isIntrinsicSingleArgCallStmt
 #include "RenameVars.h"                  // for RenameVars, global_renamer
@@ -40,4 +41,5 @@
 #include "SynTree/TypeSubstitution.h"    // for TypeSubstitution
 #include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
+#include "Tuples/Tuples.h"
 #include "typeops.h"                     // for extractResultType
 #include "Unify.h"                       // for unify
@@ -46,5 +48,5 @@
 
 namespace ResolvExpr {
-	struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting {
+	struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting, public WithStmtsToAdd {
 		Resolver() {}
 		Resolver( const SymTab::Indexer & other ) {
@@ -611,4 +613,17 @@
 			expr = alt.expr;
 			alt.expr = nullptr;
+
+			// if with expression might be impure, create a temporary so that it is evaluated once
+			if ( Tuples::maybeImpure( expr ) ) {
+				static UniqueName tmpNamer( "_with_tmp_" );
+				ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) );
+				expr = new VariableExpr( tmp );
+				stmtsToAddBefore.push_back( new DeclStmt( tmp ) );
+				if ( InitTweak::isConstructable( tmp->type ) ) {
+					// generate ctor/dtor and resolve them
+					tmp->init = InitTweak::genCtorInit( tmp );
+					tmp->accept( *visitor );
+				}
+			}
 		}
 	}
