mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ConstraintSystem] Fix out-of-order arguments
Detect and fix out-of-order arguments by moving them into correct positions.
This commit is contained in:
@@ -371,3 +371,14 @@ AddMissingArguments::create(ConstraintSystem &cs, FunctionType *funcType,
|
||||
void *mem = cs.getAllocator().Allocate(size, alignof(AddMissingArguments));
|
||||
return new (mem) AddMissingArguments(cs, funcType, synthesizedArgs, locator);
|
||||
}
|
||||
|
||||
bool MoveOutOfOrderArgument::diagnose(Expr *root, bool asNote) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
MoveOutOfOrderArgument *MoveOutOfOrderArgument::create(
|
||||
ConstraintSystem &cs, unsigned argIdx, unsigned prevArgIdx,
|
||||
ArrayRef<ParamBinding> bindings, ConstraintLocator *locator) {
|
||||
return new (cs.getAllocator())
|
||||
MoveOutOfOrderArgument(cs, argIdx, prevArgIdx, bindings, locator);
|
||||
}
|
||||
|
||||
@@ -129,6 +129,9 @@ enum class FixKind : uint8_t {
|
||||
|
||||
/// Allow single tuple closure parameter destructuring into N arguments.
|
||||
AllowClosureParameterDestructuring,
|
||||
|
||||
/// If there is out-of-order argument, let's fix that by re-ordering.
|
||||
MoveOutOfOrderArgument,
|
||||
};
|
||||
|
||||
class ConstraintFix {
|
||||
@@ -681,6 +684,35 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class MoveOutOfOrderArgument final : public ConstraintFix {
|
||||
using ParamBinding = SmallVector<unsigned, 1>;
|
||||
|
||||
unsigned ArgIdx;
|
||||
unsigned PrevArgIdx;
|
||||
|
||||
SmallVector<ParamBinding, 4> Bindings;
|
||||
|
||||
MoveOutOfOrderArgument(ConstraintSystem &cs, unsigned argIdx,
|
||||
unsigned prevArgIdx, ArrayRef<ParamBinding> bindings,
|
||||
ConstraintLocator *locator)
|
||||
: ConstraintFix(cs, FixKind::MoveOutOfOrderArgument, locator),
|
||||
ArgIdx(argIdx), PrevArgIdx(prevArgIdx),
|
||||
Bindings(bindings.begin(), bindings.end()) {}
|
||||
|
||||
public:
|
||||
std::string getName() const override {
|
||||
return "move out-of-order argument to correct position";
|
||||
}
|
||||
|
||||
bool diagnose(Expr *root, bool asNote = false) const override;
|
||||
|
||||
static MoveOutOfOrderArgument *create(ConstraintSystem &cs,
|
||||
unsigned argIdx,
|
||||
unsigned prevArgIdx,
|
||||
ArrayRef<ParamBinding> bindings,
|
||||
ConstraintLocator *locator);
|
||||
};
|
||||
|
||||
} // end namespace constraints
|
||||
} // end namespace swift
|
||||
|
||||
|
||||
@@ -855,11 +855,14 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
|
||||
|
||||
class ArgumentFailureTracker : public MatchCallArgumentListener {
|
||||
ConstraintSystem &CS;
|
||||
SmallVectorImpl<ParamBinding> &Bindings;
|
||||
ConstraintLocatorBuilder Locator;
|
||||
|
||||
public:
|
||||
ArgumentFailureTracker(ConstraintSystem &cs, ConstraintLocatorBuilder locator)
|
||||
: CS(cs), Locator(locator) {}
|
||||
ArgumentFailureTracker(ConstraintSystem &cs,
|
||||
SmallVectorImpl<ParamBinding> &bindings,
|
||||
ConstraintLocatorBuilder locator)
|
||||
: CS(cs), Bindings(bindings), Locator(locator) {}
|
||||
|
||||
bool missingLabel(unsigned paramIndex) override {
|
||||
return !CS.shouldAttemptFixes();
|
||||
@@ -873,6 +876,16 @@ public:
|
||||
return !CS.shouldAttemptFixes();
|
||||
}
|
||||
|
||||
bool outOfOrderArgument(unsigned argIdx, unsigned prevArgIdx) override {
|
||||
if (CS.shouldAttemptFixes()) {
|
||||
auto *fix = MoveOutOfOrderArgument::create(
|
||||
CS, argIdx, prevArgIdx, Bindings, CS.getConstraintLocator(Locator));
|
||||
return CS.recordFix(fix);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool relabelArguments(ArrayRef<Identifier> newLabels) override {
|
||||
if (!CS.shouldAttemptFixes())
|
||||
return true;
|
||||
@@ -940,8 +953,8 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
|
||||
}
|
||||
|
||||
// Match up the call arguments to the parameters.
|
||||
ArgumentFailureTracker listener(cs, locator);
|
||||
SmallVector<ParamBinding, 4> parameterBindings;
|
||||
ArgumentFailureTracker listener(cs, parameterBindings, locator);
|
||||
if (constraints::matchCallArguments(argsWithLabels, params,
|
||||
defaultMap,
|
||||
hasTrailingClosure,
|
||||
@@ -6022,6 +6035,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
|
||||
case FixKind::AllowInvalidPartialApplication:
|
||||
case FixKind::AllowInvalidInitRef:
|
||||
case FixKind::AllowClosureParameterDestructuring:
|
||||
case FixKind::MoveOutOfOrderArgument:
|
||||
llvm_unreachable("handled elsewhere");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user