Skip to content

Commit 31700c7

Browse files
author
ematejska
authored
Merge pull request #4195 from akyrtzi/se-0111-followup-swift3
Follow-up for fixing IDE/SourceKit tests after changes for [SE-0111]
2 parents 9865ceb + 0508089 commit 31700c7

26 files changed

+199
-277
lines changed

include/swift/AST/Decl.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4253,6 +4253,9 @@ class VarDecl : public AbstractStorageDecl {
42534253
setType(Ty);
42544254
}
42554255

4256+
/// This is the type specified, including location information.
4257+
TypeLoc typeLoc;
4258+
42564259
public:
42574260
VarDecl(bool IsStatic, bool IsLet, SourceLoc NameLoc, Identifier Name,
42584261
Type Ty, DeclContext *DC)
@@ -4267,6 +4270,9 @@ class VarDecl : public AbstractStorageDecl {
42674270
bool isUserAccessible() const {
42684271
return VarDeclBits.IsUserAccessible;
42694272
}
4273+
4274+
TypeLoc &getTypeLoc() { return typeLoc; }
4275+
TypeLoc getTypeLoc() const { return typeLoc; }
42704276

42714277
/// Retrieve the source range of the variable type, or an invalid range if the
42724278
/// variable's type is not explicitly written in the source.
@@ -4398,9 +4404,6 @@ class ParamDecl : public VarDecl {
43984404
SourceLoc ArgumentNameLoc;
43994405
SourceLoc LetVarInOutLoc;
44004406

4401-
/// This is the type specified, including location information.
4402-
TypeLoc typeLoc;
4403-
44044407
/// The default value, if any, along with whether this is varargs.
44054408
llvm::PointerIntPair<ExprHandle *, 1, bool> DefaultValueAndIsVariadic;
44064409

@@ -4434,9 +4437,6 @@ class ParamDecl : public VarDecl {
44344437
SourceLoc getArgumentNameLoc() const { return ArgumentNameLoc; }
44354438

44364439
SourceLoc getLetVarInOutLoc() const { return LetVarInOutLoc; }
4437-
4438-
TypeLoc &getTypeLoc() { return typeLoc; }
4439-
TypeLoc getTypeLoc() const { return typeLoc; }
44404440

44414441
bool isTypeLocImplicit() const { return IsTypeLocImplicit; }
44424442
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
}
@@ -3743,10 +3757,14 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37433757
if (Options.SkipAttributes)
37443758
return;
37453759

3746-
if (info.isAutoClosure())
3747-
Printer << "@autoclosure ";
3748-
if (inParameterPrinting && !info.isNoEscape())
3749-
Printer << "@escaping ";
3760+
if (info.isAutoClosure()) {
3761+
Printer.printAttrName("@autoclosure");
3762+
Printer << " ";
3763+
}
3764+
if (inParameterPrinting && !info.isNoEscape()) {
3765+
Printer.printAttrName("@escaping");
3766+
Printer << " ";
3767+
}
37503768

37513769
if (Options.PrintFunctionRepresentationAttrs) {
37523770
// 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
@@ -3722,10 +3722,10 @@ ParamDecl::ParamDecl(ParamDecl *PD)
37223722
ArgumentName(PD->getArgumentName()),
37233723
ArgumentNameLoc(PD->getArgumentNameLoc()),
37243724
LetVarInOutLoc(PD->getLetVarInOutLoc()),
3725-
typeLoc(PD->getTypeLoc()),
37263725
DefaultValueAndIsVariadic(PD->DefaultValueAndIsVariadic),
37273726
IsTypeLocImplicit(PD->IsTypeLocImplicit),
37283727
defaultArgumentKind(PD->defaultArgumentKind) {
3728+
typeLoc = PD->getTypeLoc();
37293729
}
37303730

37313731

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
@@ -2225,8 +2225,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
22252225
Builder.addComma();
22262226
if (BodyParams) {
22272227
// If we have a local name for the parameter, pass in that as well.
2228-
auto name = BodyParams->get(i)->getName();
2229-
Builder.addCallParameter(Name, name, ParamType, TupleElt.isVararg(),
2228+
auto argName = BodyParams->get(i)->getArgumentName();
2229+
auto bodyName = BodyParams->get(i)->getName();
2230+
Builder.addCallParameter(argName, bodyName, ParamType, TupleElt.isVararg(),
22302231
true);
22312232
} else {
22322233
Builder.addCallParameter(Name, ParamType, TupleElt.isVararg(), true);
@@ -2244,8 +2245,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
22442245

22452246
modifiedBuilder = true;
22462247
if (BodyParams) {
2247-
auto name = BodyParams->get(0)->getName();
2248-
Builder.addCallParameter(Identifier(), name, T,
2248+
auto argName = BodyParams->get(0)->getArgumentName();
2249+
auto bodyName = BodyParams->get(0)->getName();
2250+
Builder.addCallParameter(argName, bodyName, T,
22492251
/*IsVarArg*/false, true);
22502252
} else
22512253
Builder.addCallParameter(Identifier(), T, /*IsVarArg*/false, true);
@@ -2319,7 +2321,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
23192321

23202322
void addFunctionCallPattern(const AnyFunctionType *AFT,
23212323
const AbstractFunctionDecl *AFD = nullptr) {
2322-
foundFunction(AFT);
2324+
if (AFD)
2325+
foundFunction(AFD);
2326+
else
2327+
foundFunction(AFT);
23232328

23242329
// Add the pattern, possibly including any default arguments.
23252330
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
@@ -855,7 +855,8 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc,
855855
bool hadError = validateTypedPattern(*this, dc, TP, options, resolver);
856856
Pattern *subPattern = TP->getSubPattern();
857857
if (coercePatternToType(subPattern, dc, P->getType(),
858-
options|TR_FromNonInferredPattern, resolver))
858+
options|TR_FromNonInferredPattern, resolver,
859+
TP->getTypeLoc()))
859860
hadError = true;
860861
else {
861862
TP->setSubPattern(subPattern);
@@ -994,7 +995,12 @@ static bool coercePatternViaConditionalDowncast(TypeChecker &tc,
994995
/// Perform top-down type coercion on the given pattern.
995996
bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
996997
TypeResolutionOptions options,
997-
GenericTypeResolver *resolver) {
998+
GenericTypeResolver *resolver,
999+
TypeLoc tyLoc) {
1000+
if (tyLoc.isNull()) {
1001+
tyLoc = TypeLoc::withoutLoc(type);
1002+
}
1003+
9981004
TypeResolutionOptions subOptions = options - TR_EnumPatternPayload;
9991005
switch (P->getKind()) {
10001006
// For parens and vars, just set the type annotation and propagate inwards.
@@ -1088,7 +1094,9 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
10881094
else if (!var->isInvalid())
10891095
type = var->getType();
10901096
P->setType(type);
1091-
1097+
var->getTypeLoc() = tyLoc;
1098+
var->getTypeLoc().setType(var->getType());
1099+
10921100
// If we are inferring a variable to have type AnyObject.Type,
10931101
// "()", or optional thereof, emit a diagnostic. In the first 2 cases, the
10941102
// 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

@@ -2427,13 +2431,17 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
24272431
elementOptions |= TR_FunctionInput;
24282432

24292433
for (auto tyR : repr->getElements()) {
2430-
if (NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR)) {
2434+
NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR);
2435+
if (namedTyR && !(options & TR_ImmediateFunctionInput)) {
24312436
Type ty = resolveType(namedTyR->getTypeRepr(), elementOptions);
24322437
if (!ty || ty->is<ErrorType>()) return ty;
24332438

24342439
elements.push_back(TupleTypeElt(ty, namedTyR->getName()));
24352440
} else {
2436-
Type ty = resolveType(tyR, elementOptions);
2441+
// FIXME: Preserve and serialize parameter names in function types, maybe
2442+
// with a new sugar type.
2443+
Type ty = resolveType(namedTyR ? namedTyR->getTypeRepr() : tyR,
2444+
elementOptions);
24372445
if (!ty || ty->is<ErrorType>()) return ty;
24382446

24392447
elements.push_back(TupleTypeElt(ty));

0 commit comments

Comments
 (0)