@@ -739,23 +739,17 @@ ArrayRef<Substitution> BoundGenericType::getSubstitutions(
739
739
740
740
SmallVector<ProtocolConformanceRef, 4 > conformances;
741
741
for (auto proto : archetype->getConformsTo ()) {
742
- // If the type is a type variable or is dependent, just fill in null
742
+ // If the type is a type variable or is dependent, just fill in empty
743
743
// conformances.
744
744
if (type->is <TypeVariableType>() || type->isTypeParameter ()) {
745
745
conformances.push_back (ProtocolConformanceRef (proto));
746
746
747
747
// Otherwise, find the conformances.
748
748
} else {
749
- auto conforms = module ->lookupConformance (type, proto, resolver);
750
- switch (conforms.getInt ()) {
751
- case ConformanceKind::Conforms:
752
- conformances.push_back (
753
- ProtocolConformanceRef (proto, conforms.getPointer ()));
754
- break ;
755
- case ConformanceKind::DoesNotConform:
749
+ if (auto conforms = module ->lookupConformance (type, proto, resolver))
750
+ conformances.push_back (*conforms);
751
+ else
756
752
conformances.push_back (ProtocolConformanceRef (proto));
757
- break ;
758
- }
759
753
}
760
754
}
761
755
@@ -778,28 +772,28 @@ ArrayRef<Substitution> BoundGenericType::getSubstitutions(
778
772
return permanentSubs;
779
773
}
780
774
781
- LookupConformanceResult Module::lookupConformance (Type type,
782
- ProtocolDecl *protocol,
783
- LazyResolver *resolver) {
775
+ Optional<ProtocolConformanceRef>
776
+ Module::lookupConformance (Type type, ProtocolDecl *protocol,
777
+ LazyResolver *resolver) {
784
778
ASTContext &ctx = getASTContext ();
785
779
786
780
// An archetype conforms to a protocol if the protocol is listed in the
787
781
// archetype's list of conformances.
788
782
if (auto archetype = type->getAs <ArchetypeType>()) {
789
783
if (protocol->isSpecificProtocol (KnownProtocolKind::AnyObject)) {
790
784
if (archetype->requiresClass ())
791
- return { nullptr , ConformanceKind::Conforms };
792
- return { nullptr , ConformanceKind::DoesNotConform };
785
+ return ProtocolConformanceRef (protocol);
786
+
787
+ return None;
793
788
}
794
789
795
790
for (auto ap : archetype->getConformsTo ()) {
796
791
if (ap == protocol || ap->inheritsFrom (protocol))
797
- return { nullptr , ConformanceKind::Conforms } ;
792
+ return ProtocolConformanceRef (protocol) ;
798
793
}
799
794
800
- if (!archetype->getSuperclass ()) {
801
- return { nullptr , ConformanceKind::DoesNotConform };
802
- }
795
+ if (!archetype->getSuperclass ())
796
+ return None;
803
797
}
804
798
805
799
// An existential conforms to a protocol if the protocol is listed in the
@@ -815,74 +809,68 @@ LookupConformanceResult Module::lookupConformance(Type type,
815
809
for (auto proto : protocols) {
816
810
if (!proto->isObjC () &&
817
811
!proto->isSpecificProtocol (KnownProtocolKind::AnyObject))
818
- return { nullptr , ConformanceKind::DoesNotConform } ;
812
+ return None ;
819
813
}
820
814
821
815
// If the existential type cannot be represented or the protocol does not
822
816
// conform to itself, there's no point in looking further.
823
817
if (!protocol->existentialConformsToSelf () ||
824
818
!protocol->existentialTypeSupported (resolver))
825
- return { nullptr , ConformanceKind::DoesNotConform } ;
819
+ return None ;
826
820
827
821
// Special-case AnyObject, which may not be in the list of conformances.
828
822
if (protocol->isSpecificProtocol (KnownProtocolKind::AnyObject)) {
829
- return { nullptr , type->isClassExistentialType ()
830
- ? ConformanceKind::Conforms
831
- : ConformanceKind::DoesNotConform };
823
+ if (type->isClassExistentialType ())
824
+ return ProtocolConformanceRef (protocol);
825
+
826
+ return None;
832
827
}
833
828
834
829
// Look for this protocol within the existential's list of conformances.
835
830
for (auto proto : protocols) {
836
- if (proto == protocol || proto->inheritsFrom (protocol)) {
837
- return { nullptr , ConformanceKind::Conforms };
838
- }
831
+ if (proto == protocol || proto->inheritsFrom (protocol))
832
+ return ProtocolConformanceRef (protocol);
839
833
}
840
834
841
835
// We didn't find our protocol in the existential's list; it doesn't
842
836
// conform.
843
- return { nullptr , ConformanceKind::DoesNotConform } ;
837
+ return None ;
844
838
}
845
839
846
840
// Check for protocol conformance of archetype via superclass requirement.
847
841
if (auto archetype = type->getAs <ArchetypeType>()) {
848
842
if (auto super = archetype->getSuperclass ()) {
849
- auto inheritedConformance = lookupConformance (super, protocol, resolver);
850
- switch (inheritedConformance.getInt ()) {
851
- case ConformanceKind::DoesNotConform:
852
- return { nullptr , ConformanceKind::DoesNotConform };
853
- case ConformanceKind::Conforms:
854
- auto result =
855
- ctx.getInheritedConformance (type, inheritedConformance.getPointer ());
856
- return { result, ConformanceKind::Conforms };
843
+ if (auto inheritedConformance = lookupConformance (super, protocol,
844
+ resolver)) {
845
+ return ProtocolConformanceRef (
846
+ ctx.getInheritedConformance (
847
+ type,
848
+ inheritedConformance->getConcrete ()));
857
849
}
850
+
851
+ return None;
858
852
}
859
853
}
860
854
861
855
// UnresolvedType is a placeholder for an unknown type used when generating
862
856
// diagnostics. We consider it to conform to all protocols, since the
863
857
// intended type might have.
864
858
if (type->is <UnresolvedType>()) {
865
- return {
866
- ctx.getConformance (type, protocol, protocol->getLoc (), this ,
867
- ProtocolConformanceState::Complete),
868
- ConformanceKind::Conforms
869
- };
859
+ return ProtocolConformanceRef (
860
+ ctx.getConformance (type, protocol, protocol->getLoc (), this ,
861
+ ProtocolConformanceState::Complete));
870
862
}
871
863
872
864
873
865
auto nominal = type->getAnyNominal ();
874
866
875
867
// If we don't have a nominal type, there are no conformances.
876
- // FIXME: We may have implicit conformances for some cases. Handle those
877
- // here.
878
- if (!nominal) {
879
- return { nullptr , ConformanceKind::DoesNotConform };
880
- }
868
+ if (!nominal) return None;
881
869
882
870
// Find the (unspecialized) conformance.
883
871
SmallVector<ProtocolConformance *, 2 > conformances;
884
872
if (!nominal->lookupConformance (this , protocol, conformances))
885
- return { nullptr , ConformanceKind::DoesNotConform } ;
873
+ return None ;
886
874
887
875
// FIXME: Ambiguity resolution.
888
876
auto conformance = conformances.front ();
@@ -905,19 +893,13 @@ LookupConformanceResult Module::lookupConformance(Type type,
905
893
// Compute the conformance for the inherited type.
906
894
auto inheritedConformance = lookupConformance (superclassTy, protocol,
907
895
resolver);
908
- switch (inheritedConformance.getInt ()) {
909
- case ConformanceKind::DoesNotConform:
910
- llvm_unreachable (" We already found the inherited conformance" );
911
-
912
- case ConformanceKind::Conforms:
913
- // Create inherited conformance below.
914
- break ;
915
- }
896
+ assert (inheritedConformance &&
897
+ " We already found the inherited conformance" );
916
898
917
899
// Create the inherited conformance entry.
918
900
conformance
919
- = ctx.getInheritedConformance (type, inheritedConformance. getPointer ());
920
- return { conformance, ConformanceKind::Conforms } ;
901
+ = ctx.getInheritedConformance (type, inheritedConformance-> getConcrete ());
902
+ return ProtocolConformanceRef ( conformance) ;
921
903
}
922
904
923
905
// If the type is specialized, find the conformance for the generic type.
@@ -938,18 +920,18 @@ LookupConformanceResult Module::lookupConformance(Type type,
938
920
939
921
for (auto sub : substitutions) {
940
922
if (sub.getReplacement ()->is <ErrorType>())
941
- return { nullptr , ConformanceKind::DoesNotConform } ;
923
+ return None ;
942
924
}
943
925
944
926
// Create the specialized conformance entry.
945
927
auto result = ctx.getSpecializedConformance (type, conformance,
946
928
substitutions);
947
- return { result, ConformanceKind::Conforms } ;
929
+ return ProtocolConformanceRef ( result) ;
948
930
}
949
931
}
950
932
951
933
// Record and return the simple conformance.
952
- return { conformance, ConformanceKind::Conforms } ;
934
+ return ProtocolConformanceRef ( conformance) ;
953
935
}
954
936
955
937
namespace {
0 commit comments