summaryrefslogtreecommitdiffstats
path: root/source/slang/syntax.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/syntax.cpp')
-rw-r--r--source/slang/syntax.cpp57
1 files changed, 46 insertions, 11 deletions
diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp
index 2c214a332..f8237359d 100644
--- a/source/slang/syntax.cpp
+++ b/source/slang/syntax.cpp
@@ -489,7 +489,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
bool restore = false;
if (thisSubst && thisSubst->sourceType.Ptr() == dynamic_cast<Val*>(this))
thisSubst->sourceType = nullptr;
- auto newSubst = declRef.substitutions->SubstituteImpl(subst, ioDiff);
+ auto newSubst = substituteSubstitutions(declRef.substitutions, subst, ioDiff);
if (restore)
thisSubst->sourceType = oldSubstSrc;
if (auto thisTypeSubst = newSubst.As<ThisTypeSubstitution>())
@@ -1205,9 +1205,7 @@ void Type::accept(IValVisitor* visitor, void* extra)
if (!this) return nullptr;
int diff = 0;
- RefPtr<Substitutions> outerSubst;
- if (outer)
- outerSubst = outer->SubstituteImpl(subst, &diff);
+ RefPtr<Substitutions> outerSubst = outer ? outer->SubstituteImpl(subst, &diff) : nullptr;
RefPtr<Val> newSourceType;
if (sourceType)
newSourceType = sourceType->SubstituteImpl(subst, &diff);
@@ -1244,9 +1242,36 @@ void Type::accept(IValVisitor* visitor, void* extra)
return false;
}
- RefPtr<Substitutions> GlobalGenericParamSubstitution::SubstituteImpl(Substitutions* /*subst*/, int* /*ioDiff*/)
+ RefPtr<Substitutions> GlobalGenericParamSubstitution::SubstituteImpl(Substitutions* subst, int* ioDiff)
{
- // we will never replace values for this type of substitution
+ // if we find a GlobalGenericParamSubstitution in subst that references the same __generic_param decl
+ // return a copy of that GlobalGenericParamSubstitution
+ int diff = 0;
+ RefPtr<Substitutions> outerSubst = outer ? outer->SubstituteImpl(subst, &diff) : nullptr;
+ while (subst)
+ {
+ if (auto gSubst = dynamic_cast<GlobalGenericParamSubstitution*>(subst))
+ {
+ if (gSubst->paramDecl == paramDecl)
+ {
+ // substitute only if we are really different
+ if (!gSubst->actualType->EqualsVal(actualType))
+ {
+ RefPtr<GlobalGenericParamSubstitution> rs = new GlobalGenericParamSubstitution(*gSubst);
+ rs->outer = outerSubst;
+ return rs;
+ }
+ }
+ }
+ subst = subst->outer;
+ }
+ if (diff)
+ {
+ *ioDiff++;
+ RefPtr<GlobalGenericParamSubstitution> rs = new GlobalGenericParamSubstitution(*this);
+ rs->outer = outerSubst;
+ return rs;
+ }
return this;
}
@@ -1322,8 +1347,9 @@ void Type::accept(IValVisitor* visitor, void* extra)
}
return false;
}
- void insertGlobalGenericSubstitutions(RefPtr<Substitutions> & destSubst, Substitutions * srcSubst)
+ void insertGlobalGenericSubstitutions(RefPtr<Substitutions> & destSubst, Substitutions * srcSubst, int * ioDiff)
{
+ int diff = 0;
while (srcSubst)
{
if (auto globalGenSubst = dynamic_cast<GlobalGenericParamSubstitution*>(srcSubst))
@@ -1333,19 +1359,18 @@ void Type::accept(IValVisitor* visitor, void* extra)
RefPtr<GlobalGenericParamSubstitution> cpyGlobalGenSubst = new GlobalGenericParamSubstitution(*globalGenSubst);
cpyGlobalGenSubst->outer = nullptr;
insertSubstAtBottom(destSubst, cpyGlobalGenSubst);
+ diff = 1;
}
}
srcSubst = srcSubst->outer;
}
+ *ioDiff += diff;
}
DeclRefBase DeclRefBase::SubstituteImpl(Substitutions* subst, int* ioDiff)
{
- insertGlobalGenericSubstitutions(substitutions, subst);
- if (!substitutions) return *this;
-
int diff = 0;
- RefPtr<Substitutions> substSubst = substitutions->SubstituteImpl(subst, &diff);
+ RefPtr<Substitutions> substSubst = substituteSubstitutions(substitutions, subst, &diff);
if (!diff)
return *this;
@@ -1841,6 +1866,16 @@ void Type::accept(IValVisitor* visitor, void* extra)
return nullptr;
}
+ RefPtr<Substitutions> substituteSubstitutions(RefPtr<Substitutions> oldSubst, Substitutions * subst, int * ioDiff)
+ {
+ if (oldSubst)
+ oldSubst = oldSubst->SubstituteImpl(subst, ioDiff);
+
+ RefPtr<Substitutions> newSubst = oldSubst;
+ insertGlobalGenericSubstitutions(newSubst, subst, ioDiff);
+ return newSubst;
+ }
+
// FilteredTupleType
String FilteredTupleType::ToString()