Skip to content

Commit 202cf2e

Browse files
committed
[SE-0111] Track function reference kinds in member references.
Extend the handling of function reference kinds to member references (e.g., x.f), and therefore the logic for stripping argument labels. We appear to be stripping argument labels from all of the places where it is required.
1 parent a953690 commit 202cf2e

13 files changed

+298
-89
lines changed

include/swift/AST/Expr.h

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,14 @@ class alignas(8) Expr {
205205
enum { NumTupleExprBits = NumExprBits + 3 };
206206
static_assert(NumTupleExprBits <= 32, "fits in an unsigned");
207207

208+
class UnresolvedDotExprBitfields {
209+
friend class UnresolvedDotExpr;
210+
unsigned : NumExprBits;
211+
unsigned FunctionRefKind : 2;
212+
};
213+
enum { NumUnresolvedDotExprExprBits = NumExprBits + 2 };
214+
static_assert(NumUnresolvedDotExprExprBits <= 32, "fits in an unsigned");
215+
208216
class SubscriptExprBitfields {
209217
friend class SubscriptExpr;
210218
unsigned : NumExprBits;
@@ -254,17 +262,17 @@ class alignas(8) Expr {
254262
class OverloadSetRefExprBitfields {
255263
friend class OverloadSetRefExpr;
256264
unsigned : NumExprBits;
265+
unsigned FunctionRefKind : 2;
257266
};
258-
enum { NumOverloadSetRefExprBits = NumExprBits };
267+
enum { NumOverloadSetRefExprBits = NumExprBits + 2};
259268
static_assert(NumOverloadSetRefExprBits <= 32, "fits in an unsigned");
260269

261270
class OverloadedDeclRefExprBitfields {
262271
friend class OverloadedDeclRefExpr;
263272
unsigned : NumOverloadSetRefExprBits;
264273
unsigned IsSpecialized : 1;
265-
unsigned FunctionRefKind : 2;
266274
};
267-
enum { NumOverloadedDeclRefExprBits = NumOverloadSetRefExprBits + 3 };
275+
enum { NumOverloadedDeclRefExprBits = NumOverloadSetRefExprBits + 1 };
268276
static_assert(NumOverloadedDeclRefExprBits <= 32, "fits in an unsigned");
269277

270278
class BooleanLiteralExprBitfields {
@@ -422,6 +430,7 @@ class alignas(8) Expr {
422430
UnresolvedDeclRefExprBitfields UnresolvedDeclRefExprBits;
423431
TupleExprBitfields TupleExprBits;
424432
MemberRefExprBitfields MemberRefExprBits;
433+
UnresolvedDotExprBitfields UnresolvedDotExprBits;
425434
SubscriptExprBitfields SubscriptExprBits;
426435
DynamicSubscriptExprBitfields DynamicSubscriptExprBits;
427436
UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
@@ -1400,9 +1409,12 @@ class OverloadSetRefExpr : public Expr {
14001409
ArrayRef<ValueDecl*> Decls;
14011410

14021411
protected:
1403-
OverloadSetRefExpr(ExprKind Kind, ArrayRef<ValueDecl*> decls, bool Implicit,
1404-
Type Ty)
1405-
: Expr(Kind, Implicit, Ty), Decls(decls) {}
1412+
OverloadSetRefExpr(ExprKind Kind, ArrayRef<ValueDecl*> decls,
1413+
FunctionRefKind functionRefKind, bool Implicit, Type Ty)
1414+
: Expr(Kind, Implicit, Ty), Decls(decls) {
1415+
OverloadSetRefExprBits.FunctionRefKind =
1416+
static_cast<unsigned>(functionRefKind);
1417+
}
14061418

14071419
public:
14081420
ArrayRef<ValueDecl*> getDecls() const { return Decls; }
@@ -1416,6 +1428,17 @@ class OverloadSetRefExpr : public Expr {
14161428
/// concrete base object (which is not a metatype).
14171429
bool hasBaseObject() const;
14181430

1431+
/// Retrieve the kind of function reference.
1432+
FunctionRefKind getFunctionRefKind() const {
1433+
return static_cast<FunctionRefKind>(
1434+
OverloadSetRefExprBits.FunctionRefKind);
1435+
}
1436+
1437+
/// Set the kind of function reference.
1438+
void setFunctionRefKind(FunctionRefKind refKind) {
1439+
OverloadSetRefExprBits.FunctionRefKind = static_cast<unsigned>(refKind);
1440+
}
1441+
14191442
static bool classof(const Expr *E) {
14201443
return E->getKind() >= ExprKind::First_OverloadSetRefExpr &&
14211444
E->getKind() <= ExprKind::Last_OverloadSetRefExpr;
@@ -1432,11 +1455,10 @@ class OverloadedDeclRefExpr final : public OverloadSetRefExpr {
14321455
bool isSpecialized,
14331456
FunctionRefKind functionRefKind,
14341457
bool Implicit, Type Ty = Type())
1435-
: OverloadSetRefExpr(ExprKind::OverloadedDeclRef, Decls, Implicit, Ty),
1458+
: OverloadSetRefExpr(ExprKind::OverloadedDeclRef, Decls, functionRefKind,
1459+
Implicit, Ty),
14361460
Loc(Loc) {
14371461
OverloadedDeclRefExprBits.IsSpecialized = isSpecialized;
1438-
OverloadedDeclRefExprBits.FunctionRefKind =
1439-
static_cast<unsigned>(functionRefKind);
14401462
}
14411463

14421464
DeclNameLoc getNameLoc() const { return Loc; }
@@ -1449,17 +1471,6 @@ class OverloadedDeclRefExpr final : public OverloadSetRefExpr {
14491471
return OverloadedDeclRefExprBits.IsSpecialized;
14501472
}
14511473

1452-
/// Retrieve the kind of function reference.
1453-
FunctionRefKind getFunctionRefKind() const {
1454-
return static_cast<FunctionRefKind>(
1455-
OverloadedDeclRefExprBits.FunctionRefKind);
1456-
}
1457-
1458-
/// Set the kind of function reference.
1459-
void setFunctionRefKind(FunctionRefKind refKind) {
1460-
OverloadedDeclRefExprBits.FunctionRefKind = static_cast<unsigned>(refKind);
1461-
}
1462-
14631474
static bool classof(const Expr *E) {
14641475
return E->getKind() == ExprKind::OverloadedDeclRef;
14651476
}
@@ -2317,8 +2328,12 @@ class UnresolvedDotExpr : public Expr {
23172328
public:
23182329
UnresolvedDotExpr(Expr *subexpr, SourceLoc dotloc, DeclName name,
23192330
DeclNameLoc nameloc, bool Implicit)
2320-
: Expr(ExprKind::UnresolvedDot, Implicit), SubExpr(subexpr), DotLoc(dotloc),
2321-
NameLoc(nameloc), Name(name) {}
2331+
: Expr(ExprKind::UnresolvedDot, Implicit), SubExpr(subexpr), DotLoc(dotloc),
2332+
NameLoc(nameloc), Name(name) {
2333+
UnresolvedDotExprBits.FunctionRefKind =
2334+
static_cast<unsigned>(NameLoc.isCompound() ? FunctionRefKind::Compound
2335+
: FunctionRefKind::Unapplied);
2336+
}
23222337

23232338
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
23242339

@@ -2337,6 +2352,16 @@ class UnresolvedDotExpr : public Expr {
23372352
DeclName getName() const { return Name; }
23382353
DeclNameLoc getNameLoc() const { return NameLoc; }
23392354

2355+
/// Retrieve the kind of function reference.
2356+
FunctionRefKind getFunctionRefKind() const {
2357+
return static_cast<FunctionRefKind>(UnresolvedDotExprBits.FunctionRefKind);
2358+
}
2359+
2360+
/// Set the kind of function reference.
2361+
void setFunctionRefKind(FunctionRefKind refKind) {
2362+
UnresolvedDotExprBits.FunctionRefKind = static_cast<unsigned>(refKind);
2363+
}
2364+
23402365
static bool classof(const Expr *E) {
23412366
return E->getKind() == ExprKind::UnresolvedDot;
23422367
}

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1860,7 +1860,8 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
18601860
}
18611861
void visitUnresolvedDotExpr(UnresolvedDotExpr *E) {
18621862
printCommon(E, "unresolved_dot_expr")
1863-
<< " field '" << E->getName() << "'";
1863+
<< " field '" << E->getName() << "'"
1864+
<< " function_ref=" << getFunctionRefKindStr(E->getFunctionRefKind());
18641865
if (E->getBase()) {
18651866
OS << '\n';
18661867
printRec(E->getBase());

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6787,6 +6787,7 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
67876787
= cs.getTypeOfMemberReference(base->getType(), witness,
67886788
/*isTypeReference=*/false,
67896789
/*isDynamicResult=*/false,
6790+
FunctionRefKind::DoubleApply,
67906791
dotLocator);
67916792

67926793
// Form the call argument.

lib/Sema/CSDiag.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,7 +2220,8 @@ bool FailureDiagnosis::diagnoseGeneralMemberFailure(Constraint *constraint) {
22202220

22212221
MemberLookupResult result =
22222222
CS->performMemberLookup(constraint->getKind(), constraint->getMember(),
2223-
baseTy, constraint->getLocator(),
2223+
baseTy, constraint->getFunctionRefKind(),
2224+
constraint->getLocator(),
22242225
/*includeInaccessibleMembers*/true);
22252226

22262227
switch (result.OverallResult) {
@@ -4535,7 +4536,7 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) {
45354536

45364537
MemberLookupResult result =
45374538
CS->performMemberLookup(ConstraintKind::ValueMember, subscriptName,
4538-
baseType, locator,
4539+
baseType, FunctionRefKind::DoubleApply, locator,
45394540
/*includeInaccessibleMembers*/true);
45404541

45414542

@@ -5716,7 +5717,9 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
57165717
MemberLookupResult result =
57175718
CS->performMemberLookup(memberConstraint->getKind(),
57185719
memberConstraint->getMember(),
5719-
baseObjTy, memberConstraint->getLocator(),
5720+
baseObjTy,
5721+
memberConstraint->getFunctionRefKind(),
5722+
memberConstraint->getLocator(),
57205723
/*includeInaccessibleMembers*/true);
57215724

57225725
switch (result.OverallResult) {

lib/Sema/CSGen.cpp

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ static Expr *skipImplicitConversions(Expr *expr) {
3434
}
3535

3636
/// \brief Find the declaration directly referenced by this expression.
37-
static ValueDecl *findReferencedDecl(Expr *expr, DeclNameLoc &loc) {
37+
static std::pair<ValueDecl *, FunctionRefKind>
38+
findReferencedDecl(Expr *expr, DeclNameLoc &loc) {
3839
do {
3940
expr = expr->getSemanticsProvidingExpr();
4041

@@ -45,10 +46,10 @@ static ValueDecl *findReferencedDecl(Expr *expr, DeclNameLoc &loc) {
4546

4647
if (auto dre = dyn_cast<DeclRefExpr>(expr)) {
4748
loc = dre->getNameLoc();
48-
return dre->getDecl();
49+
return { dre->getDecl(), dre->getFunctionRefKind() };
4950
}
5051

51-
return nullptr;
52+
return { nullptr, FunctionRefKind::Unapplied };
5253
} while (true);
5354
}
5455

@@ -1002,12 +1003,11 @@ namespace {
10021003
// The base must have a member of the given name, such that accessing
10031004
// that member through the base returns a value convertible to the type
10041005
// of this expression.
1005-
// FIXME: use functionRefKind
10061006
auto baseTy = base->getType();
10071007
auto tv = CS.createTypeVariable(
10081008
CS.getConstraintLocator(expr, ConstraintLocator::Member),
10091009
TVO_CanBindToLValue);
1010-
CS.addValueMemberConstraint(baseTy, name, tv,
1010+
CS.addValueMemberConstraint(baseTy, name, tv, functionRefKind,
10111011
CS.getConstraintLocator(expr, ConstraintLocator::Member));
10121012
return tv;
10131013
}
@@ -1119,11 +1119,12 @@ namespace {
11191119
// UnresolvedSubscriptExpr from SubscriptExpr.
11201120
if (decl) {
11211121
OverloadChoice choice(base->getType(), decl, /*isSpecialized=*/false,
1122-
FunctionRefKind::SingleApply);
1122+
FunctionRefKind::DoubleApply);
11231123
CS.addBindOverloadConstraint(fnTy, choice, subscriptMemberLocator);
11241124
} else {
11251125
CS.addValueMemberConstraint(baseTy, Context.Id_subscript,
1126-
fnTy, subscriptMemberLocator);
1126+
fnTy, FunctionRefKind::DoubleApply,
1127+
subscriptMemberLocator);
11271128
}
11281129

11291130
// Add the constraint that the index expression's type be convertible
@@ -1208,13 +1209,15 @@ namespace {
12081209
segment->getType(),
12091210
segmentTyV,
12101211
Identifier(),
1212+
FunctionRefKind::Compound,
12111213
locator));
12121214

12131215
DeclName segmentName(C, C.Id_init, { C.Id_stringInterpolationSegment });
12141216
CS.addConstraint(Constraint::create(CS, ConstraintKind::ValueMember,
12151217
tvMeta,
12161218
methodTy,
12171219
segmentName,
1220+
FunctionRefKind::DoubleApply,
12181221
locator));
12191222

12201223
}
@@ -1384,7 +1387,7 @@ namespace {
13841387

13851388
choices.push_back(OverloadChoice(Type(), decls[i],
13861389
expr->isSpecialized(),
1387-
/*FIXME:*/FunctionRefKind::DoubleApply));
1390+
expr->getFunctionRefKind()));
13881391
}
13891392

13901393
// If there are no valid overloads, give up.
@@ -1420,6 +1423,10 @@ namespace {
14201423
auto baseLocator = CS.getConstraintLocator(
14211424
expr,
14221425
ConstraintLocator::MemberRefBase);
1426+
FunctionRefKind functionRefKind =
1427+
expr->getArgument() ? FunctionRefKind::DoubleApply
1428+
: FunctionRefKind::Compound;
1429+
14231430
auto memberLocator
14241431
= CS.getConstraintLocator(expr, ConstraintLocator::UnresolvedMember);
14251432
auto baseTy = CS.createTypeVariable(baseLocator, /*options=*/0);
@@ -1434,7 +1441,8 @@ namespace {
14341441
// member, i.e., an enum case or a static variable.
14351442
auto baseMetaTy = MetatypeType::get(baseTy);
14361443
CS.addUnresolvedValueMemberConstraint(baseMetaTy, expr->getName(),
1437-
memberTy, memberLocator);
1444+
memberTy, functionRefKind,
1445+
memberLocator);
14381446

14391447
// If there is an argument, apply it.
14401448
if (auto arg = expr->getArgument()) {
@@ -1494,7 +1502,7 @@ namespace {
14941502
/*options=*/0);
14951503
auto methodTy = FunctionType::get(argsTy, resultTy);
14961504
CS.addValueMemberConstraint(baseTy, expr->getName(),
1497-
methodTy,
1505+
methodTy, expr->getFunctionRefKind(),
14981506
CS.getConstraintLocator(expr, ConstraintLocator::ConstructorMember));
14991507

15001508
// The result of the expression is the partial application of the
@@ -1503,7 +1511,7 @@ namespace {
15031511
}
15041512

15051513
return addMemberRefConstraints(expr, expr->getBase(), expr->getName(),
1506-
/*FIXME:*/FunctionRefKind::DoubleApply);
1514+
expr->getFunctionRefKind());
15071515
}
15081516

15091517
Type visitUnresolvedSpecializeExpr(UnresolvedSpecializeExpr *expr) {
@@ -2495,7 +2503,9 @@ namespace {
24952503
if (CS.shouldAttemptFixes()) {
24962504
Constraint *coerceConstraint =
24972505
Constraint::create(CS, ConstraintKind::ExplicitConversion,
2498-
fromType, toType, DeclName(), locator);
2506+
fromType, toType, DeclName(),
2507+
FunctionRefKind::Compound,
2508+
locator);
24992509
Constraint *downcastConstraint =
25002510
Constraint::createFixed(CS, ConstraintKind::CheckedCast,
25012511
FixKind::CoerceToCheckedCast, fromType,
@@ -2730,10 +2740,14 @@ namespace {
27302740
// type-checked down to a call; turn it back into an overloaded
27312741
// member reference expression.
27322742
DeclNameLoc memberLoc;
2733-
if (auto member = findReferencedDecl(dotCall->getFn(), memberLoc)) {
2743+
auto memberAndFunctionRef = findReferencedDecl(dotCall->getFn(),
2744+
memberLoc);
2745+
if (memberAndFunctionRef.first) {
27342746
auto base = skipImplicitConversions(dotCall->getArg());
27352747
return new (TC.Context) MemberRefExpr(base,
2736-
dotCall->getDotLoc(), member, memberLoc,
2748+
dotCall->getDotLoc(),
2749+
memberAndFunctionRef.first,
2750+
memberLoc,
27372751
expr->isImplicit());
27382752
}
27392753
}
@@ -2744,10 +2758,13 @@ namespace {
27442758
// actually matter; turn it back into an overloaded member reference
27452759
// expression.
27462760
DeclNameLoc memberLoc;
2747-
if (auto member = findReferencedDecl(dotIgnored->getRHS(), memberLoc)) {
2761+
auto memberAndFunctionRef = findReferencedDecl(dotIgnored->getRHS(),
2762+
memberLoc);
2763+
if (memberAndFunctionRef.first) {
27482764
auto base = skipImplicitConversions(dotIgnored->getLHS());
27492765
return new (TC.Context) MemberRefExpr(base,
2750-
dotIgnored->getDotLoc(), member,
2766+
dotIgnored->getDotLoc(),
2767+
memberAndFunctionRef.first,
27512768
memberLoc, expr->isImplicit());
27522769
}
27532770
}
@@ -3073,9 +3090,9 @@ Type swift::checkMemberType(DeclContext &DC, Type BaseTy,
30733090
TypeVariableOptions::TVO_CanBindToLValue);
30743091
CS.addConstraint(Constraint::createDisjunction(CS, {
30753092
Constraint::create(CS, ConstraintKind::TypeMember, Ty,
3076-
TV, DeclName(Id), Loc),
3093+
TV, DeclName(Id), FunctionRefKind::Compound, Loc),
30773094
Constraint::create(CS, ConstraintKind::ValueMember, Ty,
3078-
TV, DeclName(Id), Loc)
3095+
TV, DeclName(Id), FunctionRefKind::DoubleApply, Loc)
30793096
}, Loc));
30803097
Ty = TV;
30813098
}
@@ -3172,7 +3189,8 @@ bool swift::isExtensionApplied(DeclContext &DC, Type BaseTy,
31723189
return;
31733190
}
31743191
// Add constraints accordingly.
3175-
CS.addConstraint(Constraint::create(CS, Kind, First, Second, DeclName(), Loc));
3192+
CS.addConstraint(Constraint::create(CS, Kind, First, Second, DeclName(),
3193+
FunctionRefKind::Compound, Loc));
31763194
};
31773195

31783196
// For every requirement, add a constraint.
@@ -3221,6 +3239,7 @@ static bool canSatisfy(Type T1, Type T2, DeclContext &DC, ConstraintKind Kind,
32213239
T2 = T2.transform(Trans);
32223240
}
32233241
CS.addConstraint(Constraint::create(CS, Kind, T1, T2, DeclName(),
3242+
FunctionRefKind::Compound,
32243243
CS.getConstraintLocator(nullptr)));
32253244
SmallVector<Solution, 4> Solutions;
32263245
return AllowFreeVariables ?
@@ -3252,7 +3271,8 @@ swift::resolveValueMember(DeclContext &DC, Type BaseTy, DeclName Name) {
32523271
}
32533272
ConstraintSystem CS(*TC, &DC, None);
32543273
MemberLookupResult LookupResult = CS.performMemberLookup(
3255-
ConstraintKind::ValueMember, Name, BaseTy, nullptr, false);
3274+
ConstraintKind::ValueMember, Name, BaseTy, FunctionRefKind::DoubleApply,
3275+
nullptr, false);
32563276
if (LookupResult.ViableCandidates.empty())
32573277
return Result;
32583278
ConstraintLocator *Locator = CS.getConstraintLocator(nullptr);

0 commit comments

Comments
 (0)