Skip to content

Partially Revert #27862 #28171

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

Merged
merged 1 commit into from
Nov 11, 2019
Merged
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
9 changes: 7 additions & 2 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5214,7 +5214,7 @@ enum class ParamSpecifier : uint8_t {

/// A function parameter declaration.
class ParamDecl : public VarDecl {
Identifier ArgumentName;
llvm::PointerIntPair<Identifier, 1, bool> ArgumentNameAndDestructured;
SourceLoc ParameterNameLoc;
SourceLoc ArgumentNameLoc;
SourceLoc SpecifierLoc;
Expand Down Expand Up @@ -5251,7 +5251,9 @@ class ParamDecl : public VarDecl {
static ParamDecl *cloneWithoutType(const ASTContext &Ctx, ParamDecl *PD);

/// Retrieve the argument (API) name for this function parameter.
Identifier getArgumentName() const { return ArgumentName; }
Identifier getArgumentName() const {
return ArgumentNameAndDestructured.getPointer();
}

/// Retrieve the parameter (local) name for this function parameter.
Identifier getParameterName() const { return getName(); }
Expand All @@ -5270,6 +5272,9 @@ class ParamDecl : public VarDecl {
TypeRepr *getTypeRepr() const { return TyRepr; }
void setTypeRepr(TypeRepr *repr) { TyRepr = repr; }

bool isDestructured() const { return ArgumentNameAndDestructured.getInt(); }
void setDestructured(bool repr) { ArgumentNameAndDestructured.setInt(repr); }

DefaultArgumentKind getDefaultArgumentKind() const {
return static_cast<DefaultArgumentKind>(Bits.ParamDecl.defaultArgumentKind);
}
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,8 @@ ERROR(parameter_operator_keyword_argument,none,

ERROR(parameter_unnamed,none,
"unnamed parameters must be written with the empty name '_'", ())
WARNING(parameter_unnamed_warn,none,
"unnamed parameters must be written with the empty name '_'", ())

ERROR(parameter_curry_syntax_removed,none,
"cannot have more than one parameter list", ())
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,9 @@ class Parser {

/// True if we emitted a parse error about this parameter.
bool isInvalid = false;

/// True if this parameter is potentially destructuring a tuple argument.
bool isPotentiallyDestructured = false;
};

/// Describes the context in which the given parameter is being parsed.
Expand Down
3 changes: 2 additions & 1 deletion lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5914,7 +5914,8 @@ ParamDecl::ParamDecl(SourceLoc specifierLoc,
VarDecl::Introducer::Let,
/*IsCaptureList*/ false, parameterNameLoc, parameterName, dc,
StorageIsNotMutable),
ArgumentName(argumentName), ParameterNameLoc(parameterNameLoc),
ArgumentNameAndDestructured(argumentName, false),
ParameterNameLoc(parameterNameLoc),
ArgumentNameLoc(argumentNameLoc), SpecifierLoc(specifierLoc) {
Bits.ParamDecl.SpecifierComputed = false;
Bits.ParamDecl.defaultArgumentKind =
Expand Down
2 changes: 1 addition & 1 deletion lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2657,7 +2657,7 @@ parseClosureSignatureIfPresent(SmallVectorImpl<CaptureListEntry> &captureList,
// possible and give a proper fix-it. See SE-0110 for more details.
auto isTupleDestructuring = [](ParamDecl *param) -> bool {
auto *typeRepr = param->getTypeRepr();
if (!(typeRepr && typeRepr->isInvalid()))
if (!(typeRepr && param->isDestructured()))
return false;
return !param->hasName() && isa<TupleTypeRepr>(typeRepr);
};
Expand Down
18 changes: 15 additions & 3 deletions lib/Parse/ParsePattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,12 +363,18 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
if (param.Type) {
// Mark current parameter type as invalid so it is possible
// to diagnose it as destructuring of the closure parameter list.
param.Type->setInvalid();
param.isInvalid = true;
param.isPotentiallyDestructured = true;
if (!isClosure) {
// Unnamed parameters must be written as "_: Type".
diagnose(typeStartLoc, diag::parameter_unnamed)
.fixItInsert(typeStartLoc, "_: ");
} else {
// Unnamed parameters were accidentally possibly accepted after
// SE-110 depending on the kind of declaration. We now need to
// warn about the misuse of this syntax and offer to
// fix it.
diagnose(typeStartLoc, diag::parameter_unnamed_warn)
.fixItInsert(typeStartLoc, "_: ");
}
}
} else {
Expand Down Expand Up @@ -492,7 +498,13 @@ mapParsedParameters(Parser &parser,
// If we diagnosed this parameter as a parse error, propagate to the decl.
if (paramInfo.isInvalid)
param->setInvalid();


// If we need to diagnose this parameter as a destructuring, propagate that
// to the decl.
// FIXME: This is a terrible way to catch this.
if (paramInfo.isPotentiallyDestructured)
param->setDestructured(true);

// If a type was provided, create the type for the parameter.
if (auto type = paramInfo.Type) {
// If 'inout' was specified, turn the type into an in-out type.
Expand Down
14 changes: 12 additions & 2 deletions test/Constraints/tuple_arguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1470,6 +1470,9 @@ let _ = sr4745.enumerated().map { (count, element) in "\(count): \(element)" }
let sr4738 = (1, (2, 3))
[sr4738].map { (x, (y, z)) -> Int in x + y + z }
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{20-26=arg1}} {{38-38=let (y, z) = arg1; }}
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{20-20=_: }}
// expected-error@-3 {{use of undeclared type 'y'}}
// expected-error@-4 {{use of undeclared type 'z'}}

// rdar://problem/31892961
let r31892961_1 = [1: 1, 2: 2]
Expand All @@ -1478,6 +1481,9 @@ r31892961_1.forEach { (k, v) in print(k + v) }
let r31892961_2 = [1, 2, 3]
let _: [Int] = r31892961_2.enumerated().map { ((index, val)) in
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{48-60=arg0}} {{3-3=\n let (index, val) = arg0\n }}
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{48-48=_: }}
// expected-error@-3 {{use of undeclared type 'index'}}
// expected-error@-4 {{use of undeclared type 'val'}}
val + 1
}

Expand All @@ -1490,12 +1496,16 @@ let r31892961_4 = (1, 2)
_ = [r31892961_4].map { x, y in x + y }

let r31892961_5 = (x: 1, (y: 2, (w: 3, z: 4)))
[r31892961_5].map { (x: Int, (y: Int, (w: Int, z: Int))) in x + y }
[r31892961_5].map { (x: Int, (y: Int, (w: Int, z: Int))) in x + y } // expected-note {{'x' declared here}}
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{30-56=arg1}} {{61-61=let (y, (w, z)) = arg1; }}
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{30-30=_: }}
// expected-error@-3{{use of unresolved identifier 'y'; did you mean 'x'?}}

let r31892961_6 = (x: 1, (y: 2, z: 4))
[r31892961_6].map { (x: Int, (y: Int, z: Int)) in x + y }
[r31892961_6].map { (x: Int, (y: Int, z: Int)) in x + y } // expected-note {{'x' declared here}}
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{30-46=arg1}} {{51-51=let (y, z) = arg1; }}
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{30-30=_: }}
// expected-error@-3{{use of unresolved identifier 'y'; did you mean 'x'?}}

// rdar://problem/32214649 -- these regressed in Swift 4 mode
// with SE-0110 because of a problem in associated type inference
Expand Down
4 changes: 2 additions & 2 deletions test/decl/func/functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ func bogusDestructuring() {
func registerCallback(_ callback: @escaping (Bar?) -> Void) {} // expected-note {{found this candidate}}
}

Foo().registerCallback { ([Bar]) in } // expected-error {{'<<error type>>' is not convertible to '[Bar]'}}
Foo().registerCallback { ([String: Bar]) in } // expected-error {{'<<error type>>' is not convertible to '[Bar]'}}
Foo().registerCallback { ([Bar]) in } // expected-warning {{unnamed parameters must be written with the empty name '_'}} {{29-29=_: }}
Foo().registerCallback { ([String: Bar]) in }// expected-warning {{unnamed parameters must be written with the empty name '_'}} {{29-29=_: }}
Foo().registerCallback { (Bar?) in } // expected-error {{ambiguous use of 'registerCallback'}}
// expected-error@-1 {{expected parameter name followed by ':'}}
// expected-error@-2 {{expected ',' separator}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

// rdar://56144412
// XFAIL: asserts
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this mean that this case started crashing again and has to be moved to "compiler_crashers"? 😢

// RUN: not %target-swift-frontend %s -emit-ir
func t(UInt=__FUNCTION__
func&t(