diff options
| author | Yong He <yonghe@outlook.com> | 2024-09-04 13:25:37 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-04 13:25:37 -0700 |
| commit | ddd29057e48a5b309726750e3daf78bfd073038e (patch) | |
| tree | a054b99acb87d61ef4818dce5fa837ccfd050288 /source/slang/slang-check-constraint.cpp | |
| parent | 56a3c028a6725e13a2ae3a724eaee05ad9f4802a (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.cpp | 40 |
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. |
