Skip to content

Commit 0b77871

Browse files
authored
Merge pull request #4182 from akyrtzi/se-0111-followup
Follow-up for fixing IDE/SourceKit tests after changes for [SE-0111]
2 parents 420088f + d187609 commit 0b77871

26 files changed

+200
-278
lines changed

include/swift/AST/Decl.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4250,6 +4250,9 @@ class VarDecl : public AbstractStorageDecl {
42504250
setType(Ty);
42514251
}
42524252

4253+
/// This is the type specified, including location information.
4254+
TypeLoc typeLoc;
4255+
42534256
public:
42544257
VarDecl(bool IsStatic, bool IsLet, SourceLoc NameLoc, Identifier Name,
42554258
Type Ty, DeclContext *DC)
@@ -4264,6 +4267,9 @@ class VarDecl : public AbstractStorageDecl {
42644267
bool isUserAccessible() const {
42654268
return VarDeclBits.IsUserAccessible;
42664269
}
4270+
4271+
TypeLoc &getTypeLoc() { return typeLoc; }
4272+
TypeLoc getTypeLoc() const { return typeLoc; }
42674273

42684274
/// Retrieve the source range of the variable type, or an invalid range if the
42694275
/// variable's type is not explicitly written in the source.
@@ -4391,9 +4397,6 @@ class ParamDecl : public VarDecl {
43914397
SourceLoc ArgumentNameLoc;
43924398
SourceLoc LetVarInOutLoc;
43934399

4394-
/// This is the type specified, including location information.
4395-
TypeLoc typeLoc;
4396-
43974400
/// The default value, if any, along with whether this is varargs.
43984401
llvm::PointerIntPair<ExprHandle *, 1, bool> DefaultValueAndIsVariadic;
43994402

@@ -4427,9 +4430,6 @@ class ParamDecl : public VarDecl {
44274430
SourceLoc getArgumentNameLoc() const { return ArgumentNameLoc; }
44284431

44294432
SourceLoc getLetVarInOutLoc() const { return LetVarInOutLoc; }
4430-
4431-
TypeLoc &getTypeLoc() { return typeLoc; }
4432-
TypeLoc getTypeLoc() const { return typeLoc; }
44334433

44344434
bool isTypeLocImplicit() const { return IsTypeLocImplicit; }
44354435
void setIsTypeLocImplicit(bool val) { IsTypeLocImplicit = val; }

include/swift/AST/PrintOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ struct PrintOptions {
425425
result.AbstractAccessors = false;
426426
result.PrintForSIL = true;
427427
result.PrintInSILBody = true;
428+
result.PreferTypeRepr = false;
428429
return result;
429430
}
430431

include/swift/AST/TypeRepr.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,32 +580,47 @@ class TupleTypeRepr : public TypeRepr {
580580
friend class TypeRepr;
581581
};
582582

583-
/// \brief A named element of a tuple type.
583+
/// \brief A named element of a tuple type or a named parameter of a function
584+
/// type.
584585
/// \code
585-
/// (x: Foo = 0)
586+
/// (x: Foo)
587+
/// (_ x: Foo) -> ()
586588
/// \endcode
587589
class NamedTypeRepr : public TypeRepr {
588590
Identifier Id;
589591
TypeRepr *Ty;
590592
SourceLoc IdLoc;
593+
SourceLoc UnderscoreLoc;
591594

592595
public:
596+
/// Used for a named element of a tuple type.
593597
NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc)
594598
: TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc) {
595599
}
600+
/// Used for a named parameter of a function type.
601+
NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc,
602+
SourceLoc underscoreLoc)
603+
: TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc),
604+
UnderscoreLoc(underscoreLoc) {
605+
}
596606

597607
bool hasName() const { return !Id.empty(); }
598608
Identifier getName() const { return Id; }
599609
TypeRepr *getTypeRepr() const { return Ty; }
600610
SourceLoc getNameLoc() const { return IdLoc; }
611+
SourceLoc getUnderscoreLoc() const { return UnderscoreLoc; }
612+
613+
bool isNamedParameter() const { return UnderscoreLoc.isValid(); }
601614

602615
static bool classof(const TypeRepr *T) {
603616
return T->getKind() == TypeReprKind::Named;
604617
}
605618
static bool classof(const NamedTypeRepr *T) { return true; }
606619

607620
private:
608-
SourceLoc getStartLocImpl() const { return IdLoc; }
621+
SourceLoc getStartLocImpl() const {
622+
return UnderscoreLoc.isValid() ? UnderscoreLoc : IdLoc;
623+
}
609624
SourceLoc getEndLocImpl() const { return Ty->getEndLoc(); }
610625
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
611626
friend class TypeRepr;

