diff -u dmd/scope.c dmd-trace/scope.c
--- dmd/scope.c	2009-04-06 02:47:20.000000000 +0200
+++ dmd-trace/scope.c	2009-04-08 14:24:55.000000000 +0200
@@ -53,6 +53,7 @@
     this->parent = NULL;
     this->sw = NULL;
     this->tf = NULL;
+    this->tinst = NULL;
     this->sbreak = NULL;
     this->scontinue = NULL;
     this->fes = NULL;
@@ -90,6 +91,7 @@
     this->sd = NULL;
     this->sw = enclosing->sw;
     this->tf = enclosing->tf;
+    this->tinst = enclosing->tinst;
     this->sbreak = enclosing->sbreak;
     this->scontinue = enclosing->scontinue;
     this->fes = enclosing->fes;
diff -u dmd/scope.h dmd-trace/scope.h
--- dmd/scope.h	2009-04-06 02:47:20.000000000 +0200
+++ dmd-trace/scope.h	2009-04-08 14:25:12.000000000 +0200
@@ -51,6 +51,7 @@
     LabelStatement *slabel;	// enclosing labelled statement
     SwitchStatement *sw;	// enclosing switch statement
     TryFinallyStatement *tf;	// enclosing try finally statement
+    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 -u dmd/staticassert.c dmd-trace/staticassert.c
--- dmd/staticassert.c	2009-04-06 02:47:20.000000000 +0200
+++ dmd-trace/staticassert.c	2009-04-08 14:26:37.000000000 +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 -u dmd/template.c dmd-trace/template.c
--- dmd/template.c	2009-04-06 02:47:20.000000000 +0200
+++ dmd-trace/template.c	2009-04-08 14:31:00.000000000 +0200
@@ -3049,6 +3049,7 @@
     this->tiargs = NULL;
     this->tempdecl = NULL;
     this->inst = NULL;
+    this->tinst = NULL;
     this->argsym = NULL;
     this->aliasdecl = NULL;
     this->semanticdone = 0;
@@ -3076,6 +3077,7 @@
     this->tiargs = tiargs;
     this->tempdecl = td;
     this->inst = NULL;
+    this->tinst = NULL;
     this->argsym = NULL;
     this->aliasdecl = NULL;
     this->semanticdone = 0;
@@ -3163,6 +3165,10 @@
 #if LOG
     printf("\tdo semantic\n");
 #endif
+
+    // get the enclosing template instance from the scope tinst
+    tinst = sc->tinst;
+
     if (havetempdecl)
     {
 	assert((size_t)tempdecl->scope > 0x10000);
@@ -3371,6 +3377,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 WINDOWS_SEH
   __try
@@ -3435,6 +3442,8 @@
     if (global.errors != errorsave)
     {
 	error("error instantiating");
+	if (tinst)
+	    tinst->printInstantiationTrace();
 	errors = 1;
 	if (global.gag)
 	    tempdecl->instances.remove(tempdecl_instance_idx);
@@ -3999,6 +4008,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];
@@ -4029,6 +4039,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];
@@ -4148,6 +4159,43 @@
     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 ================================ */
 
 TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual,
diff -u dmd/template.h dmd-trace/template.h
--- dmd/template.h	2009-04-06 02:47:20.000000000 +0200
+++ dmd-trace/template.h	2009-04-08 14:32:01.000000000 +0200
@@ -269,6 +269,7 @@
 
     TemplateDeclaration *tempdecl;	// referenced by foo.bar.abc
     TemplateInstance *inst;		// refer to existing instance
+    TemplateInstance *tinst;            // enclosing template instance
     ScopeDsymbol *argsym;		// argument symbol table
     AliasDeclaration *aliasdecl;	// !=NULL if instance is an alias for its
 					// sole member
@@ -300,6 +301,7 @@
     int oneMember(Dsymbol **ps);
     char *toChars();
     char *mangle();
+    void printInstantiationTrace();
 
     void toObjFile(int multiobj);			// compile to .obj file
 
