diff --git src/mtype.c src/mtype.c
index caeffa6..b07f9e1 100644
--- src/mtype.c
+++ src/mtype.c
@@ -1873,6 +1873,18 @@ Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident)
                 fd->error("must be a template opDispatch(string s), not a %s", fd->kind());
                 return new ErrorExp();
             }
+            for (TemplateDeclaration *tdi = td; tdi; tdi = tdi->overnext)
+            {
+                Dsymbol *s = tdi->onemember;
+                if (s)
+                {
+                    s = s->toAlias();
+                    if (s->isFuncDeclaration() || s->isVarDeclaration() ||
+                        s->isTemplateDeclaration())
+                        continue;
+                }
+                tdi->error("is not a function template");   // fail339
+            }
             StringExp *se = new StringExp(e->loc, ident->toChars());
             Objects *tiargs = new Objects();
             tiargs->push(se);
@@ -5423,16 +5435,12 @@ d_uns64 TypeQualified::size(Loc loc)
  *      if type, *pt is set
  */
 
+static Dsymbol *resolveMember(Loc loc, Scope *sc, Dsymbol *s, Identifier *id);
+
 void TypeQualified::resolveHelper(Loc loc, Scope *sc,
-        Dsymbol *s, Dsymbol *scopesym,
+        Dsymbol *rootsym, Dsymbol *scopesym,
         Expression **pe, Type **pt, Dsymbol **ps)
 {
-    VarDeclaration *v;
-    FuncDeclaration *fd;
-    EnumMember *em;
-    TupleDeclaration *td;
-    Expression *e;
-
 #if 0
     printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, toChars());
     if (scopesym)
@@ -5441,164 +5449,156 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
     *pe = NULL;
     *pt = NULL;
     *ps = NULL;