lib/AST/ASTPrinter.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,8 +2516,10 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
25162516
});
25172517
if (decl->hasType()) {
25182518
Printer << ": ";
2519-
// Use the non-repr external type, but reuse the TypeLoc printing code.
2520-
printTypeLoc(TypeLoc::withoutLoc(decl->getType()));
2519+
auto tyLoc = decl->getTypeLoc();
2520+
if (!tyLoc.getTypeRepr())
2521+
tyLoc = TypeLoc::withoutLoc(decl->getType());
2522+
printTypeLoc(tyLoc);
25212523
}
25222524

25232525
printAccessors(decl);
@@ -2777,10 +2779,19 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {
27772779

27782780
Type ResultTy = decl->getResultType();
27792781
if (ResultTy && !ResultTy->isVoid()) {
2782+
TypeLoc ResultTyLoc = decl->getBodyResultTypeLoc();
2783+
if (!ResultTyLoc.getTypeRepr())
2784+
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
2785+
// FIXME: Hacky way to workaround the fact that 'Self' as return
2786+
// TypeRepr is not getting 'typechecked'. See
2787+
// \c resolveTopLevelIdentTypeComponent function in TypeCheckType.cpp.
2788+
if (auto *simId = dyn_cast_or_null<SimpleIdentTypeRepr>(ResultTyLoc.getTypeRepr())) {
2789+
if (simId->getIdentifier().str() == "Self")
2790+
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
2791+
}
27802792
Printer << " -> ";
2781-
// Use the non-repr external type, but reuse the TypeLoc printing code.
27822793
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
2783-
printTypeLoc(TypeLoc::withoutLoc(ResultTy));
2794+
printTypeLoc(ResultTyLoc);
27842795
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
27852796
}
27862797
}
@@ -3233,6 +3244,9 @@ void Decl::print(raw_ostream &os) const {
32333244
options.FunctionDefinitions = true;
32343245
options.TypeDefinitions = true;
32353246
options.VarInitializers = true;
3247+
// FIXME: Move all places where SIL printing is happening to explicit options.
3248+
// For example, see \c ProjectionPath::print.
3249+
options.PreferTypeRepr = false;
32363250

32373251
print(os, options);
32383252
}
@@ -3749,10 +3763,14 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37493763
if (Options.SkipAttributes)
37503764
return;
37513765

3752-
if (info.isAutoClosure())
3753-
Printer << "@autoclosure ";
3754-
if (inParameterPrinting && !info.isNoEscape())
3755-
Printer << "@escaping ";
3766+
if (info.isAutoClosure()) {
3767+
Printer.printAttrName("@autoclosure");
3768+
Printer << " ";
3769+
}
3770+
if (inParameterPrinting && !info.isNoEscape()) {
3771+
Printer.printAttrName("@escaping");
3772+
Printer << " ";
3773+
}
37563774

