|
30 | 30 |
|
31 | 31 | using namespace swift;
|
32 | 32 |
|
33 |
| -/// |
34 |
| -/// Common code for generic functions, generic types |
35 |
| -/// |
36 |
| - |
37 |
| -std::string |
38 |
| -TypeChecker::gatherGenericParamBindingsText( |
39 |
| - ArrayRef<Type> types, |
40 |
| - TypeArrayView<GenericTypeParamType> genericParams, |
41 |
| - TypeSubstitutionFn substitutions) { |
42 |
| - llvm::SmallPtrSet<GenericTypeParamType *, 2> knownGenericParams; |
43 |
| - for (auto type : types) { |
44 |
| - if (type.isNull()) continue; |
45 |
| - |
46 |
| - type.visit([&](Type type) { |
47 |
| - if (auto gp = type->getAs<GenericTypeParamType>()) { |
48 |
| - knownGenericParams.insert( |
49 |
| - gp->getCanonicalType()->castTo<GenericTypeParamType>()); |
50 |
| - } |
51 |
| - }); |
52 |
| - } |
53 |
| - |
54 |
| - if (knownGenericParams.empty()) |
55 |
| - return ""; |
56 |
| - |
57 |
| - SmallString<128> result; |
58 |
| - for (auto gp : genericParams) { |
59 |
| - auto canonGP = gp->getCanonicalType()->castTo<GenericTypeParamType>(); |
60 |
| - if (!knownGenericParams.count(canonGP)) |
61 |
| - continue; |
62 |
| - |
63 |
| - if (result.empty()) |
64 |
| - result += " [with "; |
65 |
| - else |
66 |
| - result += ", "; |
67 |
| - result += gp->getName().str(); |
68 |
| - result += " = "; |
69 |
| - |
70 |
| - auto type = substitutions(canonGP); |
71 |
| - if (!type) |
72 |
| - return ""; |
73 |
| - |
74 |
| - result += type.getString(); |
75 |
| - } |
76 |
| - |
77 |
| - result += "]"; |
78 |
| - return result.str().str(); |
79 |
| -} |
80 |
| - |
81 |
| - |
82 | 33 | //
|
83 | 34 | // Generic functions
|
84 | 35 | //
|
@@ -817,6 +768,61 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
|
817 | 768 | /// Checking bound generic type arguments
|
818 | 769 | ///
|
819 | 770 |
|
| 771 | +/// Create a text string that describes the bindings of generic parameters |
| 772 | +/// that are relevant to the given set of types, e.g., |
| 773 | +/// "[with T = Bar, U = Wibble]". |
| 774 | +/// |
| 775 | +/// \param types The types that will be scanned for generic type parameters, |
| 776 | +/// which will be used in the resulting type. |
| 777 | +/// |
| 778 | +/// \param genericParams The generic parameters to use to resugar any |
| 779 | +/// generic parameters that occur within the types. |
| 780 | +/// |
| 781 | +/// \param substitutions The generic parameter -> generic argument |
| 782 | +/// substitutions that will have been applied to these types. |
| 783 | +/// These are used to produce the "parameter = argument" bindings in the test. |
| 784 | +static std::string gatherGenericParamBindingsText( |
| 785 | + ArrayRef<Type> types, TypeArrayView<GenericTypeParamType> genericParams, |
| 786 | + TypeSubstitutionFn substitutions) { |
| 787 | + llvm::SmallPtrSet<GenericTypeParamType *, 2> knownGenericParams; |
| 788 | + for (auto type : types) { |
| 789 | + if (type.isNull()) continue; |
| 790 | + |
| 791 | + type.visit([&](Type type) { |
| 792 | + if (auto gp = type->getAs<GenericTypeParamType>()) { |
| 793 | + knownGenericParams.insert( |
| 794 | + gp->getCanonicalType()->castTo<GenericTypeParamType>()); |
| 795 | + } |
| 796 | + }); |
| 797 | + } |
| 798 | + |
| 799 | + if (knownGenericParams.empty()) |
| 800 | + return ""; |
| 801 | + |
| 802 | + SmallString<128> result; |
| 803 | + for (auto gp : genericParams) { |
| 804 | + auto canonGP = gp->getCanonicalType()->castTo<GenericTypeParamType>(); |
| 805 | + if (!knownGenericParams.count(canonGP)) |
| 806 | + continue; |
| 807 | + |
| 808 | + if (result.empty()) |
| 809 | + result += " [with "; |
| 810 | + else |
| 811 | + result += ", "; |
| 812 | + result += gp->getName().str(); |
| 813 | + result += " = "; |
| 814 | + |
| 815 | + auto type = substitutions(canonGP); |
| 816 | + if (!type) |
| 817 | + return ""; |
| 818 | + |
| 819 | + result += type.getString(); |
| 820 | + } |
| 821 | + |
| 822 | + result += "]"; |
| 823 | + return result.str().str(); |
| 824 | +} |
| 825 | + |
820 | 826 | void TypeChecker::diagnoseRequirementFailure(
|
821 | 827 | const CheckGenericArgumentsResult::RequirementFailureInfo &reqFailureInfo,
|
822 | 828 | SourceLoc errorLoc, SourceLoc noteLoc, Type targetTy,
|
@@ -871,9 +877,8 @@ void TypeChecker::diagnoseRequirementFailure(
|
871 | 877 | ctx.Diags.diagnose(errorLoc, diagnostic, targetTy, substReq.getFirstType(),
|
872 | 878 | substSecondTy);
|
873 | 879 |
|
874 |
| - const auto genericParamBindingsText = |
875 |
| - TypeChecker::gatherGenericParamBindingsText( |
876 |
| - {req.getFirstType(), secondTy}, genericParams, substitutions); |
| 880 | + const auto genericParamBindingsText = gatherGenericParamBindingsText( |
| 881 | + {req.getFirstType(), secondTy}, genericParams, substitutions); |
877 | 882 |
|
878 | 883 | ctx.Diags.diagnose(noteLoc, diagnosticNote, req.getFirstType(), secondTy,
|
879 | 884 | genericParamBindingsText);
|
|
0 commit comments