mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/master' into master-next
This commit is contained in:
@@ -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; }
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user