Skip to content

Commit e65dfc8

Browse files
authored
Merge pull request swiftlang#25221 from rjmccall/function-builders
Preliminary support for function builders
2 parents 2df3652 + b4cdbc0 commit e65dfc8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2330
-147
lines changed

include/swift/AST/ASTTypeIDs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct PropertyWrapperTypeInfo;
2727
class Type;
2828
class VarDecl;
2929
class TypeAliasDecl;
30+
class Type;
3031

3132
#define SWIFT_AST_TYPEID_ZONE 1
3233

include/swift/AST/Attr.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@ SIMPLE_DECL_ATTR(_propertyWrapper, PropertyWrapper,
407407
SIMPLE_DECL_ATTR(_disfavoredOverload, DisfavoredOverload,
408408
OnAbstractFunction | OnVar | OnSubscript | UserInaccessible,
409409
87)
410+
SIMPLE_DECL_ATTR(_functionBuilder, FunctionBuilder,
411+
OnNominalType,
412+
88)
410413

411414
SIMPLE_DECL_ATTR(IBSegueAction, IBSegueAction,
412415
OnFunc,

include/swift/AST/Decl.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2709,6 +2709,14 @@ class ValueDecl : public Decl {
27092709
/// `this` must be of a decl type that supports opaque return types, and
27102710
/// must not have previously had an opaque result type set.
27112711
void setOpaqueResultTypeDecl(OpaqueTypeDecl *D);
2712+
2713+
/// Retrieve the attribute associating this declaration with a
2714+
/// function builder, if there is one.
2715+
CustomAttr *getAttachedFunctionBuilder() const;
2716+
2717+
/// Retrieve the @functionBuilder type attached to this declaration,
2718+
/// if there is one.
2719+
Type getFunctionBuilderType() const;
27122720
};
27132721

27142722
/// This is a common base class for declarations which declare a type.
@@ -5334,7 +5342,7 @@ class ParamDecl : public VarDecl {
53345342
assert(isVariadic());
53355343
return getVarargBaseTy(getInterfaceType());
53365344
}
5337-
5345+
53385346
SourceRange getSourceRange() const;
53395347

53405348
AnyFunctionType::Param toFunctionParam(Type type = Type()) const;

include/swift/AST/DiagnosticsSema.def

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4463,6 +4463,44 @@ ERROR(property_wrapper_type_not_usable_from_inline,none,
44634463
"must be '@usableFromInline' or public",
44644464
(bool, bool))
44654465

4466+
//------------------------------------------------------------------------------
4467+
// MARK: function builder diagnostics
4468+
//------------------------------------------------------------------------------
4469+
ERROR(function_builder_decl, none,
4470+
"closure containing a declaration cannot be used with function "
4471+
"builder %0", (DeclName))
4472+
NOTE(note_function_builder_decl, none,
4473+
"closure containing a declaration cannot be used with function "
4474+
"builder %0", (DeclName))
4475+
ERROR(function_builder_control_flow, none,
4476+
"closure containing control flow statement cannot be used with function "
4477+
"builder %0", (DeclName))
4478+
NOTE(note_function_builder_control_flow, none,
4479+
"closure containing control flow statement cannot be used with function "
4480+
"builder %0", (DeclName))
4481+
ERROR(function_builder_attribute_not_allowed_here, none,
4482+
"function builder attribute %0 can only be applied to a parameter, "
4483+
"function, or computed property", (DeclName))
4484+
ERROR(function_builder_attribute_on_storage_without_getter, none,
4485+
"function builder attribute %0 can only be applied to a "
4486+
"%select{subscript|property|constant|variable}1 if it defines a getter",
4487+
(DeclName, unsigned))
4488+
ERROR(function_builder_parameter_not_of_function_type, none,
4489+
"function builder attribute %0 can only be applied to a parameter of "
4490+
"function type",
4491+
(DeclName))
4492+
ERROR(function_builder_parameter_autoclosure, none,
4493+
"function builder attribute %0 cannot be applied to an autoclosure "
4494+
"parameter",
4495+
(DeclName))
4496+
ERROR(function_builder_multiple, none,
4497+
"only one function builder attribute can be attached to a "
4498+
"%select{declaration|parameter}0", (bool))
4499+
NOTE(previous_function_builder_here, none,
4500+
"previous function builder specified here", ())
4501+
ERROR(function_builder_arguments, none,
4502+
"function builder attributes cannot have arguments", ())
4503+
44664504
#ifndef DIAG_NO_UNDEF
44674505
# if defined(DIAG)
44684506
# undef DIAG

include/swift/AST/KnownIdentifiers.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ IDENTIFIER(Any)
3131
IDENTIFIER(ArrayLiteralElement)
3232
IDENTIFIER(atIndexedSubscript)
3333
IDENTIFIER_(bridgeToObjectiveC)
34+
IDENTIFIER(buildBlock)
35+
IDENTIFIER(buildDo)
36+
IDENTIFIER(buildEither)
37+
IDENTIFIER(buildIf)
3438
IDENTIFIER(Change)
3539
IDENTIFIER_WITH_NAME(code_, "_code")
3640
IDENTIFIER(CodingKeys)
@@ -59,6 +63,7 @@ IDENTIFIER(Encoder)
5963
IDENTIFIER(encoder)
6064
IDENTIFIER(error)
6165
IDENTIFIER(errorDomain)
66+
IDENTIFIER(first)
6267
IDENTIFIER(forKeyedSubscript)
6368
IDENTIFIER(Foundation)
6469
IDENTIFIER(for)
@@ -93,6 +98,7 @@ IDENTIFIER(parameter)
9398
IDENTIFIER(Protocol)
9499
IDENTIFIER(rawValue)
95100
IDENTIFIER(RawValue)
101+
IDENTIFIER(second)
96102
IDENTIFIER(Selector)
97103
IDENTIFIER(self)
98104
IDENTIFIER(Self)

include/swift/AST/TypeCheckRequests.h

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class RequirementRepr;
3535
class SpecializeAttr;
3636
class TypeAliasDecl;
3737
struct TypeLoc;
38+
class ValueDecl;
3839

3940
/// Display a nominal type or extension thereof.
4041
void simple_display(
@@ -622,6 +623,57 @@ class StructuralTypeRequest :
622623
bool isCached() const { return true; }
623624
};
624625

626+
/// Request the custom attribute which attaches a function builder to the
627+
/// given declaration.
628+
class AttachedFunctionBuilderRequest :
629+
public SimpleRequest<AttachedFunctionBuilderRequest,
630+
CacheKind::Cached,
631+
CustomAttr *,
632+
ValueDecl *> {
633+
public:
634+
using SimpleRequest::SimpleRequest;
635+
636+
private:
637+
friend SimpleRequest;
638+
639+
// Evaluation.
640+
llvm::Expected<CustomAttr *>
641+
evaluate(Evaluator &evaluator, ValueDecl *decl) const;
642+
643+
public:
644+
// Caching
645+
bool isCached() const;
646+
647+
// Cycle handling
648+
void diagnoseCycle(DiagnosticEngine &diags) const;
649+
void noteCycleStep(DiagnosticEngine &diags) const;
650+
};
651+
652+
/// Request the function builder type attached to the given declaration,
653+
/// if any.
654+
class FunctionBuilderTypeRequest :
655+
public SimpleRequest<FunctionBuilderTypeRequest,
656+
CacheKind::Cached,
657+
Type,
658+
ValueDecl *> {
659+
public:
660+
using SimpleRequest::SimpleRequest;
661+
662+
private:
663+
friend SimpleRequest;
664+
665+
llvm::Expected<Type>
666+
evaluate(Evaluator &evaluator, ValueDecl *decl) const;
667+
668+
public:
669+
// Caching
670+
bool isCached() const { return true; }
671+
672+
// Cycle handling
673+
void diagnoseCycle(DiagnosticEngine &diags) const;
674+
void noteCycleStep(DiagnosticEngine &diags) const;
675+
};
676+
625677
// Allow AnyValue to compare two Type values, even though Type doesn't
626678
// support ==.
627679
template<>
@@ -631,7 +683,7 @@ inline bool AnyValue::Holder<Type>::equals(const HolderBase &other) const {
631683
static_cast<const Holder<Type> &>(other).value.getPointer();
632684
}
633685

634-
void simple_display(llvm::raw_ostream &out, const Type &type);
686+
void simple_display(llvm::raw_ostream &out, Type value);
635687

636688
/// The zone number for the type checker.
637689
#define SWIFT_TYPE_CHECKER_REQUESTS_TYPEID_ZONE 10

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@ SWIFT_TYPEID(AttachedPropertyWrapperRequest)
3333
SWIFT_TYPEID(AttachedPropertyWrapperTypeRequest)
3434
SWIFT_TYPEID(PropertyWrapperBackingPropertyTypeRequest)
3535
SWIFT_TYPEID(PropertyWrapperBackingPropertyInfoRequest)
36+
SWIFT_TYPEID(AttachedFunctionBuilderRequest)
37+
SWIFT_TYPEID(FunctionBuilderTypeRequest)

include/swift/AST/Types.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,12 +3113,32 @@ BEGIN_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType)
31133113
}
31143114
END_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType)
31153115