37573775
if (Options.PrintFunctionRepresentationAttrs) {
37583776
// TODO: coalesce into a single convention attribute.

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3729,10 +3729,10 @@ ParamDecl::ParamDecl(ParamDecl *PD)
37293729
ArgumentName(PD->getArgumentName()),
37303730
ArgumentNameLoc(PD->getArgumentNameLoc()),
37313731
LetVarInOutLoc(PD->getLetVarInOutLoc()),
3732-
typeLoc(PD->getTypeLoc()),
37333732
DefaultValueAndIsVariadic(PD->DefaultValueAndIsVariadic),
37343733
IsTypeLocImplicit(PD->IsTypeLocImplicit),
37353734
defaultArgumentKind(PD->defaultArgumentKind) {
3735+
typeLoc = PD->getTypeLoc();
37363736
}
37373737

37383738

lib/AST/TypeRepr.cpp

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ TypeRepr *CloneVisitor::visitTupleTypeRepr(TupleTypeRepr *T) {
198198

199199
TypeRepr *CloneVisitor::visitNamedTypeRepr(NamedTypeRepr *T) {
200200
return new (Ctx) NamedTypeRepr(T->getName(), visit(T->getTypeRepr()),
201-
T->getNameLoc());
201+
T->getNameLoc(), T->getUnderscoreLoc());
202202
}
203203

204204
TypeRepr *CloneVisitor::visitProtocolCompositionTypeRepr(
@@ -276,13 +276,26 @@ void AttributedTypeRepr::printAttrs(llvm::raw_ostream &OS) const {
276276
void AttributedTypeRepr::printAttrs(ASTPrinter &Printer) const {
277277
const TypeAttributes &Attrs = getAttrs();
278278

279-
if (Attrs.has(TAK_autoclosure)) Printer << "@autoclosure ";
280-
if (Attrs.has(TAK_escaping)) Printer << "@escaping ";
279+
if (Attrs.has(TAK_autoclosure)) {
280+
Printer.printAttrName("@autoclosure");
281+
Printer << " ";
282+
}
283+
if (Attrs.has(TAK_escaping)) {
284+
Printer.printAttrName("@escaping");
285+
Printer << " ";
286+
}
281287

282-
if (Attrs.has(TAK_thin)) Printer << "@thin ";
283-
if (Attrs.has(TAK_thick)) Printer << "@thick ";
288+
if (Attrs.has(TAK_thin)) {
289+
Printer.printAttrName("@thin");
290+
Printer << " ";
291+
}
292+
if (Attrs.has(TAK_thick)) {
293+
Printer.printAttrName("@thick");
294+
Printer << " ";
295+
}
284296
if (Attrs.convention.hasValue()) {
285-
Printer << "@convention(" << Attrs.convention.getValue() << ") ";
297+
Printer.printAttrName("@convention");
298+
Printer << "(" << Attrs.convention.getValue() << ") ";
286299
}
287300
}
288301

@@ -411,9 +424,19 @@ void TupleTypeRepr::printImpl(ASTPrinter &Printer,
411424

412425
void NamedTypeRepr::printImpl(ASTPrinter &Printer,
413426
const PrintOptions &Opts) const {
414-
if (!Id.empty()) {
415-
Printer.printName(Id, PrintNameContext::TupleElement);
427+
if (isNamedParameter()) {
428+
// Printing empty Identifier is same as printing '_'.
429+
Printer.printName(Identifier(), PrintNameContext::FunctionParameterExternal);
430+
if (!Id.empty()) {
431+
Printer << " ";
432+
Printer.printName(Id, PrintNameContext::FunctionParameterLocal);
433+
}
416434
Printer << ": ";
435+
} else {
436+
if (!Id.empty()) {
437+
Printer.printName(Id, PrintNameContext::TupleElement);
438+
Printer << ": ";
439+
}
417440
}
418441
printTypeRepr(Ty, Printer, Opts);
419442
}

lib/IDE/CodeCompletion.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,8 +2268,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
22682268
Builder.addComma();
22692269
if (BodyParams) {
22702270
// If we have a local name for the parameter, pass in that as well.
2271-
auto name = BodyParams->get(i)->getName();
2272-
Builder.addCallParameter(Name, name, ParamType, TupleElt.isVararg(),
2271+
auto argName = BodyParams->get(i)->getArgumentName();
2272+
auto bodyName = BodyParams->get(i)->getName();
2273+
Builder.addCallParameter(argName, bodyName, ParamType, TupleElt.isVararg(),
22732274
true);
22742275
} else {
22752276
Builder.addCallParameter(Name, ParamType, TupleElt.isVararg(), true);
@@ -2287,8 +2288,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
22872288

22882289
modifiedBuilder = true;
22892290
if (BodyParams) {
2290-
auto name = BodyParams->get(0)->getName();
2291-
Builder.addCallParameter(Identifier(), name, T,
2291+
auto argName = BodyParams->get(0)->getArgumentName();
2292+
auto bodyName = BodyParams->get(0)->getName();
2293+
Builder.addCallParameter(argName, bodyName, T,
22922294
/*IsVarArg*/false, true);
22932295
} else
22942296
Builder.addCallParameter(Identifier(), T, /*IsVarArg*/false, true);
@@ -2362,7 +2364,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
23622364

23632365
void addFunctionCallPattern(const AnyFunctionType *AFT,
23642366
const AbstractFunctionDecl *AFD = nullptr) {
2365-
foundFunction(AFT);
2367+
if (AFD)
2368+
foundFunction(AFD);
2369+
else
2370+
foundFunction(AFT);
23662371

23672372
// Add the pattern, possibly including any default arguments.
23682373
auto addPattern = [&](bool includeDefaultArgs = true) {

lib/Parse/ParseType.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,12 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
711711
else
712712
diag.fixItReplace(SourceRange(firstNameLoc), "_");
713713
}
714+
715+
if (firstNameLoc.isValid() || secondNameLoc.isValid()) {
716+
// Form the named parameter type representation.
717+
ElementsR[i] = new (Context) NamedTypeRepr(secondName, ElementsR[i],
718+
secondNameLoc, firstNameLoc);
719+
}
714720
}
715721
}
716722

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,35 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
16441644
auto topLocator = cs.getConstraintLocator(semanticExpr);
16451645
referencedDecl = solution.resolveLocatorToDecl(topLocator);
16461646

1647+
if (!referencedDecl.getDecl()) {
1648+
// Do another check in case we have a curried call from binding a function
1649+
// reference to a variable, for example:
1650+
//
1651+
// class C {
1652+
// func instanceFunc(p1: Int, p2: Int) {}
1653+
// }
1654+
// func t(c: C) {
1655+
// C.instanceFunc(c)#^COMPLETE^#
1656+
// }
1657+
//
1658+
// We need to get the referenced function so we can complete the argument
1659+
// labels. (Note that the requirement to have labels in the curried call
1660+
// seems inconsistent with the removal of labels from function types.
1661+
// If this changes the following code could be removed).
1662+
if (auto *CE = dyn_cast<CallExpr>(semanticExpr)) {
1663+
if (auto *UDE = dyn_cast<UnresolvedDotExpr>(CE->getFn())) {
1664+
if (isa<TypeExpr>(UDE->getBase())) {
1665+
auto udeLocator = cs.getConstraintLocator(UDE);
1666+
auto udeRefDecl = solution.resolveLocatorToDecl(udeLocator);
1667+
if (auto *FD = dyn_cast_or_null<FuncDecl>(udeRefDecl.getDecl())) {
1668+
if (FD->isInstanceMember())
1669+
referencedDecl = udeRefDecl;
1670+
}
1671+
}
1672+
}
1673+
}
1674+
}
1675+
16471676
// Recover the original type if needed.
16481677
recoverOriginalType();
16491678
return exprType;

lib/Sema/TypeCheckPattern.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,8 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc,
854854
bool hadError = validateTypedPattern(*this, dc, TP, options, resolver);
855855
Pattern *subPattern = TP->getSubPattern();
856856
if (coercePatternToType(subPattern, dc, P->getType(),
857-
options|TR_FromNonInferredPattern, resolver))
857+
options|TR_FromNonInferredPattern, resolver,
858+
TP->getTypeLoc()))
858859
hadError = true;
859860
else {
860861
TP->setSubPattern(subPattern);
@@ -993,7 +994,12 @@ static bool coercePatternViaConditionalDowncast(TypeChecker &tc,
993994
/// Perform top-down type coercion on the given pattern.
994995
bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
995996
TypeResolutionOptions options,
996-
GenericTypeResolver *resolver) {
997+
GenericTypeResolver *resolver,
998+
TypeLoc tyLoc) {
999+
if (tyLoc.isNull()) {
1000+
tyLoc = TypeLoc::withoutLoc(type);
1001+
}
1002+
9971003
TypeResolutionOptions subOptions = options - TR_EnumPatternPayload;
9981004
switch (P->getKind()) {
9991005
// For parens and vars, just set the type annotation and propagate inwards.
@@ -1086,7 +1092,9 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
10861092
else if (!var->isInvalid())
10871093
type = var->getType();
10881094
P->setType(type);
1089-
1095+
var->getTypeLoc() = tyLoc;
1096+
var->getTypeLoc().setType(var->getType());
1097+
10901098
// If we are inferring a variable to have type AnyObject.Type,
10911099
// "()", or optional thereof, emit a diagnostic. In the first 2 cases, the
10921100
// coder probably forgot a cast and expected a concrete type. In the later

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,11 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
888888
comp->getIdentifier() == TC.Context.Id_Self) {
889889
auto func = cast<FuncDecl>(DC);
890890
assert(func->hasDynamicSelf() && "Not marked as having dynamic Self?");
891-
891+
892+
// FIXME: The passed-in TypeRepr should get 'typechecked' as well.
893+
// The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl
894+
// while the 'Self' type is more than just a reference to a TypeDecl.
895+
892896
return func->getDynamicSelf();
893897
}
894898

@@ -2447,13 +2451,17 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
24472451
elementOptions |= TR_FunctionInput;
24482452

24492453
for (auto tyR : repr->getElements()) {
2450-
if (NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR)) {
2454+
NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR);
2455+
if (namedTyR && !(options & TR_ImmediateFunctionInput)) {
24512456
Type ty = resolveType(namedTyR->getTypeRepr(), elementOptions);
24522457
if (!ty || ty->is<ErrorType>()) return ty;
24532458

24542459
elements.push_back(TupleTypeElt(ty, namedTyR->getName()));
24552460
} else {
2456-
Type ty = resolveType(tyR, elementOptions);
2461+
// FIXME: Preserve and serialize parameter names in function types, maybe
2462+
// with a new sugar type.
2463+
Type ty = resolveType(namedTyR ? namedTyR->getTypeRepr() : tyR,
2464+
elementOptions);
24572465
if (!ty || ty->is<ErrorType>()) return ty;
24582466

24592467
elements.push_back(TupleTypeElt(ty));

0 commit comments

Comments
 (0)