Skip to content

Commit ff9b8dc

Browse files
authored
Merge pull request swiftlang#64090 from gottesmm/reference-bindings
[reference-binding] InOut Prototype
2 parents 5b31444 + 0ad5a18 commit ff9b8dc

35 files changed

+926
-41
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,9 @@ ERROR(no_default_arg_closure,none,
964964
ERROR(no_default_arg_curried,none,
965965
"default arguments are not allowed in curried parameter lists", ())
966966
ERROR(var_pattern_in_var,none,
967+
"'%select{let||var}0' cannot appear nested inside another 'var' or "
968+
"'let' pattern", (unsigned))
969+
ERROR(var_pattern_in_var_inout,none,
967970
"'%select{let|inout|var}0' cannot appear nested inside another 'var', "
968971
"'let', or 'inout' pattern", (unsigned))
969972
ERROR(extra_var_in_multiple_pattern_list,none,
@@ -2077,5 +2080,11 @@ ERROR(parser_new_parser_errors,none,
20772080
"new Swift parser generated errors for code that C++ parser accepted",
20782081
())
20792082

2083+
// MARK: Reference Binding Diagnostics
2084+
ERROR(sil_markuncheckedreferencebinding_requires_attribute,none,
2085+
"mark_unchecked_reference_binding requires an attribute like [inout]", ())
2086+
ERROR(sil_markuncheckedreferencebinding_invalid_attribute,none,
2087+
"Attribute '[%0]' can not be applied to mark_unchecked_reference_binding", (StringRef))
2088+
20802089
#define UNDEFINE_DIAGNOSTIC_MACROS
20812090
#include "DefineDiagnosticMacros.h"

include/swift/AST/DiagnosticsSIL.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,5 +816,16 @@ WARNING(nontrivial_string_to_rawpointer_conversion,none,
816816
"forming %0 to an inout variable of type String exposes the internal representation "
817817
"rather than the string contents.", (Type))
818818

819+
// MARK: Reference Binding Warnings
820+
ERROR(sil_referencebinding_unknown_pattern, none,
821+
"reference binding that the compiler does not understand how to check. Please file a bug",
822+
())
823+
ERROR(sil_referencebinding_src_used_within_inout_scope, none,
824+
"var bound to inout binding cannot be used within the inout binding's scope",
825+
())
826+
NOTE(sil_referencebinding_inout_binding_here, none,
827+
"inout binding here",
828+
())
829+
819830
#define UNDEFINE_DIAGNOSTIC_MACROS
820831
#include "DefineDiagnosticMacros.h"

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ EXPERIMENTAL_FEATURE(ImportSymbolicCXXDecls, false)
179179
/// Generate bindings for functions that 'throw' in the C++ section of the generated Clang header.
180180
EXPERIMENTAL_FEATURE(GenerateBindingsForThrowingFunctionsInCXX, false)
181181

182+
/// Enable reference bindings.
183+
EXPERIMENTAL_FEATURE(ReferenceBindings, false)
184+
182185
#undef EXPERIMENTAL_FEATURE
183186
#undef UPCOMING_FEATURE
184187
#undef SUPPRESSIBLE_LANGUAGE_FEATURE

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2057,7 +2057,7 @@ DeclNameRef formDeclNameRef(ASTContext &ctx,
20572057
bool isCxxClassTemplateSpec = false);
20582058

20592059
/// Whether a given token can be the start of a decl.
2060-
bool isKeywordPossibleDeclStart(const Token &Tok);
2060+
bool isKeywordPossibleDeclStart(const LangOptions &options, const Token &Tok);
20612061

20622062
} // end namespace swift
20632063

include/swift/SIL/MemAccessUtils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,7 @@ inline bool isAccessStorageIdentityCast(SingleValueInstruction *svi) {
16321632
// Simply pass-thru the incoming address.
16331633
case SILInstructionKind::MarkUninitializedInst:
16341634
case SILInstructionKind::MarkMustCheckInst:
1635+
case SILInstructionKind::MarkUnresolvedReferenceBindingInst:
16351636
case SILInstructionKind::MarkDependenceInst:
16361637
case SILInstructionKind::CopyValueInst:
16371638
return true;

include/swift/SIL/SILBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,13 @@ class SILBuilder {
13301330
MarkMustCheckInst(getSILDebugLocation(loc), src, kind));
13311331
}
13321332

1333+
MarkUnresolvedReferenceBindingInst *createMarkUnresolvedReferenceBindingInst(
1334+
SILLocation loc, SILValue src,
1335+
MarkUnresolvedReferenceBindingInst::Kind kind) {
1336+
return insert(new (getModule()) MarkUnresolvedReferenceBindingInst(
1337+
getSILDebugLocation(loc), src, kind));
1338+
}
1339+
13331340
CopyableToMoveOnlyWrapperValueInst *
13341341
createOwnedCopyableToMoveOnlyWrapperValue(SILLocation loc, SILValue src) {
13351342
return insert(new (getModule()) CopyableToMoveOnlyWrapperValueInst(

include/swift/SIL/SILCloner.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,16 @@ void SILCloner<ImplClass>::visitMarkMustCheckInst(MarkMustCheckInst *Inst) {
18891889
recordClonedInstruction(Inst, MVI);
18901890
}
18911891

1892+
template <typename ImplClass>
1893+
void SILCloner<ImplClass>::visitMarkUnresolvedReferenceBindingInst(
1894+
MarkUnresolvedReferenceBindingInst *Inst) {
1895+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
1896+
auto *MVI = getBuilder().createMarkUnresolvedReferenceBindingInst(
1897+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1898+
Inst->getKind());
1899+
recordClonedInstruction(Inst, MVI);
1900+
}
1901+
18921902
template <typename ImplClass>
18931903
void SILCloner<ImplClass>::visitMoveOnlyWrapperToCopyableValueInst(
18941904
MoveOnlyWrapperToCopyableValueInst *inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8339,6 +8339,37 @@ class MarkMustCheckInst
83398339
}
83408340
};
83418341

8342+
/// A marker instruction that states a given alloc_box or alloc_stack is a
8343+
/// reference binding that must be transformed.
8344+
class MarkUnresolvedReferenceBindingInst
8345+
: public UnaryInstructionBase<
8346+
SILInstructionKind::MarkUnresolvedReferenceBindingInst,
8347+
SingleValueInstruction>,
8348+
public OwnershipForwardingMixin {
8349+
friend class SILBuilder;
8350+
8351+
public:
8352+
enum class Kind : unsigned {
8353+
Invalid = 0,
8354+
8355+
InOut = 1,
8356+
};
8357+
8358+
private:
8359+
Kind kind;
8360+
8361+
MarkUnresolvedReferenceBindingInst(SILDebugLocation debugLoc,
8362+
SILValue operand, Kind kind)
8363+
: UnaryInstructionBase(debugLoc, operand, operand->getType()),
8364+
OwnershipForwardingMixin(
8365+
SILInstructionKind::MarkUnresolvedReferenceBindingInst,
8366+
operand->getOwnershipKind()),
8367+
kind(kind) {}
8368+
8369+
public:
8370+
Kind getKind() const { return kind; }
8371+
};
8372+
83428373
/// Convert from a non-trivial copyable type to an `@moveOnly` wrapper type.
83438374
///
83448375
/// IMPORTANT: Unlike other forwarding instructions, the ownership of
@@ -10693,7 +10724,8 @@ inline bool OwnershipForwardingMixin::isa(SILInstructionKind kind) {
1069310724
OwnershipForwardingConversionInst::classof(kind) ||
1069410725
OwnershipForwardingSelectEnumInstBase::classof(kind) ||
1069510726
OwnershipForwardingMultipleValueInstruction::classof(kind) ||
10696-
kind == SILInstructionKind::MarkMustCheckInst;
10727+
kind == SILInstructionKind::MarkMustCheckInst ||
10728+
kind == SILInstructionKind::MarkUnresolvedReferenceBindingInst;
1069710729
}
1069810730

1069910731
inline OwnershipForwardingMixin *
@@ -10717,6 +10749,8 @@ OwnershipForwardingMixin::get(SILInstruction *inst) {
1071710749
return result;
1071810750
if (auto *result = dyn_cast<MarkMustCheckInst>(inst))
1071910751
return result;
10752+
if (auto *result = dyn_cast<MarkUnresolvedReferenceBindingInst>(inst))
10753+
return result;
1072010754
if (auto *result = dyn_cast<MoveOnlyWrapperToCopyableValueInst>(inst))
1072110755
return result;
1072210756
if (auto *result = dyn_cast<CopyableToMoveOnlyWrapperValueInst>(inst))

include/swift/SIL/SILNodes.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,12 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
467467
// running the relevant diagnostic.
468468
SINGLE_VALUE_INST(MarkMustCheckInst, mark_must_check,
469469
SingleValueInstruction, None, DoesNotRelease)
470+
// A canary value inserted by a SIL generating frontend to signal to the
471+
// reference binding transform to check/transform a specific value. Valid
472+
// only in Raw SIL. The relevant checkers should remove the instruction after
473+
// successfully running the relevant diagnostic.
474+
SINGLE_VALUE_INST(MarkUnresolvedReferenceBindingInst, mark_unresolved_reference_binding,
475+
SingleValueInstruction, None, DoesNotRelease)
470476
// Convert a $T to $@moveOnly T. This is the method that one uses to convert a
471477
// trivial value to a non-trivial move only value. Ownership is fixed at construction by
472478
// frontend to express specific semantics: guaranteed for guaranteed function arguments

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ PASS(MoveOnlyBorrowToDestructureTransform,
468468
"used to convert borrow+projection to destructures. Once this has run, the move "
469469
"only object checker runs and ensures that the destructures do not create "
470470
"any move only errors with respect to non-borrow+projection uses")
471+
PASS(ReferenceBindingTransform, "sil-reference-binding-transform",
472+
"Check/transform reference bindings")
471473
PASS(PruneVTables, "prune-vtables",
472474
"Mark class methods that do not require vtable dispatch")
473475
PASS_RANGE(AllPasses, AADumper, PruneVTables)

0 commit comments

Comments
 (0)