diff options
Diffstat (limited to 'llvm.cpp')
-rw-r--r-- | llvm.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
@@ -234,12 +234,29 @@ AFn::liftCall(CEnv& cenv, const AType& argsT) assert(gt != cenv.tenv.genericTypes.end()); AType* thisType = new AType(*gt->second); Subst argsSubst; + if (!thisType->concrete()) { // Build substitution to apply to generic type assert(argsT.size() == prot()->size()); ATuple* genericProtT = gt->second->at(1)->as<ATuple*>(); - for (size_t i = 0; i < argsT.size(); ++i) - argsSubst[genericProtT->at(i)->to<AType*>()] = argsT.at(i)->to<AType*>(); + for (size_t i = 0; i < argsT.size(); ++i) { + const AType* genericArgT = genericProtT->at(i)->to<const AType*>(); + AType* callArgT = argsT.at(i)->to<AType*>(); + assert(genericArgT); + assert(callArgT); + if (callArgT->kind == AType::EXPR) { + assert(genericArgT->kind == AType::EXPR); + assert(callArgT->size() == genericArgT->size()); + for (size_t i = 0; i < callArgT->size(); ++i) { + AType* gT = genericArgT->at(i)->to<AType*>(); + AType* aT = callArgT->at(i)->to<AType*>(); + if (gT && aT) + argsSubst[gT] = aT; + } + } else { + argsSubst[genericArgT] = callArgT; + } + } // Apply substitution to get concrete type for this call thisType = argsSubst.apply(thisType)->as<AType*>(); |