3116-
/// Map the given parameter list onto a bitvector describing whether
3117-
/// the argument type at each index has a default argument associated with
3118-
/// it.
3119-
SmallBitVector
3120-
computeDefaultMap(ArrayRef<AnyFunctionType::Param> params,
3121-
const ValueDecl *paramOwner, bool skipCurriedSelf);
3116+
/// Provides information about the parameter list of a given declaration, including whether each parameter
3117+
/// has a default argument.
3118+
struct ParameterListInfo {
3119+
SmallBitVector defaultArguments;
3120+
std::vector<Type> functionBuilderTypes;
3121+
3122+
public:
3123+
ParameterListInfo() { }
3124+
3125+
ParameterListInfo(ArrayRef<AnyFunctionType::Param> params,
3126+
const ValueDecl *paramOwner, bool skipCurriedSelf);
3127+
3128+
/// Whether the parameter at the given index has a default argument.
3129+
bool hasDefaultArgument(unsigned paramIdx) const;
3130+
3131+
/// Retrieve the number of non-defaulted parameters.
3132+
unsigned numNonDefaultedParameters() const {
3133+
return defaultArguments.count();
3134+
}
3135+
3136+
/// Retrieve the number of parameters for which we have information.
3137+
unsigned size() const { return defaultArguments.size(); }
3138+
3139+
/// Retrieve the function builder type for the given parameter.
3140+
Type getFunctionBuilderType(unsigned paramIdx) const;
3141+
};
31223142

31233143
/// Turn a param list into a symbolic and printable representation that does not
31243144
/// include the types, something like (: , b:, c:)

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class CodeCompletionCallbacks {
116116
};
117117

118118
/// Set target decl for attribute if the CC token is in attribute of the decl.
119-
virtual void setAttrTargetDecl(Decl *D) {}
119+
virtual void setAttrTargetDeclKind(Optional<DeclKind> DK) {}
120120

121121
/// Complete the whole expression. This is a fallback that should
122122
/// produce results when more specific completion methods failed.

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2590,6 +2590,7 @@ void PrintAST::printOneParameter(const ParamDecl *param,
25902590

25912591
auto TheTypeLoc = param->getTypeLoc();
25922592

2593+
printAttributes(param);
25932594
printArgName();
25942595

25952596
if (!TheTypeLoc.getTypeRepr() && param->hasInterfaceType())

0 commit comments

Comments
 (0)