Index: aggregate.h
===================================================================
--- aggregate.h	(revision 317)
+++ aggregate.h	(working copy)
@@ -132,6 +132,7 @@
     StructDeclaration(Loc loc, Identifier *id);
     Dsymbol *syntaxCopy(Dsymbol *s);
     void semantic(Scope *sc);
+    Dsymbol *search(Loc loc, Identifier *ident, int flags);
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     char *mangle();
     const char *kind();
Index: declaration.c
===================================================================
--- declaration.c	(revision 317)
+++ declaration.c	(working copy)
@@ -710,10 +710,19 @@
     //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;
@@ -752,7 +761,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");
 
@@ -781,7 +826,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;
@@ -904,7 +950,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();
@@ -1187,6 +1237,7 @@
 
 	    if (!global.errors && !inferred)
 	    {
+		unsigned progress = Module::dprogress;
 		unsigned errors = global.errors;
 		global.gag++;
 		//printf("+gag\n");
@@ -1208,6 +1259,7 @@
 		//printf("-gag\n");
 		if (errors != global.errors)	// if errors happened
 		{
+		    Module::dprogress = progress; // we are throwing away the expression copy, so no progress
 		    if (global.gag == 0)
 			global.errors = errors;	// act as if nothing happened
 #if DMDV2
Index: mars.c
===================================================================
--- mars.c	(revision 317)
+++ mars.c	(working copy)
@@ -1088,6 +1088,8 @@
     if (global.errors)
        fatal();
 
+    global.tryfwd++;
+
     // Do semantic analysis
     for (i = 0; i < modules.dim; i++)
     {
@@ -1096,6 +1098,10 @@
 	    printf("semantic  %s\n", m->toChars());
 	m->semantic();
     }
+
+    global.tryfwd--;
+    Module::runDeferredSemantic(true); // output "normal" errors instead of "forward" errors by semantic2
+
     if (global.errors)
 	fatal();
 
Index: mars.h
===================================================================
--- mars.h	(revision 317)
+++ mars.h	(working copy)
@@ -232,6 +232,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.c
===================================================================
--- module.c	(revision 317)
+++ module.c	(working copy)
@@ -932,13 +932,15 @@
  * Run semantic() on deferred symbols.
  */
 
-void Module::runDeferredSemantic()
+void Module::runDeferredSemantic(bool force)
 {
     size_t len;
 
     static int nested;
     if (nested)
 	return;
+    if(!force && dprogress == 0)
+	return;
     //if (deferred.dim) printf("+Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim);
     nested++;
 
Index: module.h
===================================================================
--- module.h	(revision 317)
+++ module.h	(working copy)
@@ -139,8 +139,8 @@
     Dsymbol *search(Loc loc, Identifier *ident, int flags);
     Dsymbol *symtabInsert(Dsymbol *s);
     void deleteObjFile();
-    void addDeferredSemantic(Dsymbol *s);
-    void runDeferredSemantic();
+    static void addDeferredSemantic(Dsymbol *s);
+    static void runDeferredSemantic(bool force = false);
     int imports(Module *m);
 
     // Back end
Index: struct.c
===================================================================
--- struct.c	(revision 317)
+++ 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;
@@ -554,6 +569,24 @@
     }
 }
 
+Dsymbol *StructDeclaration::search(Loc loc, Identifier *ident, int flags)
+{
+    Dsymbol *s;
+    //printf("%s.ClassDeclaration::search('%s')\n", toChars(), ident->toChars());
+
+    if (scope)
+    	semantic(NULL);
+
+    if (!members || !symtab)
+    {
+	error("is forward referenced when looking for '%s'", ident->toChars());
+	//*(char*)0=0;
+	return NULL;
+    }
+
+    return ScopeDsymbol::search(loc, ident, flags);
+}
+
 void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
 {   int i;
 
Index: template.c
===================================================================
--- template.c	(revision 317)
+++ template.c	(working copy)
@@ -3595,6 +3595,7 @@
     // will get called on the instance members
 #if 1
     int dosemantic3 = 0;
+    Array *addedAsMember = 0;
     {	Array *a;
 
 	Scope *scx = sc;
@@ -3633,6 +3634,7 @@
 	    if (i == a->dim)
 	    {
 		a->push(this);
+		addedAsMember = a;
 		break;
 	    }
 	    if (this == (Dsymbol *)a->data[i])	// if already in Array
@@ -3827,7 +3829,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
