diff --git a/src/hdrgen.c b/src/hdrgen.c
index 74c029f..19e6b94 100644
--- a/src/hdrgen.c
+++ b/src/hdrgen.c
@@ -547,6 +547,18 @@ public:
     void visit(WithStatement *s)
     {
         buf->writestring("with (");
+        if (Parameter *a = s->arg)
+        {
+            StorageClass stc = a->storageClass;
+            if (!a->type && !stc)
+                stc = STCauto;
+            StorageClassDeclaration::stcToCBuffer(buf, stc);
+            if (a->type)
+                typeToBuffer(a->type, a->ident);
+            else
+                buf->writestring(a->ident->toChars());
+            buf->writestring(" = ");
+        }
         s->exp->accept(this);
         buf->writestring(")");
         buf->writenl();
diff --git a/src/parse.c b/src/parse.c
index 2d73144..565dfdf 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -4301,6 +4301,61 @@ void Parser::checkDanglingElse(Loc elseloc)
     }
 }
 
+StorageClass Parser::parseStorageClass()
+{
+    StorageClass storageClass = 0;
+    StorageClass stc = 0;
+LagainStc:
+    if (stc)
+    {
+        if (storageClass & stc)
+            error("redundant storage class '%s'", Token::toChars(token.value));
+        storageClass |= stc;
+        composeStorageClass(storageClass);
+        nextToken();
+    }
+    switch (token.value)
+    {
+        case TOKref:
+            stc = STCref;
+            goto LagainStc;
+        case TOKauto:
+            stc = STCauto;
+            goto LagainStc;
+        case TOKconst:
+            if (peekNext() != TOKlparen)
+            {
+                stc = STCconst;
+                goto LagainStc;
+            }
+            break;
+        case TOKimmutable:
+            if (peekNext() != TOKlparen)
+            {
+                stc = STCimmutable;
+                goto LagainStc;
+            }
+            break;
+        case TOKshared:
+            if (peekNext() != TOKlparen)
+            {
+                stc = STCshared;
+                goto LagainStc;
+            }
+            break;
+        case TOKwild:
+            if (peekNext() != TOKlparen)
+            {
+                stc = STCwild;
+                goto LagainStc;
+            }
+            break;
+        default:
+            break;
+    }
+    return storageClass;
+}
+
 /*****************************************
  * Input:
  *      flags   PSxxxx
@@ -4777,56 +4832,7 @@ Statement *Parser::parseStatement(int flags, const utf8_t** endPtr)
             nextToken();
             check(TOKlparen);
 
-            StorageClass storageClass = 0;
-            StorageClass stc = 0;
-        LagainStc:
-            if (stc)
-            {
-                if (storageClass & stc)
-                    error("redundant storage class '%s'", Token::toChars(token.value));
-                storageClass |= stc;
-                composeStorageClass(storageClass);
-                nextToken();
-            }
-            switch (token.value)
-            {
-                case TOKref:
-                    stc = STCref;
-                    goto LagainStc;
-                case TOKauto:
-                    stc = STCauto;
-                    goto LagainStc;
-                case TOKconst:
-                    if (peekNext() != TOKlparen)
-                    {
-                        stc = STCconst;
-                        goto LagainStc;
-                    }
-                    break;
-                case TOKimmutable:
-                    if (peekNext() != TOKlparen)
-                    {
-                        stc = STCimmutable;
-                        goto LagainStc;
-                    }
-                    break;
-                case TOKshared:
-                    if (peekNext() != TOKlparen)
-                    {
-                        stc = STCshared;
-                        goto LagainStc;
-                    }
-                    break;
-                case TOKwild:
-                    if (peekNext() != TOKlparen)
-                    {
-                        stc = STCwild;
-                        goto LagainStc;
-                    }
-                    break;
-                default:
-                    break;
-            }
+            StorageClass storageClass = parseStorageClass();
 
             if (storageClass != 0 &&
                 token.value == TOKidentifier &&
@@ -5181,15 +5187,37 @@ Statement *Parser::parseStatement(int flags, const utf8_t** endPtr)
         }
 
         case TOKwith:
-        {   Expression *exp;
+        {
             Statement *body;
+            Expression *exp = NULL;
+            Parameter *arg = NULL;
 
             nextToken();
             check(TOKlparen);
+
+            StorageClass storageClass = parseStorageClass();
+
+            if (storageClass != 0 &&
+                token.value == TOKidentifier &&
+                peek(&token)->value == TOKassign)
+            {
+                Identifier *ai = token.ident;
+                Type *at = NULL;        // infer argument type
+                nextToken();
+                check(TOKassign);
+                arg = new Parameter(storageClass, at, ai, NULL);
+            }
+            else if (isDeclaration(&token, 2, TOKassign, NULL))
+            {
+                Identifier *ai;
+                Type *at = parseType(&ai);
+                check(TOKassign);
+                arg = new Parameter(storageClass, at, ai, NULL);
+            }
             exp = parseExpression();
             check(TOKrparen);
             body = parseStatement(PSscope);
-            s = new WithStatement(loc, exp, body);
+            s = new WithStatement(loc, arg, exp, body);
             break;
         }
 
diff --git a/src/parse.h b/src/parse.h
index 9e6141c..ddd0702 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -117,6 +117,7 @@ public:
     Type *parseBasicType2(Type *t);
     Type *parseDeclarator(Type *t, Identifier **pident,
         TemplateParameters **tpl = NULL, StorageClass storage_class = 0, int* pdisable = NULL, Expressions **pudas = NULL);
+    StorageClass parseStorageClass();
     void parseStorageClasses(StorageClass &storage_class, LINK &link, unsigned &structalign, Expressions *&udas);
     Dsymbols *parseDeclarations(bool autodecl, PrefixAttributes *pAttrs, const utf8_t *comment);
     FuncDeclaration *parseContracts(FuncDeclaration *f);
diff --git a/src/statement.c b/src/statement.c
index a7c257c..49baff9 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -4161,9 +4161,10 @@ bool SynchronizedStatement::hasContinue()
 
 /******************************** WithStatement ***************************/
 
