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 = llvm::function_ref<Type(const Expr *)> getType =
[](const Expr *E) -> Type { return E->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 /// getIndex - Retrieve the index of the subscript expression, i.e., the
/// "offset" into the base value. /// "offset" into the base value.
Expr *getIndex() const { return Index; } Expr *getIndex() const { return Index; }

View File

@@ -1504,33 +1504,6 @@ DynamicSubscriptExpr::create(ASTContext &ctx, Expr *base, Expr *index,
hasTrailingClosure, decl, implicit); 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, UnresolvedMemberExpr::UnresolvedMemberExpr(SourceLoc dotLoc,
DeclNameLoc nameLoc, DeclNameLoc nameLoc,
DeclNameRef name, Expr *argument, DeclNameRef name, Expr *argument,

View File

@@ -1228,41 +1228,13 @@ namespace {
bool hasTrailingClosure, bool hasTrailingClosure,
ConstraintLocatorBuilder locator, bool isImplicit, ConstraintLocatorBuilder locator, bool isImplicit,
AccessSemantics semantics, AccessSemantics semantics,
Optional<SelectedOverload> selected = None) { const SelectedOverload &selected) {
// 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;
}
// Build the new subscript. // Build the new subscript.
auto newSubscript = buildSubscriptHelper(base, index, argLabels, auto newSubscript = buildSubscriptHelper(base, index, argLabels,
*selected, hasTrailingClosure, selected, hasTrailingClosure,
locator, isImplicit, semantics); locator, isImplicit, semantics);
if (selected->choice.getKind() == OverloadChoiceKind::DeclViaDynamic) { if (selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic) {
// Rewrite for implicit unwrapping if the solution requires it. // Rewrite for implicit unwrapping if the solution requires it.
auto *dynamicLocator = cs.getConstraintLocator( auto *dynamicLocator = cs.getConstraintLocator(
locator, {ConstraintLocator::SubscriptMember, locator, {ConstraintLocator::SubscriptMember,
@@ -1277,19 +1249,19 @@ namespace {
} }
} }
if (selected->choice.isDecl()) { if (selected.choice.isDecl()) {
auto locatorKind = ConstraintLocator::SubscriptMember; auto locatorKind = ConstraintLocator::SubscriptMember;
if (selected->choice.getKind() == if (selected.choice.getKind() ==
OverloadChoiceKind::DynamicMemberLookup) OverloadChoiceKind::DynamicMemberLookup)
locatorKind = ConstraintLocator::Member; locatorKind = ConstraintLocator::Member;
if (selected->choice.getKind() == if (selected.choice.getKind() ==
OverloadChoiceKind::KeyPathDynamicMemberLookup && OverloadChoiceKind::KeyPathDynamicMemberLookup &&
!isa<SubscriptExpr>(locator.getAnchor())) !isa<SubscriptExpr>(locator.getAnchor()))
locatorKind = ConstraintLocator::Member; locatorKind = ConstraintLocator::Member;
newSubscript = newSubscript =
forceUnwrapIfExpected(newSubscript, selected->choice, forceUnwrapIfExpected(newSubscript, selected.choice,
locator.withPathElement(locatorKind)); locator.withPathElement(locatorKind));
} }
@@ -1298,7 +1270,7 @@ namespace {
Expr *buildSubscriptHelper(Expr *base, Expr *index, Expr *buildSubscriptHelper(Expr *base, Expr *index,
ArrayRef<Identifier> argLabels, ArrayRef<Identifier> argLabels,
SelectedOverload &selected, const SelectedOverload &selected,
bool hasTrailingClosure, bool hasTrailingClosure,
ConstraintLocatorBuilder locator, ConstraintLocatorBuilder locator,
bool isImplicit, AccessSemantics semantics) { bool isImplicit, AccessSemantics semantics) {
@@ -2862,8 +2834,29 @@ namespace {
cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember); cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember);
auto overload = solution.getOverloadChoiceIfAvailable(memberLocator); auto overload = solution.getOverloadChoiceIfAvailable(memberLocator);
if (overload && overload->choice.getKind() == // Handles situation where there was a solution available but it didn't
OverloadChoiceKind::KeyPathDynamicMemberLookup) { // 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( return buildDynamicMemberLookupRef(
expr, expr->getBase(), expr->getIndex()->getStartLoc(), SourceLoc(), expr, expr->getBase(), expr->getIndex()->getStartLoc(), SourceLoc(),
*overload, memberLocator); *overload, memberLocator);
@@ -2872,7 +2865,7 @@ namespace {
return buildSubscript( return buildSubscript(
expr->getBase(), expr->getIndex(), expr->getArgumentLabels(), expr->getBase(), expr->getIndex(), expr->getArgumentLabels(),
expr->hasTrailingClosure(), cs.getConstraintLocator(expr), 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. /// "Finish" an array expression by filling in the semantic expression.
@@ -2967,11 +2960,14 @@ namespace {
} }
Expr *visitDynamicSubscriptExpr(DynamicSubscriptExpr *expr) { Expr *visitDynamicSubscriptExpr(DynamicSubscriptExpr *expr) {
auto *memberLocator =
cs.getConstraintLocator(expr, ConstraintLocator::SubscriptMember);
return buildSubscript(expr->getBase(), expr->getIndex(), return buildSubscript(expr->getBase(), expr->getIndex(),
expr->getArgumentLabels(), expr->getArgumentLabels(),
expr->hasTrailingClosure(), expr->hasTrailingClosure(),
cs.getConstraintLocator(expr), cs.getConstraintLocator(expr),
expr->isImplicit(), AccessSemantics::Ordinary); expr->isImplicit(), AccessSemantics::Ordinary,
solution.getOverloadChoice(memberLocator));
} }
Expr *visitTupleElementExpr(TupleElementExpr *expr) { Expr *visitTupleElementExpr(TupleElementExpr *expr) {
@@ -4193,8 +4189,6 @@ namespace {
} }
auto kind = origComponent.getKind(); auto kind = origComponent.getKind();
Optional<SelectedOverload> foundDecl;
auto locator = cs.getConstraintLocator( auto locator = cs.getConstraintLocator(
E, LocatorPathElt::KeyPathComponent(i)); E, LocatorPathElt::KeyPathComponent(i));
@@ -4207,48 +4201,42 @@ namespace {
// If this is an unresolved link, make sure we resolved it. // If this is an unresolved link, make sure we resolved it.
if (kind == KeyPathExpr::Component::Kind::UnresolvedProperty || if (kind == KeyPathExpr::Component::Kind::UnresolvedProperty ||
kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) { kind == KeyPathExpr::Component::Kind::UnresolvedSubscript) {
foundDecl = solution.getOverloadChoiceIfAvailable(locator); auto foundDecl = solution.getOverloadChoiceIfAvailable(locator);
// Leave the component unresolved if the overload was not resolved. if (!foundDecl) {
if (foundDecl) { // If we couldn't resolve the component, leave it alone.
isDynamicMember = resolvedComponents.push_back(origComponent);
foundDecl->choice.getKind() == baseTy = origComponent.getComponentType();
OverloadChoiceKind::DynamicMemberLookup || continue;
foundDecl->choice.getKind() == }
OverloadChoiceKind::KeyPathDynamicMemberLookup;
// If this was a @dynamicMemberLookup property, then we actually isDynamicMember =
// form a subscript reference, so switch the kind. foundDecl->choice.getKind() ==
if (isDynamicMember) { OverloadChoiceKind::DynamicMemberLookup ||
kind = KeyPathExpr::Component::Kind::UnresolvedSubscript; foundDecl->choice.getKind() ==
} OverloadChoiceKind::KeyPathDynamicMemberLookup;
// If this was a @dynamicMemberLookup property, then we actually
// form a subscript reference, so switch the kind.
if (isDynamicMember) {
kind = KeyPathExpr::Component::Kind::UnresolvedSubscript;
} }
} }
switch (kind) { switch (kind) {
case KeyPathExpr::Component::Kind::UnresolvedProperty: { case KeyPathExpr::Component::Kind::UnresolvedProperty: {
// If we couldn't resolve the component, leave it alone. buildKeyPathPropertyComponent(solution.getOverloadChoice(locator),
if (!foundDecl) { origComponent.getLoc(),
resolvedComponents.push_back(origComponent);
break;
}
buildKeyPathPropertyComponent(*foundDecl, origComponent.getLoc(),
locator, resolvedComponents); locator, resolvedComponents);
break; break;
} }
case KeyPathExpr::Component::Kind::UnresolvedSubscript: { 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; ArrayRef<Identifier> subscriptLabels;
if (!isDynamicMember) if (!isDynamicMember)
subscriptLabels = origComponent.getSubscriptLabels(); subscriptLabels = origComponent.getSubscriptLabels();
buildKeyPathSubscriptComponent( buildKeyPathSubscriptComponent(
*foundDecl, origComponent.getLoc(), origComponent.getIndexExpr(), solution.getOverloadChoice(locator),
origComponent.getLoc(), origComponent.getIndexExpr(),
subscriptLabels, locator, resolvedComponents); subscriptLabels, locator, resolvedComponents);
break; break;
} }
@@ -4485,7 +4473,8 @@ namespace {
} }
void buildKeyPathSubscriptComponent( void buildKeyPathSubscriptComponent(
SelectedOverload &overload, SourceLoc componentLoc, Expr *indexExpr, const SelectedOverload &overload,
SourceLoc componentLoc, Expr *indexExpr,
ArrayRef<Identifier> labels, ConstraintLocator *locator, ArrayRef<Identifier> labels, ConstraintLocator *locator,
SmallVectorImpl<KeyPathExpr::Component> &components) { SmallVectorImpl<KeyPathExpr::Component> &components) {
auto subscript = cast<SubscriptDecl>(overload.choice.getDecl()); auto subscript = cast<SubscriptDecl>(overload.choice.getDecl());

View File

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