Skip to content

Commit 4fcef2b

Browse files
authored
Merge pull request #27220 from slavapestov/default-arg-self-capture-diagnostic
Default arguments: implement captures for local functions, diagnose 'Self' for methods
2 parents 334d892 + 78ae7ac commit 4fcef2b

19 files changed

+434
-274
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5164,6 +5164,7 @@ class ParamDecl : public VarDecl {
51645164
PointerUnion<Expr *, VarDecl *> DefaultArg;
51655165
Initializer *InitContext = nullptr;
51665166
StringRef StringRepresentation;
5167+
CaptureInfo Captures;
51675168
};
51685169

51695170
enum class Flags : uint8_t {
@@ -5249,6 +5250,13 @@ class ParamDecl : public VarDecl {
52495250

52505251
void setDefaultArgumentInitContext(Initializer *initContext);
52515252

5253+
const CaptureInfo &getDefaultArgumentCaptureInfo() const {
5254+
assert(DefaultValueAndFlags.getPointer());
5255+
return DefaultValueAndFlags.getPointer()->Captures;
5256+
}
5257+
5258+
void setDefaultArgumentCaptureInfo(const CaptureInfo &captures);
5259+
52525260
/// Extracts the text of the default argument attached to the provided
52535261
/// ParamDecl, removing all inactive #if clauses and providing only the
52545262
/// text of active #if clauses.

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2655,6 +2655,8 @@ ERROR(dynamic_self_invalid_method,none,
26552655
"covariant 'Self' can only appear at the top level of method result type", ())
26562656
ERROR(dynamic_self_stored_property_init,none,
26572657
"covariant 'Self' type cannot be referenced from a stored property initializer", ())
2658+
ERROR(dynamic_self_default_arg,none,
2659+
"covariant 'Self' type cannot be referenced from a default argument expression", ())
26582660

26592661
//------------------------------------------------------------------------------
26602662
// MARK: Type Check Attributes

include/swift/SIL/TypeLowering.h

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ class TypeConverter {
689689

690690
llvm::DenseMap<OverrideKey, SILConstantInfo *> ConstantOverrideTypes;
691691

692-
llvm::DenseMap<AnyFunctionRef, CaptureInfo> LoweredCaptures;
692+
llvm::DenseMap<SILDeclRef, CaptureInfo> LoweredCaptures;
693693

694694
/// Cache of loadable SILType to number of (estimated) fields
695695
///
@@ -844,10 +844,13 @@ class TypeConverter {
844844
/// Returns the formal type, lowered AST type, and SILFunctionType
845845
/// for a constant reference.
846846
const SILConstantInfo &getConstantInfo(SILDeclRef constant);
847-
847+
848+
/// Get the generic environment for a constant.
849+
GenericSignature *getConstantGenericSignature(SILDeclRef constant);
850+
848851
/// Get the generic environment for a constant.
849852
GenericEnvironment *getConstantGenericEnvironment(SILDeclRef constant);
850-
853+
851854
/// Returns the SIL type of a constant reference.
852855
SILType getConstantType(SILDeclRef constant) {
853856
return getConstantInfo(constant).getSILType();
@@ -893,11 +896,6 @@ class TypeConverter {
893896
SILType getEmptyTupleType() {
894897
return SILType::getPrimitiveObjectType(TupleType::getEmpty(Context));
895898
}
896-
897-
/// Get a function type curried with its capture context.
898-
CanAnyFunctionType getFunctionInterfaceTypeWithCaptures(
899-
CanAnyFunctionType funcType,
900-
AnyFunctionRef closure);
901899

902900
/// Describes what we're trying to compute a bridged type for.
903901
///
@@ -944,17 +942,6 @@ class TypeConverter {
944942
SILType getSubstitutedStorageType(AbstractStorageDecl *value,
945943
Type lvalueType);
946944

947-
/// Retrieve the set of archetypes closed over by the given function.
948-
GenericEnvironment *getEffectiveGenericEnvironment(AnyFunctionRef fn,
949-
CaptureInfo captureInfo);
950-
951-
/// Retrieve the set of generic parameters closed over by the given function.
952-
CanGenericSignature getEffectiveGenericSignature(AnyFunctionRef fn,
953-
CaptureInfo captureInfo);
954-
955-
/// Retrieve the set of generic parameters closed over by the context.
956-
CanGenericSignature getEffectiveGenericSignature(DeclContext *dc);
957-
958945
/// Push a generic function context. See GenericContextScope for an RAII
959946
/// interface to this function.
960947
///
@@ -980,10 +967,10 @@ class TypeConverter {
980967
CanType get##BridgedType##Type();
981968
#include "swift/SIL/BridgedTypes.def"
982969

983-
/// Get the capture list from a closure, with transitive function captures
984-
/// flattened.
985-
CaptureInfo getLoweredLocalCaptures(AnyFunctionRef fn);
986-
bool hasLoweredLocalCaptures(AnyFunctionRef fn);
970+
/// Get the capture list for a function or default argument, with transitive
971+
/// function captures flattened.
972+
CaptureInfo getLoweredLocalCaptures(SILDeclRef fn);
973+
bool hasLoweredLocalCaptures(SILDeclRef fn);
987974

988975
enum class ABIDifference : uint8_t {
989976
// No ABI differences, function can be trivially bitcast to result type.

lib/AST/ASTDumper.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,9 +988,17 @@ namespace {
988988
if (P->isAutoClosure())
989989
OS << " autoclosure";
990990

991-
if (P->getDefaultArgumentKind() != DefaultArgumentKind::None)
991+
if (P->getDefaultArgumentKind() != DefaultArgumentKind::None) {
992992
printField("default_arg",
993993
getDefaultArgumentKindString(P->getDefaultArgumentKind()));
994+
}
995+
996+
if (P->getDefaultValue() &&
997+
!P->getDefaultArgumentCaptureInfo().isTrivial()) {
998+
OS << " ";
999+
P->getDefaultArgumentCaptureInfo().print(
1000+
PrintWithColorRAII(OS, CapturesColor).getOS());
1001+
}
9941002

9951003
if (auto init = P->getDefaultValue()) {
9961004
OS << " expression=\n";

lib/AST/Decl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5866,6 +5866,11 @@ void ParamDecl::setDefaultArgumentInitContext(Initializer *initContext) {
58665866
DefaultValueAndFlags.getPointer()->InitContext = initContext;
58675867
}
58685868

5869+
void ParamDecl::setDefaultArgumentCaptureInfo(const CaptureInfo &captures) {
5870+
assert(DefaultValueAndFlags.getPointer());
5871+
DefaultValueAndFlags.getPointer()->Captures = captures;
5872+
}
5873+
58695874
/// Return nullptr if there is no property wrapper
58705875
Expr *swift::findOriginalPropertyWrapperInitialValue(VarDecl *var,
58715876
Expr *init) {

lib/SIL/SILFunctionType.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ static std::pair<AbstractionPattern, CanType> updateResultTypeForForeignError(
715715
/// If we ever add that ability, it will be a different capture list
716716
/// from the function to which the argument is attached.
717717
static void
718-
lowerCaptureContextParameters(TypeConverter &TC, AnyFunctionRef function,
718+
lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
719719
CanGenericSignature genericSig,
720720
ResilienceExpansion expansion,
721721
SmallVectorImpl<SILParameterInfo> &inputs) {
@@ -725,8 +725,7 @@ lowerCaptureContextParameters(TypeConverter &TC, AnyFunctionRef function,
725725
// canonicalize references to the generic parameters that may appear in
726726
// non-canonical types in that context. We need the original generic
727727
// signature from the AST for that.
728-
auto origGenericSig = function.getGenericSignature();
729-
728+
auto origGenericSig = function.getAnyFunctionRef()->getGenericSignature();
730729
auto loweredCaptures = TC.getLoweredLocalCaptures(function);
731730

732731
for (auto capture : loweredCaptures.getCaptures()) {
@@ -999,18 +998,12 @@ static CanSILFunctionType getSILFunctionType(
999998
yields, coroutineKind);
1000999

10011000
// Lower the capture context parameters, if any.
1002-
//
1003-
// *NOTE* Currently default arg generators can not capture anything.
1004-
// If we ever add that ability, it will be a different capture list
1005-
// from the function to which the argument is attached.
1006-
if (constant && !constant->isDefaultArgGenerator()) {
1007-
if (auto function = constant->getAnyFunctionRef()) {
1008-
auto expansion = ResilienceExpansion::Maximal;
1009-
if (constant->isSerialized())
1010-
expansion = ResilienceExpansion::Minimal;
1011-
lowerCaptureContextParameters(TC, *function, genericSig, expansion,
1012-
inputs);
1013-
}
1001+
if (constant && constant->getAnyFunctionRef()) {
1002+
auto expansion = ResilienceExpansion::Maximal;
1003+
if (constant->isSerialized())
1004+
expansion = ResilienceExpansion::Minimal;
1005+
lowerCaptureContextParameters(TC, *constant, genericSig, expansion,
1006+
inputs);
10141007
}
10151008

10161009
auto calleeConvention = ParameterConvention::Direct_Unowned;

0 commit comments

Comments
 (0)