From ddd29057e48a5b309726750e3daf78bfd073038e Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 4 Sep 2024 13:25:37 -0700 Subject: 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. --- source/slang/slang-check-constraint.cpp | 40 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'source/slang/slang-check-constraint.cpp') 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. -- cgit v1.2.3