Skip to content

Commit dd1de8d

Browse files
authored
Merge pull request #4421 from slavapestov/small-cleanups
Small cleanups
2 parents a23bb43 + 66ce63b commit dd1de8d

File tree

9 files changed

+91
-46
lines changed

9 files changed

+91
-46
lines changed

include/swift/AST/ASTContext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ class ASTContext {
206206
/// The name of the SwiftShims module "SwiftShims".
207207
Identifier SwiftShimsModuleName;
208208

209-
/// Note: in non-NDEBUG builds, tracks the context of each archetype
210-
/// type, which can be very useful for debugging.
209+
/// Note: in non-NDEBUG builds, tracks the context of each primary
210+
/// archetype type, which can be very useful for debugging.
211211
llvm::DenseMap<ArchetypeType *, DeclContext *> ArchetypeContexts;
212212

213213
// Define the set of known identifiers.

include/swift/AST/Types.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,12 +3748,10 @@ class ArchetypeType final : public SubstitutableType,
37483748
/// True if this is the 'Self' parameter of a protocol or an associated type
37493749
/// of 'Self'.
37503750
bool isSelfDerived() {
3751-
ArchetypeType *t = this;
3751+
ArchetypeType *t = getPrimary();
37523752

3753-
do {
3754-
if (t->getSelfProtocol())
3755-
return true;
3756-
} while ((t = t->getParent()));
3753+
if (t && t->getSelfProtocol())
3754+
return true;
37573755

37583756
return false;
37593757
}
@@ -3810,6 +3808,16 @@ class ArchetypeType final : public SubstitutableType,
38103808
return ParentOrOpened.isNull();
38113809
}
38123810

