@@ -2770,11 +2770,22 @@ std::vector<ReturnStmt *> TypeChecker::findReturnStatements(AnyFunctionRef fn) {
2770
2770
return precheck.getReturnStmts ();
2771
2771
}
2772
2772
2773
- bool TypeChecker::typeSupportsBuilderOp (
2773
+ ResultBuilderOpSupport TypeChecker::checkBuilderOpSupport (
2774
2774
Type builderType, DeclContext *dc, Identifier fnName,
2775
- ArrayRef<Identifier> argLabels, SmallVectorImpl<ValueDecl *> *allResults,
2776
- bool checkAvailability) {
2775
+ ArrayRef<Identifier> argLabels, SmallVectorImpl<ValueDecl *> *allResults) {
2776
+
2777
+ auto isUnavailable = [&](Decl *D) -> bool {
2778
+ if (AvailableAttr::isUnavailable (D))
2779
+ return true ;
2780
+
2781
+ auto loc = extractNearestSourceLoc (dc);
2782
+ auto context = ExportContext::forFunctionBody (dc, loc);
2783
+ return TypeChecker::checkDeclarationAvailability (D, context).hasValue ();
2784
+ };
2785
+
2777
2786
bool foundMatch = false ;
2787
+ bool foundUnavailable = false ;
2788
+
2778
2789
SmallVector<ValueDecl *, 4 > foundDecls;
2779
2790
dc->lookupQualified (
2780
2791
builderType, DeclNameRef (fnName),
@@ -2793,17 +2804,12 @@ bool TypeChecker::typeSupportsBuilderOp(
2793
2804
continue ;
2794
2805
}
2795
2806
2796
- // If we are checking availability, the candidate must have enough
2797
- // availability in the calling context.
2798
- if (checkAvailability) {
2799
- if (AvailableAttr::isUnavailable (func))
2800
- continue ;
2801
- if (TypeChecker::checkDeclarationAvailability (
2802
- func, ExportContext::forFunctionBody (
2803
- dc, extractNearestSourceLoc (dc))))
2804
- continue ;
2807
+ // Check if the the candidate has a suitable availability for the
2808
+ // calling context.
2809
+ if (isUnavailable (func)) {
2810
+ foundUnavailable = true ;
2811
+ continue ;
2805
2812
}
2806
-
2807
2813
foundMatch = true ;
2808
2814
break ;
2809
2815
}
@@ -2812,7 +2818,18 @@ bool TypeChecker::typeSupportsBuilderOp(
2812
2818
if (allResults)
2813
2819
allResults->append (foundDecls.begin (), foundDecls.end ());
2814
2820
2815
- return foundMatch;
2821
+ if (!foundMatch) {
2822
+ return foundUnavailable ? ResultBuilderOpSupport::Unavailable
2823
+ : ResultBuilderOpSupport::Unsupported;
2824
+ }
2825
+ return ResultBuilderOpSupport::Supported;
2826
+ }
2827
+
2828
+ bool TypeChecker::typeSupportsBuilderOp (
2829
+ Type builderType, DeclContext *dc, Identifier fnName,
2830
+ ArrayRef<Identifier> argLabels, SmallVectorImpl<ValueDecl *> *allResults) {
2831
+ return checkBuilderOpSupport (builderType, dc, fnName, argLabels, allResults)
2832
+ .isSupported (/* requireAvailable*/ false );
2816
2833
}
2817
2834
2818
2835
Type swift::inferResultBuilderComponentType (NominalTypeDecl *builder) {
@@ -2976,13 +2993,13 @@ bool ResultBuilder::supports(Identifier fnBaseName,
2976
2993
bool checkAvailability) {
2977
2994
DeclName name (DC->getASTContext (), fnBaseName, argLabels);
2978
2995
auto known = SupportedOps.find (name);
2979
- if (known != SupportedOps.end ()) {
2980
- return known->second ;
2981
- }
2996
+ if (known != SupportedOps.end ())
2997
+ return known->second .isSupported (checkAvailability);
2982
2998
2983
- return SupportedOps[name] = TypeChecker::typeSupportsBuilderOp (
2984
- BuilderType, DC, fnBaseName, argLabels, /* allResults*/ {},
2985
- checkAvailability);
2999
+ auto support = TypeChecker::checkBuilderOpSupport (
3000
+ BuilderType, DC, fnBaseName, argLabels, /* allResults*/ {});
3001
+ SupportedOps.insert ({name, support});
3002
+ return support.isSupported (checkAvailability);
2986
3003
}
2987
3004
2988
3005
Expr *ResultBuilder::buildCall (SourceLoc loc, Identifier fnName,
0 commit comments