Merge remote-tracking branch 'origin/master' into master-next

This commit is contained in:
swift_jenkins
2019-12-16 14:09:55 -08:00
4 changed files with 63 additions and 112 deletions

View File

@@ -1741,17 +1741,6 @@ public:
llvm::function_ref<Type(const Expr *)> getType =
[](const Expr *E) -> Type { return E->getType(); });
/// Create a new dynamic subscript.
static DynamicSubscriptExpr *create(ASTContext &ctx, Expr *base,
SourceLoc lSquareLoc,
ArrayRef<Expr *> indexArgs,
ArrayRef<Identifier> indexArgLabels,
ArrayRef<SourceLoc> indexArgLabelLocs,
SourceLoc rSquareLoc,
Expr *trailingClosure,
ConcreteDeclRef decl,
bool implicit);
/// getIndex - Retrieve the index of the subscript expression, i.e., the
/// "offset" into the base value.
Expr *getIndex() const { return Index; }

View File

@@ -1504,33 +1504,6 @@ DynamicSubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index,
hasTrailingClosure, decl, implicit);
}
DynamicSubscriptExpr *
DynamicSubscriptExpr::create(ASTContext &ctx, Expr *base, SourceLoc lSquareLoc,
ArrayRef<Expr *> indexArgs,
ArrayRef<Identifier> indexArgLabels,
ArrayRef<SourceLoc> indexArgLabelLocs,
SourceLoc rSquareLoc,
Expr *trailingClosure,
ConcreteDeclRef decl,
bool implicit) {
SmallVector<Identifier, 4> indexArgLabelsScratch;
SmallVector<SourceLoc, 4> indexArgLabelLocsScratch;
Expr *index = packSingleArgument(ctx, lSquareLoc, indexArgs, indexArgLabels,
indexArgLabelLocs, rSquareLoc,
trailingClosure, implicit,
indexArgLabelsScratch,
indexArgLabelLocsScratch);
size_t size = totalSizeToAlloc(indexArgLabels, indexArgLabelLocs,
trailingClosure != nullptr);
void *memory = ctx.Allocate(size, alignof(DynamicSubscriptExpr));
return new (memory) DynamicSubscriptExpr(base, index, indexArgLabels,
indexArgLabelLocs,
trailingClosure != nullptr,
decl, implicit);
}
UnresolvedMemberExpr::UnresolvedMemberExpr(SourceLoc dotLoc,
DeclNameLoc nameLoc,
DeclNameRef name, Expr *argument,

View File

@@ -1228,41 +1228,13 @@ namespace {
bool hasTrailingClosure,
ConstraintLocatorBuilder locator, bool isImplicit,
AccessSemantics semantics,
Optional<SelectedOverload> selected = None) {
// Determine the declaration selected for this subscript operation.
if (!selected)
selected = solution.getOverloadChoiceIfAvailable(
cs.getConstraintLocator(
locator.withPathElement(
ConstraintLocator::SubscriptMember)));
// Handles situation where there was a solution available but it didn't
// have a proper overload selected from subscript call, might be because
// solver was allowed to return free or unresolved types, which can
// happen while running diagnostics on one of the expressions.
if (!selected.hasValue()) {
auto &de = cs.getASTContext().Diags;
auto baseType = cs.getType(base);
if (auto errorType = baseType->getAs<ErrorType>()) {
de.diagnose(base->getLoc(), diag::cannot_subscript_base,
errorType->getOriginalType())
.highlight(base->getSourceRange());
} else {
de.diagnose(base->getLoc(), diag::cannot_subscript_ambiguous_base)
.highlight(base->getSourceRange());
}
return nullptr;
}
const SelectedOverload &selected) {
// Build the new subscript.
auto newSubscript = buildSubscriptHelper(base, index, argLabels,
*selected, hasTrailingClosure,
selected, hasTrailingClosure,
locator, isImplicit, semantics);
if (selected->choice.getKind() == OverloadChoiceKind::DeclViaDynamic) {
if (selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic) {
// Rewrite for implicit unwrapping if the solution requires it.
auto *dynamicLocator = cs.getConstraintLocator(
locator, {ConstraintLocator::SubscriptMember,
@@ -1277,19 +1249,19 @@ namespace {
}
}
if (selected->choice.isDecl()) {
if (selected.choice.isDecl()) {
auto locatorKind = ConstraintLocator::SubscriptMember;
if (selected->choice.getKind() ==
if (selected.choice.getKind() ==
OverloadChoiceKind::DynamicMemberLookup)
locatorKind = ConstraintLocator::Member;
if (selected->choice.getKind() ==
if (selected.choice.getKind() ==
OverloadChoiceKind::KeyPathDynamicMemberLookup &&
!isa<SubscriptExpr>(locator.getAnchor()))
locatorKind = ConstraintLocator::Member;
newSubscript =
forceUnwrapIfExpected(newSubscript, selected->choice,
forceUnwrapIfExpected(newSubscript, selected.choice,
locator.withPathElement(locatorKind));
}
@@ -1298,7 +1270,7 @@ namespace {
Expr *buildSubscriptHelper(Expr *base, Expr *index,
ArrayRef<Identifier> argLabels,
SelectedOverload &selected,
const SelectedOverload &selected,
bool hasTrailingClosure,
ConstraintLocatorBuilder locator,
bool isImplicit, AccessSemantics semantics) {
@@ -2862,7 +2834,28 @@ namespace {
cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember);
auto overload = solution.getOverloadChoiceIfAvailable(memberLocator);
if (overload && overload->choice.getKind() ==
// Handles situation where there was a solution available but it didn't
// have a proper overload selected from subscript call, might be because
// solver was allowed to return free or unresolved types, which can
// happen while running diagnostics on one of the expressions.
if (!overload) {
const auto *base = expr->getBase();
auto &de = cs.getASTContext().Diags;
auto baseType = cs.getType(base);
if (auto errorType = baseType->getAs<ErrorType>()) {
de.diagnose(base->getLoc(), diag::cannot_subscript_base,
errorType->getOriginalType())
.highlight(base->getSourceRange());
} else {
de.diagnose(base->getLoc(), diag::cannot_subscript_ambiguous_base)
.highlight(base->getSourceRange());
}
return nullptr;
}
if (overload->choice.getKind() ==
OverloadChoiceKind::KeyPathDynamicMemberLookup) {
return buildDynamicMemberLookupRef(
expr, expr->getBase(), expr->getIndex()->getStartLoc(), SourceLoc(),
@@ -2872,7 +2865,7 @@ namespace {
return buildSubscript(
expr->getBase(), expr->getIndex(), expr->getArgumentLabels(),
expr->hasTrailingClosure(), cs.getConstraintLocator(expr),
expr->isImplicit(), expr->getAccessSemantics(), overload);
expr->isImplicit(), expr->getAccessSemantics(), *overload);
}
/// "Finish" an array expression by filling in the semantic expression.
@@ -2967,11 +2960,14 @@ namespace {
}
Expr *visitDynamicSubscriptExpr(DynamicSubscriptExpr *expr) {
auto *memberLocator =
cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember);
return buildSubscript(expr->getBase(), expr->getIndex(),
expr->getArgumentLabels(),
expr->hasTrailingClosure(),
cs.getConstraintLocator(expr),
expr->isImplicit(), AccessSemantics::Ordinary);
expr->isImplicit(), AccessSemantics::Ordinary,
solution.getOverloadChoice(memberLocator));
}
Expr *visitTupleElementExpr(TupleElementExpr *expr) {
@@ -4193,8 +4189,6 @@ namespace {
}
auto kind = origComponent.getKind();
Optional<SelectedOverload> foundDecl;
auto locator = cs.getConstraintLocator(
E, LocatorPathElt::KeyPathComponent(i));
@@ -4207,9 +4201,14 @@ namespace {
// If this is an unresolved link, make sure we resolved it.
if (kind == KeyPathExpr::Component::Kind::UnresolvedProperty ||
kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) {
foundDecl = solution.getOverloadChoiceIfAvailable(locator);
// Leave the component unresolved if the overload was not resolved.
if (foundDecl) {
auto foundDecl = solution.getOverloadChoiceIfAvailable(locator);
if (!foundDecl) {
// If we couldn't resolve the component, leave it alone.
resolvedComponents.push_back(origComponent);
baseTy = origComponent.getComponentType();
continue;
}
isDynamicMember =
foundDecl->choice.getKind() ==
OverloadChoiceKind::DynamicMemberLookup ||
@@ -4222,33 +4221,22 @@ namespace {
kind = KeyPathExpr::Component::Kind::UnresolvedSubscript;
}
}
}
switch (kind) {
case KeyPathExpr::Component::Kind::UnresolvedProperty: {
// If we couldn't resolve the component, leave it alone.
if (!foundDecl) {
resolvedComponents.push_back(origComponent);
break;
}
buildKeyPathPropertyComponent(*foundDecl, origComponent.getLoc(),
buildKeyPathPropertyComponent(solution.getOverloadChoice(locator),
origComponent.getLoc(),
locator, resolvedComponents);
break;
}
case KeyPathExpr::Component::Kind::UnresolvedSubscript: {
// Leave the component unresolved if the overload was not resolved.
if (!foundDecl) {
resolvedComponents.push_back(origComponent);
break;
}
ArrayRef<Identifier> subscriptLabels;
if (!isDynamicMember)
subscriptLabels = origComponent.getSubscriptLabels();
buildKeyPathSubscriptComponent(
*foundDecl, origComponent.getLoc(), origComponent.getIndexExpr(),
solution.getOverloadChoice(locator),
origComponent.getLoc(), origComponent.getIndexExpr(),
subscriptLabels, locator, resolvedComponents);
break;
}
@@ -4485,7 +4473,8 @@ namespace {
}
void buildKeyPathSubscriptComponent(
SelectedOverload &overload, SourceLoc componentLoc, Expr *indexExpr,
const SelectedOverload &overload,
SourceLoc componentLoc, Expr *indexExpr,
ArrayRef<Identifier> labels, ConstraintLocator *locator,
SmallVectorImpl<KeyPathExpr::Component> &components) {
auto subscript = cast<SubscriptDecl>(overload.choice.getDecl());

View File

@@ -471,19 +471,19 @@ enum class SolutionCompareResult {
/// declaration was opened, which may involve type variables.
struct SelectedOverload {
/// The overload choice.
OverloadChoice choice;
const OverloadChoice choice;
/// The opened type of the base of the reference to this overload, if
/// we're referencing a member.
Type openedFullType;
const Type openedFullType;
/// The opened type produced by referring to this overload.
Type openedType;
const Type openedType;
/// The type that this overload binds. Note that this may differ from
/// openedType, for example it will include any IUO unwrapping that has taken
/// place.
Type boundType;
const Type boundType;
};
/// Provides information about the application of a function argument to a