Skip to content

Sema: Hide SE-0110 behind it's own command line flag instead of Swift 4 mode #10257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ namespace swift {
/// \brief Enable experimental property behavior feature.
bool EnableExperimentalPropertyBehaviors = false;

/// \brief Enable SE-0110.
bool EnableExperimentalSE0110 = false;

/// \brief Staging flag for treating inout parameters as Thread Sanitizer
/// accesses.
bool DisableTsanInoutInstrumentation = false;
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ def enable_sil_opaque_values : Flag<["-"], "enable-sil-opaque-values">,
def enable_large_loadable_types : Flag<["-"], "enable-large-loadable-types">,
HelpText<"Enable Large Loadable types IRGen pass">;

def enable_experimental_se_0110 :
Flag<["-"], "enable-experimental-se-0110">,
HelpText<"Enable experimental SE-0110 implementation">;

def enable_experimental_property_behaviors :
Flag<["-"], "enable-experimental-property-behaviors">,
HelpText<"Enable experimental property behaviors">;
Expand Down
3 changes: 3 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.EnableExperimentalKeyPathComponents |=
Args.hasArg(OPT_enable_experimental_keypath_components);

Opts.EnableExperimentalSE0110 |=
Args.hasArg(OPT_enable_experimental_se_0110);

Opts.EnableClassResilience |=
Args.hasArg(OPT_enable_class_resilience);

Expand Down
4 changes: 3 additions & 1 deletion lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5204,14 +5204,16 @@ Expr *ExprRewriter::coerceCallArguments(
matchCanFail = true;

// If you value your sanity, ignore the body of this 'if' statement.
if (cs.getASTContext().isSwiftVersion3()) {
if (!cs.getASTContext().LangOpts.EnableExperimentalSE0110) {
// Total hack: In Swift 3 mode, we can end up with an arity mismatch due to
// loss of ParenType sugar.
if (isa<TupleExpr>(arg))
if (auto *parenType = dyn_cast<ParenType>(paramType.getPointer()))
if (isa<TupleType>(parenType->getUnderlyingType().getPointer()))
paramType = parenType->getUnderlyingType();
}

if (cs.getASTContext().isSwiftVersion3()) {
// Total hack: In Swift 3 mode, argument labels are ignored when calling
// function type with a single Any parameter.
if (paramType->isAny()) {
Expand Down
14 changes: 7 additions & 7 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,8 +656,9 @@ matchCallArguments(ConstraintSystem &cs, ConstraintKind kind,
getCalleeDeclAndArgs(cs, locator, argLabelsScratch);
auto params = decomposeParamType(paramType, callee, calleeLevel);

if (callee && cs.getASTContext().isSwiftVersion3()
&& argType->is<TupleType>()) {
if (callee &&
!cs.getASTContext().LangOpts.EnableExperimentalSE0110 &&
argType->is<TupleType>()) {
// Hack: In Swift 3 mode, accept `foo(x, y)` for `foo((x, y))` when the
// callee is a function-typed property or an enum constructor whose
// argument is a single unlabeled type parameter.
Expand Down Expand Up @@ -1331,10 +1332,9 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
// types of two function types, we have to be careful to preserve
// ParenType sugar.
bool isArgumentTupleMatch = isArgumentTupleConversion;
bool isSwiftVersion3 = getASTContext().isSwiftVersion3();
bool isSE0110Enabled = getASTContext().LangOpts.EnableExperimentalSE0110;

// ... but not in Swift 3 mode, where this behavior was broken.
if (!isSwiftVersion3)
if (isSE0110Enabled)
if (auto elt = locator.last())
if (elt->getKind() == ConstraintLocator::FunctionArgument)
isArgumentTupleMatch = true;
Expand All @@ -1350,7 +1350,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
auto desugar2 = type2->getDesugaredType();
TypeVariableType *typeVar1, *typeVar2;
if (isArgumentTupleMatch &&
!isSwiftVersion3) {
isSE0110Enabled) {
typeVar1 = dyn_cast<TypeVariableType>(type1.getPointer());
typeVar2 = dyn_cast<TypeVariableType>(type2.getPointer());

Expand Down Expand Up @@ -1631,7 +1631,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
}

if (isArgumentTupleMatch &&
!isSwiftVersion3) {
isSE0110Enabled) {
if (!typeVar1 && !typeVar2) {
if (isa<ParenType>(type1.getPointer()) !=
isa<ParenType>(type2.getPointer())) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/MiscDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
// Note that in Swift 4 mode, this is rejected much earlier in
// the constraint solver; this check only exists to preserve the
// behavior of the earlier, incomplete implementation of SE-0110.
if (TC.Context.isSwiftVersion3())
if (!TC.Context.LangOpts.EnableExperimentalSE0110)
checkTupleSplat(Call);

// Check the callee, looking through implicit conversions.
Expand Down
30 changes: 7 additions & 23 deletions test/Compatibility/tuple_arguments.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// RUN: %target-typecheck-verify-swift -swift-version 3
// RUN: %target-typecheck-verify-swift -swift-version 4

// Tests for tuple argument behavior in Swift 3, which was broken.
// The Swift 4 test is in test/Constraints/tuple_arguments.swift.
// Tests for tuple argument behavior pre-SE0110, which was broken.
// The SE-0110 test is in test/Constraints/tuple_arguments.swift.
//
// Note that SE-0110 is currently off by default, so the compatibility
// test is run in both Swift 3 and 4 mode, and the new test is run with
// the experimental flag enabled.

// Key:
// - "Crashes in actual Swift 3" -- snippets which crashed in Swift 3.0.1.
Expand Down Expand Up @@ -1386,27 +1391,6 @@ do {
let _: (Int, Int) -> () = { t, u in _ = (t, u) }
}

// rdar://problem/28952837 - argument labels ignored when calling function
// with single 'Any' parameter
func takesAny(_: Any) {}

enum HasAnyCase {
case any(_: Any)
}

do {
let fn: (Any) -> () = { _ in }

fn(123)
fn(data: 123)

takesAny(123)
takesAny(data: 123)

_ = HasAnyCase.any(123)
_ = HasAnyCase.any(data: 123)
}

// rdar://problem/29739905 - protocol extension methods on Array had
// ParenType sugar stripped off the element type
typealias BoolPair = (Bool, Bool)
Expand Down
2 changes: 1 addition & 1 deletion test/Constraints/tuple_arguments.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -swift-version 4
// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-experimental-se-0110

// See test/Compatibility/tuple_arguments.swift for the Swift 3 behavior.

Expand Down