3811+
/// getPrimary - Return the primary archetype parent of this archetype.
3812+
ArchetypeType *getPrimary() const {
3813+
assert(!getOpenedExistentialType() && "Check for opened existential first");
3814+
3815+
auto *archetype = this;
3816+
while (auto *parent = archetype->getParent())
3817+
archetype = parent;
3818+
return const_cast<ArchetypeType *>(archetype);
3819+
}
3820+
38133821
/// Retrieve the ID number of this opened existential.
38143822
UUID getOpenedExistentialID() const {
38153823
assert(getOpenedExistentialType() && "Not an opened existential archetype");

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,10 @@ void ASTContext::dumpArchetypeContext(ArchetypeType *archetype,
26012601
void ASTContext::dumpArchetypeContext(ArchetypeType *archetype,
26022602
llvm::raw_ostream &os,
26032603
unsigned indent) const {
2604+
archetype = archetype->getPrimary();
2605+
if (!archetype)
2606+
return;
2607+
26042608
auto knownDC = ArchetypeContexts.find(archetype);
26052609
if (knownDC != ArchetypeContexts.end())
26062610
knownDC->second->printContext(os, indent);

lib/AST/ASTVerifier.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ struct ASTNodeBase {};
7878
using ScopeLike = llvm::PointerUnion<DeclContext *, BraceStmt *>;
7979
SmallVector<ScopeLike, 4> Scopes;
8080

81-
/// The set of archetypes that are currently available.
81+
/// The set of primary archetypes that are currently available.
8282
SmallPtrSet<ArchetypeType *, 4> ActiveArchetypes;
8383

8484
/// \brief The stack of optional evaluations active at this point.
@@ -106,8 +106,8 @@ struct ASTNodeBase {};
106106
for (auto genericParams = dc->getGenericParamsOfContext();
107107
genericParams;
108108
genericParams = genericParams->getOuterParameters()) {
109-
ActiveArchetypes.insert(genericParams->getAllArchetypes().begin(),
110-
genericParams->getAllArchetypes().end());
109+
for (auto *param : genericParams->getParams())
110+
ActiveArchetypes.insert(param->getArchetype());
111111
}
112112
}
113113

@@ -446,8 +446,11 @@ struct ASTNodeBase {};
446446
return false;
447447
}
448448

449+
// Get the primary archetype.
450+
auto *parent = archetype->getPrimary();
451+
449452
// Otherwise, the archetype needs to be from this scope.
450-
if (ActiveArchetypes.count(archetype) == 0) {
453+
if (ActiveArchetypes.count(parent) == 0) {
451454
// FIXME: Make an exception for serialized extensions, which don't
452455
// currently have the correct archetypes.
453456
if (auto activeScope = Scopes.back().dyn_cast<DeclContext *>()) {
@@ -463,7 +466,7 @@ struct ASTNodeBase {};
463466
Out << "AST verification error: archetype "
464467
<< archetype->getString() << " not allowed in this context\n";
465468

466-
auto knownDC = Ctx.ArchetypeContexts.find(archetype);
469+
auto knownDC = Ctx.ArchetypeContexts.find(parent);
467470
if (knownDC != Ctx.ArchetypeContexts.end()) {
468471
llvm::errs() << "archetype came from:\n";
469472
knownDC->second->dumpContext();
@@ -534,8 +537,9 @@ struct ASTNodeBase {};
534537

535538
// Add any archetypes from this scope into the set of active archetypes.
536539
if (auto genericParams = getImmediateGenericParams(scope))
537-
ActiveArchetypes.insert(genericParams->getAllArchetypes().begin(),
538-
genericParams->getAllArchetypes().end());
540+
for (auto *param : genericParams->getParams())
541+
if (auto *archetype = param->getArchetype())
542+
ActiveArchetypes.insert(archetype);
539543
}
540544
void pushScope(BraceStmt *scope) {
541545
Scopes.push_back(scope);
@@ -546,7 +550,11 @@ struct ASTNodeBase {};
546550
// Remove archetypes from this scope from the set of active archetypes.
547551
if (auto genericParams
548552
= getImmediateGenericParams(Scopes.back().get<DeclContext*>())) {
549-
for (auto archetype : genericParams->getAllArchetypes()) {
553+
for (auto *param : genericParams->getParams()) {
554+
auto *archetype = param->getArchetype();
555+
if (archetype == nullptr)
556+
continue;
557+
550558
if (!ActiveArchetypes.erase(archetype)) {
551559
llvm::errs() << "archetype " << archetype
552560
<< " not introduced by scope?\n";

lib/SIL/SILVerifier.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,27 +49,27 @@ static llvm::cl::opt<bool> SkipUnreachableMustBeLastErrors(
4949
// prevent release builds from triggering spurious unused variable warnings.
5050
#ifndef NDEBUG
5151

52-
/// Returns true if A is an opened existential type, Self, or is equal to an
53-
/// archetype in F's nested archetype list.
54-
///
55-
/// FIXME: Once Self has been removed in favor of opened existential types
56-
/// everywhere, remove support for self.
52+
/// Returns true if A is an opened existential type or is equal to an
53+
/// archetype from F's generic context.
5754
static bool isArchetypeValidInFunction(ArchetypeType *A, SILFunction *F) {
58-
// The only two cases where an archetype is always legal in a function is if
59-
// it is self or if it is from an opened existential type. Currently, Self is
60-
// being migrated away from in favor of opened existential types, so we should
61-
// remove the special case here for Self when that process is completed.
62-
//
63-
// *NOTE* Associated types of self are not valid here.
64-
if (!A->getOpenedExistentialType().isNull() || A->getSelfProtocol())
55+
if (!A->getOpenedExistentialType().isNull())
6556
return true;
6657

67-
// Ok, we have an archetype, make sure it is in the nested archetypes of our
68-
// caller.
69-
for (auto Iter : F->getContextGenericParams()->getAllNestedArchetypes())
70-
if (A->isEqual(&*Iter))
71-
return true;
72-
return A->getIsRecursive();
58+
// Find the primary archetype.
59+
A = A->getPrimary();
60+
61+
// Ok, we have a primary archetype, make sure it is in the nested generic
62+
// parameters of our caller.
63+
for (auto *params = F->getContextGenericParams();
64+
params != nullptr;
65+
params = params->getOuterParameters()) {
66+
67+
for (auto param : params->getParams())
68+
if (param->getArchetype()->isEqual(A))
69+
return true;
70+
}
71+
72+
return false;
7373
}
7474

7575
namespace {

lib/Sema/CSDiag.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1982,6 +1982,7 @@ class FailureDiagnosis :public ASTVisitor<FailureDiagnosis, /*exprresult*/bool>{
19821982

19831983
bool visitExpr(Expr *E);
19841984
bool visitIdentityExpr(IdentityExpr *E);
1985+
bool visitTryExpr(TryExpr *E);
19851986
bool visitTupleExpr(TupleExpr *E);
19861987

19871988
bool visitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
@@ -6277,6 +6278,12 @@ bool FailureDiagnosis::visitIdentityExpr(IdentityExpr *E) {
62776278
return false;
62786279
}
62796280

6281+
/// A TryExpr doesn't change it's argument, nor does it change the contextual
6282+
/// type.
6283+
bool FailureDiagnosis::visitTryExpr(TryExpr *E) {
6284+
return visit(E->getSubExpr());
6285+
}
6286+
62806287
bool FailureDiagnosis::visitExpr(Expr *E) {
62816288
// Check each of our immediate children to see if any of them are
62826289
// independently invalid.
@@ -6331,7 +6338,7 @@ void ConstraintSystem::diagnoseFailureForExpr(Expr *expr) {
63316338
// inconsistent state.
63326339
simplify(/*ContinueAfterFailures*/true);
63336340

6334-
// Look through RebindSelfInConstructorExpr to avoid weird sema issues.
6341+
// Look through RebindSelfInConstructorExpr to avoid weird Sema issues.
63356342
if (auto *RB = dyn_cast<RebindSelfInConstructorExpr>(expr))
63366343
expr = RB->getSubExpr();
63376344

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,8 @@ void TypeChecker::finalizeGenericParamList(ArchetypeBuilder &builder,
815815

816816
#ifndef NDEBUG
817817
// Record archetype contexts.
818-
for (auto archetype : genericParams->getAllArchetypes()) {
818+
for (auto *param : genericParams->getParams()) {
819+
auto *archetype = param->getArchetype();
819820
if (Context.ArchetypeContexts.count(archetype) == 0)
820821
Context.ArchetypeContexts[archetype] = dc;
821822
}

lib/Sema/TypeCheckType.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,9 +1410,9 @@ static bool isDefaultNoEscapeContext(const DeclContext *DC) {
14101410
}
14111411

14121412
// Hack to apply context-specific @escaping to an AST function type.
1413-
static Type adjustFunctionExtInfo(DeclContext *DC,
1414-
Type ty,
1415-
TypeResolutionOptions options) {
1413+
static Type applyNonEscapingFromContext(DeclContext *DC,
1414+
Type ty,
1415+
TypeResolutionOptions options) {
14161416
// Remember whether this is a function parameter.
14171417
bool isFunctionParam =
14181418
options.contains(TR_FunctionInput) ||
@@ -1426,7 +1426,11 @@ static Type adjustFunctionExtInfo(DeclContext *DC,
14261426
if (defaultNoEscape && !extInfo.isNoEscape()) {
14271427
extInfo = extInfo.withNoEscape();
14281428

1429-
// We lost the sugar to flip the isNoEscape bit
1429+
// We lost the sugar to flip the isNoEscape bit.
1430+
//
1431+
// FIXME: It would be better to add a new AttributedType sugared type,
1432+
// which would wrap the NameAliasType or ParenType, and apply the
1433+
// isNoEscape bit when de-sugaring.
14301434
return FunctionType::get(funcTy->getInput(), funcTy->getResult(), extInfo);
14311435
}
14321436

@@ -1467,7 +1471,7 @@ Type TypeChecker::resolveIdentifierType(
14671471
// Hack to apply context-specific @escaping to a typealias with an underlying
14681472
// function type.
14691473
if (result->is<FunctionType>())
1470-
result = adjustFunctionExtInfo(DC, result, options);
1474+
result = applyNonEscapingFromContext(DC, result, options);
14711475

14721476
// We allow a type to conform to a protocol that is less available than
14731477
// the type itself. This enables a type to retroactively model or directly
@@ -1716,7 +1720,7 @@ Type TypeResolver::resolveType(TypeRepr *repr, TypeResolutionOptions options) {
17161720
// Default non-escaping for closure parameters
17171721
auto result = resolveASTFunctionType(cast<FunctionTypeRepr>(repr), options);
17181722
if (result && result->is<FunctionType>())
1719-
return adjustFunctionExtInfo(DC, result, options);
1723+
return applyNonEscapingFromContext(DC, result, options);
17201724
return result;
17211725
}
17221726
return resolveSILFunctionType(cast<FunctionTypeRepr>(repr), options);
@@ -1987,10 +1991,6 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
19871991
.fixItReplace(resultRange, "Never");
19881992
}
19891993

1990-
if (attrs.has(TAK_noescape)) {
1991-
// FIXME: diagnostic to tell user this is redundant and drop it
1992-
}
1993-
19941994
// Resolve the function type directly with these attributes.
19951995
FunctionType::ExtInfo extInfo(rep,
19961996
attrs.has(TAK_autoclosure),
@@ -2030,7 +2030,7 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
20302030
attrs.clearAttribute(TAK_escaping);
20312031
} else {
20322032
// No attribute; set the isNoEscape bit if we're in parameter context.
2033-
ty = adjustFunctionExtInfo(DC, ty, options);
2033+
ty = applyNonEscapingFromContext(DC, ty, options);
20342034
}
20352035
}
20362036

@@ -2048,6 +2048,7 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs,
20482048
}
20492049
}
20502050
} else if (hasFunctionAttr && fnRepr) {
2051+
// Remove the function attributes from the set so that we don't diagnose.
20512052
for (auto i : FunctionAttrs)
20522053
attrs.clearAttribute(i);
20532054
attrs.convention = None;
@@ -2504,6 +2505,11 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
25042505

25052506
// If this is the top level of a function input list, peel off the
25062507
// ImmediateFunctionInput marker and install a FunctionInput one instead.
2508+
//
2509+
// If we have a single ParenType though, don't clear these bits; we
2510+
// still want to parse the type contained therein as if it were in
2511+
// parameter position, meaning function types are not @escaping by
2512+
// default.
25072513
auto elementOptions = options;
25082514
if (!repr->isParenType()) {
25092515
elementOptions = withoutContext(elementOptions);

test/Constraints/diagnostics.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,3 +769,14 @@ struct SR1752 {
769769
let sr1752: SR1752? = nil
770770

771771
true ? nil : sr1752?.foo() // don't generate a warning about unused result since foo returns Void
772+
773+
// <rdar://problem/27891805> QoI: FailureDiagnosis doesn't look through 'try'
774+
struct rdar27891805 {
775+
init(contentsOf: String, encoding: String) throws {}
776+
init(contentsOf: String, usedEncoding: inout String) throws {}
777+
init<T>(_ t: T) {}
778+
}
779+
780+
try rdar27891805(contentsOfURL: nil, usedEncoding: nil)
781+
// expected-error@-1 {{argument labels '(contentsOfURL:, usedEncoding:)' do not match any available overloads}}
782+
// expected-note@-2 {{overloads for 'rdar27891805' exist with these partially matching parameter lists: (contentsOf: String, encoding: String), (contentsOf: String, usedEncoding: inout String)}}

0 commit comments

Comments
 (0)