From d33e6b7475a87d5a62101afc81813e9c9e458a70 Mon Sep 17 00:00:00 2001 From: Yong He Date: Sun, 14 Jan 2018 16:22:11 -0500 Subject: allow extension of a concrete type to implement additional interface Also support the scenario that the extension declares conformance to interface I, and a method M in I is already supported by the base implementation. --- source/slang/check.cpp | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'source/slang/check.cpp') diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 6c484b493..6b8331060 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -1794,7 +1794,7 @@ namespace Slang // `requiredMemberDeclRef` is a required member of // the interface. RefPtr findWitnessForInterfaceRequirement( - DeclRef typeDeclRef, + DeclRef typeDeclRef, InheritanceDecl* inheritanceDecl, DeclRef interfaceDeclRef, DeclRef requiredMemberDeclRef, @@ -1833,11 +1833,9 @@ namespace Slang // Make sure that by-name lookup is possible. buildMemberDictionary(typeDeclRef.getDecl()); - - Decl* firstMemberOfName = nullptr; - typeDeclRef.getDecl()->memberDictionary.TryGetValue(name, firstMemberOfName); - - if (!firstMemberOfName) + auto lookupResult = lookUpLocal(getSession(), this, name, typeDeclRef); + + if (!lookupResult.isValid()) { getSink()->diagnose(inheritanceDecl, Diagnostics::typeDoesntImplementInterfaceRequirement, typeDeclRef, requiredMemberDeclRef); return nullptr; @@ -1845,10 +1843,10 @@ namespace Slang // Iterate over the members and look for one that matches // the expected signature for the requirement. - for (auto memberDecl = firstMemberOfName; memberDecl; memberDecl = memberDecl->nextInContainerWithSameName) + for (auto member : lookupResult) { - if (doesMemberSatisfyRequirement(DeclRef(memberDecl, typeDeclRef.substitutions), requiredMemberDeclRef, requirementWitness)) - return memberDecl; + if (doesMemberSatisfyRequirement(member.declRef, requiredMemberDeclRef, requirementWitness)) + return member.declRef.getDecl(); } // No suitable member found, although there were candidates. @@ -1867,7 +1865,7 @@ namespace Slang // (via the given `inheritanceDecl`) actually provides // members to satisfy all the requirements in the interface. bool checkInterfaceConformance( - DeclRef typeDeclRef, + DeclRef typeDeclRef, InheritanceDecl* inheritanceDecl, DeclRef interfaceDeclRef) { @@ -1925,7 +1923,7 @@ namespace Slang } bool checkConformanceToType( - DeclRef typeDeclRef, + DeclRef typeDeclRef, InheritanceDecl* inheritanceDecl, Type* baseType) { @@ -1953,7 +1951,7 @@ namespace Slang // `inheritanceDecl` actually does what it needs to // for that inheritance to be valid. bool checkConformance( - DeclRef typeDecl, + DeclRef typeDecl, InheritanceDecl* inheritanceDecl) { // Look at the type being inherited from, and validate @@ -1963,10 +1961,10 @@ namespace Slang } bool checkConformance( - AggTypeDecl* typeDecl, + AggTypeDeclBase* typeDecl, InheritanceDecl* inheritanceDecl) { - return checkConformance(DeclRef(typeDecl, SubstitutionSet()), inheritanceDecl); + return checkConformance(DeclRef(typeDecl, SubstitutionSet()), inheritanceDecl); } void visitAggTypeDecl(AggTypeDecl* decl) @@ -3479,10 +3477,11 @@ namespace Slang // TODO: need to check that the target type names a declaration... + DeclRef aggTypeDeclRef; if (auto targetDeclRefType = decl->targetType->As()) { // Attach our extension to that type as a candidate... - if (auto aggTypeDeclRef = targetDeclRefType->declRef.As()) + if (aggTypeDeclRef = targetDeclRefType->declRef.As()) { auto aggTypeDecl = aggTypeDeclRef.getDecl(); decl->nextCandidateExtension = aggTypeDecl->candidateExtensions; @@ -3516,6 +3515,14 @@ namespace Slang EnsureDecl(m); } + if (aggTypeDeclRef) + { + for (auto inheritanceDecl : decl->getMembersOfType()) + { + checkConformance(aggTypeDeclRef.getDecl(), inheritanceDecl); + } + } + decl->SetCheckState(DeclCheckState::Checked); } @@ -3802,7 +3809,7 @@ namespace Slang if( auto aggTypeDeclRef = declRef.As() ) { - for( auto inheritanceDeclRef : getMembersOfType(aggTypeDeclRef)) + for( auto inheritanceDeclRef : getMembersOfTypeWithExt(aggTypeDeclRef)) { EnsureDecl(inheritanceDeclRef.getDecl()); -- cgit v1.2.3 From 436f0e7198735d118daa956d0a3bb698571c3cd7 Mon Sep 17 00:00:00 2001 From: Yong He Date: Sun, 14 Jan 2018 18:20:46 -0500 Subject: temporary workaround to fix test case failures. --- source/slang/check.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source/slang/check.cpp') diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 6b8331060..3103a7908 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -1076,8 +1076,12 @@ namespace Slang { // The user is asking for us to actually perform the conversion, // so we need to generate an appropriate expression here. - - throw "foo bar baz"; + + // YONGH: I am confused why we are not hitting this case before + //throw "foo bar baz"; + // YONGH: temporary work around, may need to create the actual + // invocation expr to the constructor call + *outToExpr = fromExpr; } return true; @@ -1848,7 +1852,7 @@ namespace Slang if (doesMemberSatisfyRequirement(member.declRef, requiredMemberDeclRef, requirementWitness)) return member.declRef.getDecl(); } - + // No suitable member found, although there were candidates. // // TODO: Eventually we might want something akin to the current -- cgit v1.2.3