Pass the indices for writeback-conflict diagnostics on coroutines.

To do this, I had to introduce a way to unsafely copy an argument
list for the purposes of diagnostics.

rdar:://43802132
This commit is contained in:
John McCall
2018-08-31 04:18:20 -04:00
parent 123d27d4a8
commit dd77a2037e
6 changed files with 85 additions and 9 deletions

View File

@@ -473,3 +473,38 @@ bool ArgumentSource::isObviouslyEqual(const ArgumentSource &other) const {
}
llvm_unreachable("bad kind");
}
PreparedArguments PreparedArguments::copyForDiagnostics() const {
if (isNull())
return PreparedArguments();
assert(isValid());
PreparedArguments result(getFormalType(), isScalar());
for (auto &arg : Arguments) {
result.Arguments.push_back(arg.copyForDiagnostics());
}
return result;
}
ArgumentSource ArgumentSource::copyForDiagnostics() const {
switch (StoredKind) {
case Kind::Invalid:
return ArgumentSource();
case Kind::LValue:
// We have no way to copy an l-value for diagnostics.
return {getKnownLValueLocation(), LValue()};
case Kind::RValue:
return {getKnownRValueLocation(), asKnownRValue().copyForDiagnostics()};
case Kind::Expr:
return asKnownExpr();
case Kind::Tuple: {
auto &tuple = Storage.get<TupleStorage>(StoredKind);
SmallVector<ArgumentSource, 4> copiedElements;
for (auto &elt : tuple.Elements) {
copiedElements.push_back(elt.copyForDiagnostics());
}
return {tuple.Loc, tuple.SubstType, copiedElements};
}
}
llvm_unreachable("bad kind");
}