diff options
Diffstat (limited to 'source/slang/slang-check-conformance.cpp')
| -rw-r--r-- | source/slang/slang-check-conformance.cpp | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/source/slang/slang-check-conformance.cpp b/source/slang/slang-check-conformance.cpp index 4d54a93fb..f57e7cb38 100644 --- a/source/slang/slang-check-conformance.cpp +++ b/source/slang/slang-check-conformance.cpp @@ -18,15 +18,15 @@ namespace Slang } RefPtr<Val> SemanticsVisitor::createTypeWitness( - RefPtr<Type> type, - DeclRef<InterfaceDecl> interfaceDeclRef, + RefPtr<Type> subType, + DeclRef<AggTypeDecl> superTypeDeclRef, TypeWitnessBreadcrumb* inBreadcrumbs) { if(!inBreadcrumbs) { // We need to construct a witness to the fact - // that `type` has been proven to be *equal* - // to `interfaceDeclRef`. + // that `subType` has been proven to be *equal* + // to `superTypeDeclRef`. // SLANG_UNEXPECTED("reflexive type witness"); UNREACHABLE_RETURN(nullptr); @@ -145,15 +145,15 @@ namespace Slang } } - bool SemanticsVisitor::doesTypeConformToInterfaceImpl( - RefPtr<Type> originalType, - RefPtr<Type> type, - DeclRef<InterfaceDecl> interfaceDeclRef, + bool SemanticsVisitor::_isDeclaredSubtype( + RefPtr<Type> originalSubType, + RefPtr<Type> subType, + DeclRef<AggTypeDecl> superTypeDeclRef, RefPtr<Val>* outWitness, TypeWitnessBreadcrumb* inBreadcrumbs) { // for now look up a conformance member... - if(auto declRefType = as<DeclRefType>(type)) + if(auto declRefType = as<DeclRefType>(subType)) { auto declRef = declRefType->declRef; @@ -162,11 +162,11 @@ namespace Slang // TODO: This is actually a bit more complicated, as // the interface needs to be "object-safe" for us to // really make this determination... - if(declRef == interfaceDeclRef) + if(declRef == superTypeDeclRef) { if(outWitness) { - *outWitness = createTypeWitness(originalType, interfaceDeclRef, inBreadcrumbs); + *outWitness = createTypeWitness(originalSubType, superTypeDeclRef, inBreadcrumbs); } return true; } @@ -198,11 +198,11 @@ namespace Slang TypeWitnessBreadcrumb breadcrumb; breadcrumb.prev = inBreadcrumbs; - breadcrumb.sub = type; + breadcrumb.sub = subType; breadcrumb.sup = inheritedType; breadcrumb.declRef = inheritanceDeclRef; - if(doesTypeConformToInterfaceImpl(originalType, inheritedType, interfaceDeclRef, outWitness, &breadcrumb)) + if(_isDeclaredSubtype(originalSubType, inheritedType, superTypeDeclRef, outWitness, &breadcrumb)) { return true; } @@ -214,10 +214,10 @@ namespace Slang auto inheritedType = getSup(m_astBuilder, genConstraintDeclRef); TypeWitnessBreadcrumb breadcrumb; breadcrumb.prev = inBreadcrumbs; - breadcrumb.sub = type; + breadcrumb.sub = subType; breadcrumb.sup = inheritedType; breadcrumb.declRef = genConstraintDeclRef; - if (doesTypeConformToInterfaceImpl(originalType, inheritedType, interfaceDeclRef, outWitness, &breadcrumb)) + if (_isDeclaredSubtype(originalSubType, inheritedType, superTypeDeclRef, outWitness, &breadcrumb)) { return true; } @@ -252,14 +252,14 @@ namespace Slang breadcrumb.sup = sup; breadcrumb.declRef = constraintDeclRef; - if(doesTypeConformToInterfaceImpl(originalType, sup, interfaceDeclRef, outWitness, &breadcrumb)) + if(_isDeclaredSubtype(originalSubType, sup, superTypeDeclRef, outWitness, &breadcrumb)) { return true; } } } } - else if(auto taggedUnionType = as<TaggedUnionType>(type)) + else if(auto taggedUnionType = as<TaggedUnionType>(subType)) { // A tagged union type conforms to an interface if all of // the constituent types in the tagged union conform. @@ -276,10 +276,10 @@ namespace Slang { RefPtr<Val> caseWitness; - if(!doesTypeConformToInterfaceImpl( + if(!_isDeclaredSubtype( caseType, caseType, - interfaceDeclRef, + superTypeDeclRef, outWitness ? &caseWitness : nullptr, nullptr)) { @@ -304,8 +304,11 @@ namespace Slang // We will start out being conservative about what we accept // here, just to keep things simple. // - if(!isInterfaceSafeForTaggedUnion(interfaceDeclRef)) - return false; + if( auto superInterfaceDeclRef = superTypeDeclRef.as<InterfaceDecl>() ) + { + if(!isInterfaceSafeForTaggedUnion(superInterfaceDeclRef)) + return false; + } // If we reach this point then we have a concrete // witness for each of the case types, and that is @@ -315,7 +318,7 @@ namespace Slang { RefPtr<TaggedUnionSubtypeWitness> taggedUnionWitness = m_astBuilder->create<TaggedUnionSubtypeWitness>(); taggedUnionWitness->sub = taggedUnionType; - taggedUnionWitness->sup = DeclRefType::create(m_astBuilder, interfaceDeclRef); + taggedUnionWitness->sup = DeclRefType::create(m_astBuilder, superTypeDeclRef); taggedUnionWitness->caseWitnesses.swapWith(caseWitnesses); *outWitness = taggedUnionWitness; @@ -327,22 +330,30 @@ namespace Slang return false; } - bool SemanticsVisitor::DoesTypeConformToInterface( - RefPtr<Type> type, - DeclRef<InterfaceDecl> interfaceDeclRef) + bool SemanticsVisitor::isDeclaredSubtype( + RefPtr<Type> subType, + DeclRef<AggTypeDecl> superTypeDeclRef) { - return doesTypeConformToInterfaceImpl(type, type, interfaceDeclRef, nullptr, nullptr); + return _isDeclaredSubtype(subType, subType, superTypeDeclRef, nullptr, nullptr); } - RefPtr<Val> SemanticsVisitor::tryGetInterfaceConformanceWitness( - RefPtr<Type> type, - DeclRef<InterfaceDecl> interfaceDeclRef) + RefPtr<Val> SemanticsVisitor::tryGetSubtypeWitness( + RefPtr<Type> subType, + DeclRef<AggTypeDecl> superTypeDeclRef) { RefPtr<Val> result; - doesTypeConformToInterfaceImpl(type, type, interfaceDeclRef, &result, nullptr); + _isDeclaredSubtype(subType, subType, superTypeDeclRef, &result, nullptr); return result; } + + RefPtr<Val> SemanticsVisitor::tryGetInterfaceConformanceWitness( + RefPtr<Type> type, + DeclRef<InterfaceDecl> interfaceDeclRef) + { + return tryGetSubtypeWitness(type, interfaceDeclRef); + } + RefPtr<Val> SemanticsVisitor::createTypeEqualityWitness( Type* type) { |
