Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
376a859
[Property Wrappers] Handle property wrappers on parameters in
hborla Aug 28, 2020
8325a52
[ConstraintSystem] Teach the constraint system about property wrapper
hborla Aug 26, 2020
f57180a
[Property Wrappers] Don't allow property wrapper attributes to have
hborla Oct 10, 2020
d9951be
[Property Wrappers] Add a request to synthesize the local wrapped value
hborla Oct 11, 2020
5bdb4dc
[Sema] Visit auxiliary decls on parameters in the decl checker.
hborla Oct 11, 2020
c5bed94
[SILGen] Teach SILGen to emit property wrapper parameters.
hborla Oct 11, 2020
aa573c0
[Property Wrappers] Allow property wrapper attributes to be applied
hborla Oct 11, 2020
4bdeed5
[ConstraintSystem] Use a wrapped value placeholder when matching prop…
hborla Oct 12, 2020
cf25fff
[Property Wrappers] Set the interface type of the synthesized local
hborla Nov 8, 2020
8bdc8f9
[Property Wrappers] Use the TypeExpr instead of the TypeRepr of the
hborla Nov 10, 2020
9afa7ba
[Property Wrappers] Determine the mutability of a property wrapper pa…
hborla Nov 11, 2020
19a4f93
[Property Wrappers] Teach the constraint system to build init(project…
hborla Jan 14, 2021
6aee012
[CSApply] Add buildPropertyWrapperFnThunk, which builds a thunk around
hborla Feb 16, 2021
78b202c
[ASTWalker] Support configurating whether or not to visit the original
hborla Feb 16, 2021
31f7b1a
[ConstraintSystem] Change the type of an unapplied function reference
hborla Feb 16, 2021
6a8232e
[PreCheckExpr] Strip $ prefixes out from compound decl names for unqu…
hborla Jan 27, 2021
1486352
[Property Wrappers] Don't include the $ prefix in synthesized propert…
hborla Jan 27, 2021
140cbaa
[Parser] Allow $ prefixes on argument labels and closure parameter
hborla Jan 27, 2021
a4e3968
[Property Wrappers] Don't allow property wrappers applied to parameters
hborla Jan 27, 2021
ea3fe03
[Property Wrappers] Add a constraint fix and diagnostic for the case
hborla Jan 28, 2021
12161fa
[Sema] Diagnose invalid $ prefixes on closure parameters after the
hborla Jan 28, 2021
522eedc
[ConstraintSystem] Emit an error message when trying to pass a property
hborla Feb 1, 2021
36008a1
[NFC][Property Wrappers] Start to add Sema tests for SE-0293.
hborla Feb 7, 2021
2c2d671
[Property Wrappers] Add an unsupported error message for property wra…
hborla Feb 7, 2021
96f4315
[Property Wrappers] Implement support for parameters with an implicit
hborla Feb 9, 2021
133dec0
[ConstraintSystem] Implement implicit property wrapper attribute
hborla Feb 9, 2021
e40d7eb
[NFC][Property Wrappers] Start to add SILGen tests for SE-0293.
hborla Feb 9, 2021
aa0da03
[CSGen] Move generateWrappedPropertyTypeConstraints back to its original
hborla Feb 16, 2021
13692fe
[Property Wrappers] Store property wrapper "init from projection" exp…
hborla Feb 20, 2021
648c575
[SILGen] Teach SILGen to emit property wrapper generator functions that
hborla Feb 25, 2021
b821c8d
[Sema] Add an implicit applied property wrapper expression and a new
hborla Feb 25, 2021
9cdecf4
[Property Wrappers] Compute generic wrapped-value and projected-value
hborla Feb 25, 2021
99e0666
[ConstraintSystem] Inject implicit applied property wrapper expressions
hborla Feb 25, 2021
bea89c6
[SILGen] Serialize and give PublicNonABI linkage to property wrapper
hborla Feb 25, 2021
c29eecd
[Property Wrappers] Store the callee in AppliedPropertyWrapperExpr to…
hborla Feb 25, 2021
db38727
[ConstraintSystem] Don't allow dollar prefixes in argument labels unless
hborla Feb 26, 2021
b7a170c
[NFC][ConstraintSystem] Rename applyPropertyWrapperParameter.
hborla Feb 26, 2021
b3d54b6
[Property Wrappers] Don't allow parameters with attached property wra…
hborla Feb 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ Entities
entity-spec ::= 'fA' INDEX // default argument N+1 generator
entity-spec ::= 'fi' // non-local variable initializer
entity-spec ::= 'fP' // property wrapper backing initializer
entity-spec ::= 'fW' // property wrapper init from projected value
entity-spec ::= 'fD' // deallocating destructor; untyped
entity-spec ::= 'fd' // non-deallocating destructor; untyped
entity-spec ::= 'fE' // ivar destroyer; untyped
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/ASTMangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class ASTMangler : public Mangler {
std::string mangleInitializerEntity(const VarDecl *var, SymbolKind SKind);
std::string mangleBackingInitializerEntity(const VarDecl *var,
SymbolKind SKind = SymbolKind::Default);
std::string mangleInitFromProjectedValueEntity(const VarDecl *var,
SymbolKind SKind = SymbolKind::Default);

std::string mangleNominalType(const NominalTypeDecl *decl);

Expand Down Expand Up @@ -405,6 +407,7 @@ class ASTMangler : public Mangler {

void appendInitializerEntity(const VarDecl *var);
void appendBackingInitializerEntity(const VarDecl *var);
void appendInitFromProjectedValueEntity(const VarDecl *var);

CanType getDeclTypeForMangling(const ValueDecl *decl,
GenericSignature &genericSig,
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/ASTWalker.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ class ASTWalker {
/// TapExpr.
virtual bool shouldWalkIntoTapExpression() { return true; }

/// This method configures whether the the walker should visit the underlying
/// value of a property wrapper placeholder.
virtual bool shouldWalkIntoPropertyWrapperPlaceholderValue() { return true; }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer used - I'll remove it


/// This method configures whether the walker should visit the capture
/// initializer expressions within a capture list directly, rather than
/// walking the declarations.
Expand Down
13 changes: 13 additions & 0 deletions include/swift/AST/AnyFunctionRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "swift/Basic/LLVM.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/Types.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
Expand Down Expand Up @@ -103,6 +104,18 @@ class AnyFunctionRef {
return TheFunction.get<AbstractClosureExpr *>()->getSingleExpressionBody();
}

ParameterList *getParameters() const {
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>())
return AFD->getParameters();
return TheFunction.get<AbstractClosureExpr *>()->getParameters();
}

bool hasPropertyWrapperParameters() const {
return llvm::any_of(*getParameters(), [](const ParamDecl *param) {
return param->hasAttachedPropertyWrapper();
});
}

Type getType() const {
if (auto *AFD = TheFunction.dyn_cast<AbstractFunctionDecl *>())
return AFD->getInterfaceType();
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,7 @@ class CustomAttr final : public DeclAttribute,
unsigned getNumArguments() const { return numArgLabels; }
bool hasArgumentLabelLocs() const { return hasArgLabelLocs; }

TypeExpr *getTypeExpr() const { return typeExpr; }
TypeRepr *getTypeRepr() const;
Type getType() const;

Expand Down
9 changes: 8 additions & 1 deletion include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4917,7 +4917,10 @@ class VarDecl : public AbstractStorageDecl {

/// Whether this property has any attached property wrappers.
bool hasAttachedPropertyWrapper() const;


/// Whether this var has an implicit property wrapper attribute.
bool hasImplicitPropertyWrapper() const;

/// Whether all of the attached property wrappers have an init(wrappedValue:)
/// initializer.
bool allAttachedPropertyWrappersHaveWrappedValueInit() const;
Expand Down Expand Up @@ -4978,6 +4981,10 @@ class VarDecl : public AbstractStorageDecl {
/// property wrapper with a \c projectedValue .
VarDecl *getPropertyWrapperProjectionVar() const;

/// Retrieve the local wrapped value var for for a parameter that has
/// an attached property wrapper.
VarDecl *getPropertyWrapperWrappedValueVar() const;

/// Visit all auxiliary declarations to this VarDecl.
///
/// An auxiliary declaration is a declaration synthesized by the compiler to support
Expand Down
33 changes: 26 additions & 7 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -4109,11 +4109,11 @@ ERROR(throw_in_nonexhaustive_catch,none,

ERROR(throwing_call_in_illegal_context,none,
"call can throw, but errors cannot be thrown out of "
"%select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
"%select{<<ERROR>>|a default argument|a property wrapper initializer|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
(unsigned))
ERROR(throw_in_illegal_context,none,
"errors cannot be thrown out of "
"%select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
"%select{<<ERROR>>|a default argument|a property wrapper initializer|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
(unsigned))

ERROR(throwing_operator_without_try,none,
Expand Down Expand Up @@ -4151,11 +4151,11 @@ WARNING(no_async_in_await,none,
"no calls to 'async' functions occur within 'await' expression", ())
ERROR(async_call_in_illegal_context,none,
"'async' call cannot occur in "
"%select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
"%select{<<ERROR>>|a default argument|a property wrapper initializer|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
(unsigned))
ERROR(await_in_illegal_context,none,
"'await' operation cannot occur in "
"%select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
"%select{<<ERROR>>|a default argument|a property wrapper initializer|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
(unsigned))
ERROR(async_in_nonasync_function,none,
"%select{'async'|'await'|'async let'}0 in "
Expand Down Expand Up @@ -4197,7 +4197,7 @@ ERROR(async_let_without_await,none,
"reference to async let %0 is not marked with 'await'", (DeclName))
ERROR(async_let_in_illegal_context,none,
"async let %0 cannot be referenced in "
"%select{<<ERROR>>|a default argument|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}1",
"%select{<<ERROR>>|a default argument|a property wrapper initializer|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}1",
(DeclName, unsigned))

ERROR(asynchandler_non_func,none,
Expand Down Expand Up @@ -5482,8 +5482,27 @@ ERROR(property_wrapper_dynamic_self_type, none,
ERROR(property_wrapper_attribute_not_on_property, none,
"property wrapper attribute %0 can only be applied to a property",
(Identifier))
ERROR(property_wrapper_param_not_supported,none,
"property wrapper attribute on parameter not yet supported on %0",
(DescriptiveDeclKind))
NOTE(property_wrapper_declared_here,none,
"property wrapper type %0 declared here", (Identifier))
ERROR(property_wrapper_param_no_projection,none,
"cannot use property wrapper projection parameter; "
"wrapper %0 does not have a 'projectedValue'", (Type))
ERROR(property_wrapper_param_no_wrapper,none,
"cannot use property wrapper projection argument; "
"parameter does not have an attached property wrapper",
())
ERROR(property_wrapper_param_projection_invalid,none,
"cannot use property wrapper projection argument; "
"pass wrapped value type %0 instead", (Type))
ERROR(property_wrapper_param_mutating,none,
"property wrapper applied to parameter must have a nonmutating "
"'wrappedValue' getter", ())
ERROR(invalid_implicit_property_wrapper,none,
"inferred projection type %0 is not a property wrapper",
(Type))

ERROR(property_wrapper_mutating_get_composed_to_get_only,none,
"property wrapper %0 with a mutating getter cannot be composed inside "
Expand All @@ -5505,9 +5524,9 @@ ERROR(property_with_wrapper_conflict_attribute,none,
ERROR(property_wrapper_not_single_var, none,
"property wrapper can only apply to a single variable", ())
ERROR(property_with_wrapper_in_bad_context,none,
"%select{|non-static |non-static }1property %0 declared inside "
"%select{|non-static|non-static}1 %2 %0 declared inside "
"%select{a protocol|an extension|an enum}1 cannot have a wrapper",
(Identifier, int))
(Identifier, int, DescriptiveDeclKind))
ERROR(property_with_wrapper_overrides,none,
"property %0 with attached wrapper cannot override another property",
(Identifier))
Expand Down
56 changes: 56 additions & 0 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -4228,6 +4228,62 @@ class PropertyWrapperValuePlaceholderExpr : public Expr {
}
};

/// An implicit applied property wrapper expression.
class AppliedPropertyWrapperExpr final : public Expr {
public:
enum class ValueKind {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there is way to extract ValueKind and Param + Kind finds into their own abstract base type so it could be used here and for PropertyWrapperInitializer to reduce duplication?

WrappedValue,
ProjectedValue
};

private:
/// The concrete callee which owns the property wrapper.
ConcreteDeclRef Callee;

/// The owning declaration.
const ParamDecl *Param;

/// The source location of the argument list.
SourceLoc Loc;

/// The value to which the property wrapper is applied for initialization.
Expr *Value;

/// The kind of value that the property wrapper is applied to.
ValueKind Kind;

AppliedPropertyWrapperExpr(ConcreteDeclRef callee, const ParamDecl *param, SourceLoc loc,
Type Ty, Expr *value, ValueKind kind)
: Expr(ExprKind::AppliedPropertyWrapper, /*Implicit=*/true, Ty),
Callee(callee), Param(param), Loc(loc), Value(value), Kind(kind) {}

public:
static AppliedPropertyWrapperExpr *
create(ASTContext &ctx, ConcreteDeclRef callee, const ParamDecl *param, SourceLoc loc,
Type Ty, Expr *value, ValueKind kind);

SourceRange getSourceRange() const { return Loc; }

ConcreteDeclRef getCallee() { return Callee; }

/// Returns the parameter declaration with the attached property wrapper.
const ParamDecl *getParamDecl() const { return Param; };

/// Returns the value that the property wrapper is applied to.
Expr *getValue() { return Value; }

/// Sets the value that the property wrapper is applied to.
void setValue(Expr *value) { Value = value; }

/// Returns the kind of value, between wrapped value and projected
/// value, the property wrapper is applied to.
ValueKind getValueKind() const { return Kind; }

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::AppliedPropertyWrapper;
}
};

/// An expression referring to a default argument left unspecified at the
/// call site.
///
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ExprNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ EXPR(DynamicType, Expr)
EXPR(RebindSelfInConstructor, Expr)
EXPR(OpaqueValue, Expr)
EXPR(PropertyWrapperValuePlaceholder, Expr)
EXPR(AppliedPropertyWrapper, Expr)
EXPR(DefaultArgument, Expr)
EXPR(BindOptional, Expr)
EXPR(OptionalEvaluation, Expr)
Expand Down
8 changes: 8 additions & 0 deletions include/swift/AST/Identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ class Identifier {
bool isEditorPlaceholder() const {
return !empty() && isEditorPlaceholder(str());
}

bool hasDollarPrefix() const {
return str().startswith("$") && !(getLength() == 1);
}

const void *getAsOpaquePointer() const {
return static_cast<const void *>(Pointer);
Expand Down Expand Up @@ -324,6 +328,10 @@ class DeclBaseName {
return !isSpecial() && getIdentifier().isEditorPlaceholder();
}

bool hasDollarPrefix() const {
return getIdentifier().hasDollarPrefix();
}

/// A representation of the name to be displayed to users. May be ambiguous
/// between identifiers and special names.
StringRef userFacingName() const {
Expand Down
40 changes: 38 additions & 2 deletions include/swift/AST/Initializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ enum class InitializerKind : uint8_t {

/// A function's default argument expression.
DefaultArgument,

/// A property wrapper initialization expression.
PropertyWrapper,
};

/// An Initializer is a kind of DeclContext used for expressions that
Expand All @@ -41,9 +44,9 @@ enum class InitializerKind : uint8_t {
/// Generally, Initializers are created lazily, as most initializers
/// don't really require DeclContexts.
class Initializer : public DeclContext {
unsigned Kind : 1;
unsigned Kind : 2;
protected:
unsigned SpareBits : 31;
unsigned SpareBits : 30;

Initializer(InitializerKind kind, DeclContext *parent)
: DeclContext(DeclContextKind::Initializer, parent),
Expand Down Expand Up @@ -195,6 +198,39 @@ class SerializedDefaultArgumentInitializer : public SerializedLocalDeclContext {
return false;
}
};

/// A property wrapper initialization expression. The parent context is the
/// function or closure which owns the property wrapper.
class PropertyWrapperInitializer : public Initializer {
public:
enum class Kind {
WrappedValue,
ProjectedValue
};

private:
ParamDecl *param;
Kind kind;

public:
explicit PropertyWrapperInitializer(DeclContext *parent, ParamDecl *param, Kind kind)
: Initializer(InitializerKind::PropertyWrapper, parent),
param(param), kind(kind) {}

ParamDecl *getParam() const { return param; }

Kind getKind() const { return kind; }

static bool classof(const DeclContext *DC) {
if (auto init = dyn_cast<Initializer>(DC))
return classof(init);
return false;
}

static bool classof(const Initializer *I) {
return I->getInitializerKind() == InitializerKind::PropertyWrapper;
}
};

} // end namespace swift

Expand Down
Loading