-    if (s)
+
+    if (!rootsym)
     {
-        //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
-        s->checkDeprecated(loc, sc);            // check for deprecated aliases
-        s = s->toAlias();
-        //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
-        for (int i = 0; i < idents.dim; i++)
-        {
-            Identifier *id = (Identifier *)idents.data[i];
-            Dsymbol *sm = s->searchX(loc, sc, id);
-            //printf("\t3: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
-            //printf("\tgetType = '%s'\n", s->getType()->toChars());
-            if (!sm)
-            {   Type *t;
-
-                v = s->isVarDeclaration();
-                if (v && id == Id::length)
-                {
-                    e = v->getConstInitializer();
-                    if (!e)
-                        e = new VarExp(loc, v);
-                    t = e->type;
-                    if (!t)
-                        goto Lerror;
-                    goto L3;
-                }
-                else if (v && id == Id::stringof)
-                {
-                    e = new DsymbolExp(loc, s, 0);
-                    do
-                    {
-                        id = (Identifier *)idents.data[i];
-                        e = new DotIdExp(loc, e, id);
-                    } while (++i < idents.dim);
-                    e = e->semantic(sc);
-                    *pe = e;
-                    return;
-                }
+        error(loc, "identifier '%s' is not defined", toChars());
+        return;
+    }
 
-                t = s->getType();
-                if (!t && s->isDeclaration())
-                    t = s->isDeclaration()->type;
-                if (t)
-                {
-                    sm = t->toDsymbol(sc);
-                    if (sm)
-                    {   sm = sm->search(loc, id, 0);
-                        if (sm)
-                            goto L2;
-                    }
-                    //e = t->getProperty(loc, id);
-                    e = new TypeExp(loc, t);
-                    e = t->dotExp(sc, e, id);
-                    i++;
-                L3:
-                    for (; i < idents.dim; i++)
-                    {
-                        id = (Identifier *)idents.data[i];
-                        //printf("e: '%s', id: '%s', type = %p\n", e->toChars(), id->toChars(), e->type);
-                        if (id == Id::offsetof || !e->type)
-                        {   e = new DotIdExp(e->loc, e, id);
-                            e = e->semantic(sc);
-                        }
-                        else
-                            e = e->type->dotExp(sc, e, id);
-                    }
-                    *pe = e;
-                }
-                else
-                  Lerror:
-                    error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars());
-                return;
+    /* Resolve the array of identifiers.
+     */
+    Dsymbol *s = rootsym;
+    Expression *e = NULL;
+
+    s->checkDeprecated(loc, sc);        // check for deprecated aliases
+    s = s->toAlias();
+
+    for (size_t i = 0; i < idents.dim; i++)
+    {
+        Identifier *id = (Identifier *)idents.data[i];
+
+        if (s)
+        {
+            Dsymbol *sm = ::resolveMember(loc, sc, s, id);
+            if (sm)
+            {
+                s = sm->toAlias();
+                continue;
             }
-        L2:
-            s = sm->toAlias();
+            e = new DsymbolExp(loc, s);
+            e = e->semantic(sc);
+            s = NULL;
         }
 
-        v = s->isVarDeclaration();
-        if (v)
+        if (e)
         {
-            *pe = new VarExp(loc, v);
-            return;
+            e = new DotIdExp(loc, e, id);
+            e = e->semantic(sc);
+            if (e->op == TOKtype)
+                s = getDsymbol(e->type);
+            else
+                s = getDsymbol(e);
         }
+        assert(s || e);
+    }
+
+    if (!s)
+    {
+        if (e->op == TOKtype)
+            *pt = e->type;
+        else
+            *pe = e;
+        return;
+    }
+
+    /* Resolve the symbol.
+     */
+    VarDeclaration *v = s->isVarDeclaration();
+    if (v)
+    {
+        *pe = new VarExp(loc, v);
+        return;
+    }
 #if 0
-        fd = s->isFuncDeclaration();
-        if (fd)
-        {
-            *pe = new DsymbolExp(loc, fd, 1);
-            return;
-        }
+    FuncDeclaration *fd = s->isFuncDeclaration();
+    if (fd)
+    {
+        *pe = new DsymbolExp(loc, fd, 1);
+        return;
+    }
 #endif
-        em = s->isEnumMember();
-        if (em)
-        {
-            // It's not a type, it's an expression
-            *pe = em->value->copy();
-            return;
-        }
+    EnumMember *em = s->isEnumMember();
+    if (em)
+    {
+        // It's not a type, it's an expression
+        *pe = em->value->copy();
+        return;
+    }
 
 L1:
-        Type *t = s->getType();
-        if (!t)
-        {
-            // If the symbol is an import, try looking inside the import
-            Import *si;
+    Type *t = s->getType();
+    if (!t)
+    {
+        // If the symbol is an import, try looking inside the import
+        Import *si;
 
-            si = s->isImport();
-            if (si)
-            {
-                s = si->search(loc, s->ident, 0);
-                if (s && s != si)
-                    goto L1;
-                s = si;
-            }
-            *ps = s;
-            return;
-        }
-        if (t->ty == Tinstance && t != this && !t->deco)
-        {   error(loc, "forward reference to '%s'", t->toChars());
-            return;
+        si = s->isImport();
+        if (si)
+        {
+            s = si->search(loc, s->ident, 0);
+            if (s && s != si)
+                goto L1;
+            s = si;
         }
+        *ps = s;
+        return;
+    }
+    if (t->ty == Tinstance && t != this && !t->deco)
+    {   error(loc, "forward reference to '%s'", t->toChars());
+        return;
+    }
 
-        if (t != this)
+    if (t != this)
+    {
+        if (t->reliesOnTident())
         {
-            if (t->reliesOnTident())
+            if (s->scope)
+                t = t->semantic(loc, s->scope);
+            else
             {
-                if (s->scope)
-                    t = t->semantic(loc, s->scope);
-                else
+                /* Attempt to find correct scope in which to evaluate t.
+                 * Not sure if this is right or not, or if we should just
+                 * give forward reference error if s->scope is not set.
+                 */
+                for (Scope *scx = sc; 1; scx = scx->enclosing)
                 {
-                    /* Attempt to find correct scope in which to evaluate t.
-                     * Not sure if this is right or not, or if we should just
-                     * give forward reference error if s->scope is not set.
-                     */
-                    for (Scope *scx = sc; 1; scx = scx->enclosing)
+                    if (!scx)
+                    {   error(loc, "forward reference to '%s'", t->toChars());
+                        return;
+                    }
+                    if (scx->scopesym == scopesym)
                     {
-                        if (!scx)
-                        {   error(loc, "forward reference to '%s'", t->toChars());
-                            return;
-                        }
-                        if (scx->scopesym == scopesym)
-                        {
-                            t = t->semantic(loc, scx);
-                            break;
-                        }
+                        t = t->semantic(loc, scx);
+                        break;
                     }
                 }
             }
         }
-        if (t->ty == Ttuple)
-            *pt = t;
-        else
-            *pt = t->merge();
     }
-    if (!s)
+    if (t->ty == Ttuple)
+        *pt = t;
+    else
+        *pt = t->merge();
+}
+
+static Dsymbol *resolveMember(Loc loc, Scope *sc, Dsymbol *s, Identifier *id)
+{
+    Dsymbol *sm = s->searchX(loc, sc, id);
+    if (sm)
+        return sm;
+
+    // fall to the type of the symbol
+    Type *t = s->getType();
+    if (!t && s->isDeclaration())
+        t = ((Declaration *)s)->type;
+    if (t)
     {
-        error(loc, "identifier '%s' is not defined", toChars());
+        Dsymbol *st = t->toDsymbol(sc);
+        if (st && st != s)
+            return resolveMember(loc, sc, st, id);
     }
+    return NULL;
 }
 
 /***************************** TypeIdentifier *****************************/