-WithStatement::WithStatement(Loc loc, Expression *exp, Statement *body)
+WithStatement::WithStatement(Loc loc, Parameter *arg, Expression *exp, Statement *body)
     : Statement(loc)
 {
+    this->arg = arg;
     this->exp = exp;
     this->body = body;
     wthis = NULL;
@@ -4172,6 +4173,7 @@ WithStatement::WithStatement(Loc loc, Expression *exp, Statement *body)
 Statement *WithStatement::syntaxCopy()
 {
     return new WithStatement(loc,
+        arg ? arg->syntaxCopy() : NULL,
         exp->syntaxCopy(),
         body ? body->syntaxCopy() : NULL);
 }
@@ -4182,6 +4184,30 @@ Statement *WithStatement::semantic(Scope *sc)
     Initializer *init;
 
     //printf("WithStatement::semantic()\n");
+
+    if (arg)
+    {
+        /* Re-write to
+         * {
+         *   <decl> argname = exp
+         *   with(argname)
+         *   {
+         *     ...
+         *   }
+         * }
+         */
+        //printf("WITH arg(%s)\n", arg->ident->toChars());
+        wthis = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, exp));
+        //wthis->parent = sc->func; //k8:??? IfStatement does this
+        wthis->storage_class |= arg->storageClass;
+        //wthis->storage_class |= STCtemp; //k8:??? struct rewrite in this method does this
+        ExpStatement *es = new ExpStatement(loc, new DeclarationExp(loc, wthis));
+        exp = new VarExp(loc, wthis);
+        Statement *ss = new ScopeStatement(loc, new CompoundStatement(loc, es, this));
+        arg = NULL; // prevent further rewritings
+        return ss->semantic(sc);
+    }
+
     exp = exp->semantic(sc);
     exp = resolveProperties(sc, exp);
     // exp = exp_>optimize(0);  //?
diff --git a/src/statement.h b/src/statement.h
index 7e9c716..d27f6be 100644
--- a/src/statement.h
+++ b/src/statement.h
@@ -574,11 +574,12 @@ public:
 class WithStatement : public Statement
 {
 public:
+    Parameter *arg;
     Expression *exp;
     Statement *body;
     VarDeclaration *wthis;
 
-    WithStatement(Loc loc, Expression *exp, Statement *body);
+    WithStatement(Loc loc, Parameter *arg, Expression *exp, Statement *body);
     Statement *syntaxCopy();
     Statement *semantic(Scope *sc);
 
