diff -r 5d6ef6e6805d -r d4e95db0e62b dmd/scope.c
--- a/dmd/scope.c	Fri Aug 29 15:01:48 2008 +0200
+++ b/dmd/scope.c	Sat Aug 30 10:30:57 2008 +0200
@@ -54,6 +54,7 @@
     this->sw = NULL;
     this->tf = NULL;
     this->tfOfTry = NULL;
+    this->tinst = NULL;
     this->sbreak = NULL;
     this->scontinue = NULL;
     this->fes = NULL;
@@ -92,6 +93,7 @@
     this->sw = enclosing->sw;
     this->tf = enclosing->tf;
     this->tfOfTry = enclosing->tfOfTry;
+    this->tinst = enclosing->tinst;
     this->sbreak = enclosing->sbreak;
     this->scontinue = enclosing->scontinue;
     this->fes = enclosing->fes;
diff -r 5d6ef6e6805d -r d4e95db0e62b dmd/scope.h
--- a/dmd/scope.h	Fri Aug 29 15:01:48 2008 +0200
+++ b/dmd/scope.h	Sat Aug 30 10:30:57 2008 +0200
@@ -47,6 +47,7 @@
     SwitchStatement *sw;	// enclosing switch statement
     TryFinallyStatement *tf;	// enclosing try finally statement; set inside its finally block
     EnclosingHandler *tfOfTry; // enclosing try-finally, volatile or synchronized statement; set inside its try or body block
+    TemplateInstance *tinst;	// enclosing template instance
     Statement *sbreak;		// enclosing statement that supports "break"
     Statement *scontinue;	// enclosing statement that supports "continue"
     ForeachStatement *fes;	// if nested function for ForeachStatement, this is it
diff -r 5d6ef6e6805d -r d4e95db0e62b dmd/staticassert.c
--- a/dmd/staticassert.c	Fri Aug 29 15:01:48 2008 +0200
+++ b/dmd/staticassert.c	Sat Aug 30 10:30:57 2008 +0200
@@ -16,6 +16,8 @@
 #include "expression.h"
 #include "id.h"
 #include "hdrgen.h"
+#include "scope.h"
+#include "template.h"
 
 /********************************* AttribDeclaration ****************************/
 
@@ -66,6 +68,8 @@
 	}
 	else
 	    error("is false");
+	if(sc->tinst)
+	    sc->tinst->printInstantiationTrace();
 	if (!global.gag)
 	    fatal();
     }
diff -r 5d6ef6e6805d -r d4e95db0e62b dmd/template.c
--- a/dmd/template.c	Fri Aug 29 15:01:48 2008 +0200
+++ b/dmd/template.c	Sat Aug 30 10:30:57 2008 +0200
@@ -2775,6 +2775,7 @@
     this->havetempdecl = 0;
     this->isnested = NULL;
     this->errors = 0;
+    this->tinst = NULL;
 }
 
 
@@ -2798,6 +2799,7 @@
     this->havetempdecl = 1;
     this->isnested = NULL;
     this->errors = 0;
+    this->tinst = NULL;
 
     assert((size_t)tempdecl->scope > 0x10000);
 }
@@ -2873,6 +2875,9 @@
 	return;
     }
     semanticdone = 1;
+
+    // get the enclosing template instance from the scope tinst
+    tinst = sc->tinst;
 
 #if LOG
     printf("\tdo semantic\n");
@@ -3062,6 +3067,7 @@
     sc2 = scope->push(this);
     //printf("isnested = %d, sc->parent = %s\n", isnested, sc->parent->toChars());
     sc2->parent = /*isnested ? sc->parent :*/ this;
+    sc2->tinst = this;
 
 #if !IN_LLVM    
 #if _WIN32
@@ -3130,6 +3136,8 @@
     if (global.errors != errorsave)
     {
 	error("error instantiating");
+	if(tinst)
+	    tinst->printInstantiationTrace();
 	errors = 1;
 	if (global.gag)
 	    tempdecl->instances.remove(tempdecl_instance_idx);
@@ -3687,6 +3695,7 @@
 	assert(sc);
 	sc = sc->push(argsym);
 	sc = sc->push(this);
+	sc->tinst = this;
 	for (i = 0; i < members->dim; i++)
 	{
 	    Dsymbol *s = (Dsymbol *)members->data[i];
@@ -3717,6 +3726,7 @@
 	sc = tempdecl->scope;
 	sc = sc->push(argsym);
 	sc = sc->push(this);
+	sc->tinst = this;
 	for (int i = 0; i < members->dim; i++)
 	{
 	    Dsymbol *s = (Dsymbol *)members->data[i];
@@ -3835,6 +3845,43 @@
     s = buf.toChars();
     buf.data = NULL;
     return s;
+}
+
+void TemplateInstance::printInstantiationTrace()
+{
+    if(global.gag)
+	return;
+
+    const int max_shown = 6;
+
+    // determine instantiation depth
+    int n_instantiations = 1;
+    TemplateInstance* cur = this;
+    while(cur = cur->tinst)
+	++n_instantiations;
+
+    // show full trace only if it's short or verbose is on
+    if(n_instantiations <= max_shown || global.params.verbose)
+    {
+	cur = this;
+	while(cur)
+	{
+	    fprintf(stdmsg,"    instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
+	    cur = cur->tinst;
+	}
+    }
+    else
+    {
+	cur = this;
+	size_t i = 0;
+	for(; i < max_shown/2; ++i, cur = cur->tinst)
+	    fprintf(stdmsg,"    instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
+	fprintf(stdmsg,"    ... (%d instantiations, -v to show) ...\n", n_instantiations - max_shown);
+	for(; i < n_instantiations - max_shown + max_shown/2; ++i, cur = cur->tinst) 
+	{}
+	for(; i < n_instantiations; ++i, cur = cur->tinst) 
+	    fprintf(stdmsg,"    instantiatied in %s: %s\n", cur->loc.toChars(), cur->toChars());
+    }
 }
 
 /* ======================== TemplateMixin ================================ */
diff -r 5d6ef6e6805d -r d4e95db0e62b dmd/template.h
--- a/dmd/template.h	Fri Aug 29 15:01:48 2008 +0200
+++ b/dmd/template.h	Sat Aug 30 10:30:57 2008 +0200
@@ -314,6 +314,10 @@
 
     TemplateInstance *isTemplateInstance() { return this; }
     AliasDeclaration *isAliasDeclaration();
+
+    // LLVMDC
+    TemplateInstance *tinst; // enclosing template instance
+    void printInstantiationTrace();
 };
 
 struct TemplateMixin : TemplateInstance
