summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-constraint.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-09-04 13:25:37 -0700
committerGitHub <noreply@github.com>2024-09-04 13:25:37 -0700
commitddd29057e48a5b309726750e3daf78bfd073038e (patch)
treea054b99acb87d61ef4818dce5fa837ccfd050288 /source/slang/slang-check-constraint.cpp
parent56a3c028a6725e13a2ae3a724eaee05ad9f4802a (diff)
Fix extension override behavior, and disallow extension on interface types. (#4977)
* Add a test to ensure extension does not override existing conformance. * Fix doc. * Update documentation. * Fix doc. * Add diagnostic test.
Diffstat (limited to 'source/slang/slang-check-constraint.cpp')
-rw-r--r--source/slang/slang-check-constraint.cpp40
1 files changed, 25 insertions, 15 deletions
diff --git a/source/slang/slang-check-constraint.cpp b/source/slang/slang-check-constraint.cpp
index e5551a875..3e3ed5297 100644
--- a/source/slang/slang-check-constraint.cpp
+++ b/source/slang/slang-check-constraint.cpp
@@ -83,16 +83,22 @@ namespace Slang
Type* interfaceType)
{
// The most basic test here should be: does the type declare conformance to the trait.
- if (isSubtype(type, interfaceType, constraints->additionalSubtypeWitnesses ? IsSubTypeOptions::NoCaching : IsSubTypeOptions::None))
- return type;
-
- // If additional subtype witnesses are provided for `type` in `constraints`,
- // try to use them to see if the interface is satisfied.
+
if (constraints->subTypeForAdditionalWitnesses == type)
{
+ // If additional subtype witnesses are provided for `type` in `constraints`,
+ // try to use them to see if the interface is satisfied.
if (constraints->additionalSubtypeWitnesses->containsKey(interfaceType))
return type;
}
+ else
+ {
+ if (isSubtype(
+ type,
+ interfaceType,
+ constraints->additionalSubtypeWitnesses ? IsSubTypeOptions::NoCaching : IsSubTypeOptions::None))
+ return type;
+ }
// Just because `type` doesn't conform to the given `interfaceDeclRef`, that
// doesn't necessarily indicate a failure. It is possible that we have a call
@@ -653,18 +659,22 @@ namespace Slang
}
// Search for a witness that shows the constraint is satisfied.
- auto subTypeWitness = isSubtype(
- sub,
- sup,
- system->additionalSubtypeWitnesses ? IsSubTypeOptions::NoCaching : IsSubTypeOptions::None);
- if (!subTypeWitness)
+ SubtypeWitness* subTypeWitness = nullptr;
+ if (sub == system->subTypeForAdditionalWitnesses)
{
- if (sub == system->subTypeForAdditionalWitnesses)
- {
- // If no witness was found, try to find the witness from additional witness.
- system->additionalSubtypeWitnesses->tryGetValue(sup, subTypeWitness);
- }
+ // If we are trying to find the subtype info for a type whose inheritance info is
+ // being calculated, use what we have already known about the type.
+ system->additionalSubtypeWitnesses->tryGetValue(sup, subTypeWitness);
}
+ else
+ {
+ // The general case is to initiate a subtype query.
+ subTypeWitness = isSubtype(
+ sub,
+ sup,
+ system->additionalSubtypeWitnesses ? IsSubTypeOptions::NoCaching : IsSubTypeOptions::None);
+ }
+
if(subTypeWitness)
{
// We found a witness, so it will become an (implicit) argument.