Index: declaration.c
===================================================================
--- declaration.c	(revision 196)
+++ declaration.c	(working copy)
@@ -689,10 +689,18 @@
     //if (strcmp(toChars(), "mul") == 0) halt();
 #endif
 
+    Scope *scx = NULL;
+    if (scope)
+    {	sc = scope;
+	scx = scope;		// save so we don't make redundant copies
+	scope = NULL;
+    }
+
     storage_class |= sc->stc;
     if (storage_class & STCextern && init)
 	error("extern symbols cannot have initializers");
 
+    Type *tb = NULL;
     /* If auto type inference, do the inference
      */
     int inferred = 0;
@@ -711,7 +719,43 @@
     else
     {	if (!originalType)
 	    originalType = type;
-	type = type->semantic(loc, sc);
+	
+	Dsymbol* parent = sc->parent ? sc->parent->pastMixin() : 0;
+	if(global.tryfwd && parent && (parent->isAggregateDeclaration() || parent->isModule()))
+	{   // do not try this inside functions
+	    unsigned errors = global.errors;
+	    unsigned progress = Module::dprogress;
+	    global.gag++;
+	    Type* ntype = type->syntaxCopy(); // this line would love a garbage collector
+	    ntype = ntype->semantic(loc, sc);
+	    tb = ntype->toBasetype(); // also test for errors (especially forward referencing enum)
+	    global.gag--;
+	    if(global.errors != errors)
+	    {
+		Module::dprogress = progress; // we are throwing away the type copy, so no progress
+		if (global.gag == 0)
+		    global.errors = errors;
+		AggregateDeclaration *ad = sc->anonAgg;
+		if (!ad)
+		    ad = parent->isAggregateDeclaration();
+		if (ad)
+		    ad->sizeok = 2;
+		else
+		{
+#if DMDV2
+		    /* Save scope for later use, to try again
+		     */
+		    scope = scx ? scx : new Scope(*sc);
+		    scope->setNoFree();
+#endif
+		    scope->module->addDeferredSemantic(this);
+		}
+		return;
+	    }
+	    type = ntype;
+	}
+	else
+	    type = type->semantic(loc, sc);
     }
     //printf(" semantic type = %s\n", type ? type->toChars() : "null");
 
@@ -733,7 +777,8 @@
     Dsymbol *parent = toParent();
     FuncDeclaration *fd = parent->isFuncDeclaration();
 
-    Type *tb = type->toBasetype();
+    if(!tb)
+	tb = type->toBasetype();
     if (tb->ty == Tvoid && !(storage_class & STClazy))
     {	error("voids have no value");
 	type = Type::terror;
@@ -854,7 +899,11 @@
 	    }
 	    else
 #endif
+	    {
 		aad->addField(sc, this);
+		if(aad->sizeok == 2)
+		    return; // makes no sense to continue, we get called later again anyway
+	    }
 	}
 
 	InterfaceDeclaration *id = parent->isInterfaceDeclaration();
Index: mars.c
===================================================================
--- mars.c	(revision 196)
+++ mars.c	(working copy)
@@ -1046,6 +1046,8 @@
 	fatal();
 #endif
 
+    global.tryfwd++;
+
     // Do semantic analysis
     for (i = 0; i < modules.dim; i++)
     {
@@ -1054,6 +1056,10 @@
 	    printf("semantic  %s\n", m->toChars());
 	m->semantic();
     }
+
+    global.tryfwd--;
+    Module::runDeferredSemantic(); // output "normal" errors instead of "forward" errors by semantic2
+
     if (global.errors)
 	fatal();
 
Index: mars.h
===================================================================
--- mars.h	(revision 196)
+++ mars.h	(working copy)
@@ -227,6 +227,7 @@
     Param params;
     unsigned errors;	// number of errors reported so far
     unsigned gag;	// !=0 means gag reporting of errors
+    unsigned tryfwd;	// !=0 means do not report errors due to possible forward references
 
     Global();
 };
Index: module.h
===================================================================
--- module.h	(revision 196)
+++ module.h	(working copy)
@@ -136,8 +136,8 @@
     int needModuleInfo();
     Dsymbol *search(Loc loc, Identifier *ident, int flags);
     void deleteObjFile();
-    void addDeferredSemantic(Dsymbol *s);
-    void runDeferredSemantic();
+    static void addDeferredSemantic(Dsymbol *s);
+    static void runDeferredSemantic();
     int imports(Module *m);
 
     // Back end
Index: struct.c
===================================================================
--- struct.c	(revision 196)
+++ struct.c	(working copy)
@@ -191,8 +191,23 @@
 	return;
     }
 
+    unsigned errors = global.errors;
+    if(global.tryfwd)
+	global.gag++;
+    
     memsize = t->size(loc);
     memalignsize = t->alignsize();
+    
+    if(global.tryfwd)
+    {	global.gag--;
+	if(global.errors != errors)
+	{
+	    if (global.gag == 0)
+		global.errors = errors;
+	    sizeok = 2;		// cannot finish; flag as forward referenced
+	    return;
+	}
+    }
     xalign = t->memalign(sc->structalign);
     alignmember(xalign, memalignsize, &sc->offset);
     v->offset = sc->offset;
Index: template.c
===================================================================
--- template.c	(revision 196)
+++ template.c	(working copy)
@@ -3423,6 +3423,7 @@
     // will get called on the instance members
 #if 1
     int dosemantic3 = 0;
+    Array *addedAsMember = 0;
     {	Array *a;
 
 	Scope *scx = sc;
@@ -3461,6 +3462,7 @@
 	    if (i == a->dim)
 	    {
 		a->push(this);
+		addedAsMember = a;
 		break;
 	    }
 	    if (this == (Dsymbol *)a->data[i])	// if already in Array
@@ -3619,7 +3621,18 @@
 	}
 	errors = 1;
 	if (global.gag)
+	{
 	    tempdecl->instances.remove(tempdecl_instance_idx);
+	    if (addedAsMember)
+	    {	// the member array might have been modified by inner semantics, so better search it
+		for (size_t i = 0; i < addedAsMember->dim; i++)
+		    if (addedAsMember->data[i] == this)
+		    {
+			addedAsMember->remove (i);
+			break;
+		    }
+	    }
+	}
     }
 
 #if LOG
