mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Diagnostics] Extend single parameter tuple splat to support generic parameters
Currently single parameter tuple splat fix/diagnostic supports only
cases where parameter is a concrete tuple type, let's enhance that to
support generic parameters as well e.g.:
```swift
func foo<T>(_: T) {}
foo(0, 1, 2) // `T` expects arguments to form a tuple e.g. `foo((0, 1, 2))`
```
This commit is contained in:
@@ -707,14 +707,42 @@ bool AllowTupleSplatForSingleParameter::attempt(
|
||||
|
||||
const auto ¶m = params.front();
|
||||
|
||||
auto *paramTy = param.getOldType()->getAs<TupleType>();
|
||||
if (!paramTy || paramTy->getNumElements() != args.size())
|
||||
if (param.isInOut() || param.isVariadic() || param.isAutoClosure())
|
||||
return true;
|
||||
|
||||
auto paramTy = param.getOldType();
|
||||
|
||||
// Parameter type has to be either a tuple (with the same arity as
|
||||
// argument list), or a type variable.
|
||||
if (!(paramTy->is<TupleType>() &&
|
||||
paramTy->castTo<TupleType>()->getNumElements() == args.size()) &&
|
||||
!paramTy->is<TypeVariableType>())
|
||||
return true;
|
||||
|
||||
SmallVector<TupleTypeElt, 4> argElts;
|
||||
for (const auto &arg : args) {
|
||||
argElts.push_back(
|
||||
{arg.getPlainType(), arg.getLabel(), arg.getParameterFlags()});
|
||||
|
||||
for (unsigned index : indices(args)) {
|
||||
const auto &arg = args[index];
|
||||
|
||||
auto label = arg.getLabel();
|
||||
auto flags = arg.getParameterFlags();
|
||||
|
||||
// In situations where there is a single labeled parameter
|
||||
// we need to form a tuple with omits first label e.g.
|
||||
//
|
||||
// func foo<T>(x: T) {}
|
||||
// foo(x: 0, 1)
|
||||
//
|
||||
// We'd want to suggest argument list to be `x: (0, 1)` instead
|
||||
// of `(x: 0, 1)` which would be incorrect.
|
||||
if (index == 0 && param.getLabel() == label)
|
||||
label = Identifier();
|
||||
|
||||
// Tuple can't have `inout` elements.
|
||||
if (flags.isInOut())
|
||||
return true;
|
||||
|
||||
argElts.push_back({arg.getPlainType(), label});
|
||||
}
|
||||
|
||||
bindings[0].clear();
|
||||
|
||||
Reference in New Issue
Block a user