Skip to content

Commit 38bde33

Browse files
authored
Merge pull request swiftlang#27172 from CodaFi/aliasing-artifacts-and-noise-reduction-techniques
Kill validateDeclForNameLookup Harder
2 parents 4fcef2b + 4f6951c commit 38bde33

36 files changed

+364
-288
lines changed

include/swift/AST/Decl.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,6 +2947,8 @@ class OpaqueTypeDecl : public GenericTypeDecl {
29472947
/// TypeAliasDecl's always have 'MetatypeType' type.
29482948
///
29492949
class TypeAliasDecl : public GenericTypeDecl {
2950+
friend class UnderlyingTypeRequest;
2951+
29502952
/// The location of the 'typealias' keyword
29512953
SourceLoc TypeAliasLoc;
29522954

@@ -2974,20 +2976,28 @@ class TypeAliasDecl : public GenericTypeDecl {
29742976

29752977
void setTypeEndLoc(SourceLoc e) { TypeEndLoc = e; }
29762978

2977-
TypeLoc &getUnderlyingTypeLoc() {
2978-
return UnderlyingTy;
2979+
/// Retrieve the TypeRepr corresponding to the parsed underlying type.
2980+
TypeRepr *getUnderlyingTypeRepr() const {
2981+
return UnderlyingTy.getTypeRepr();
29792982
}
2980-
const TypeLoc &getUnderlyingTypeLoc() const {
2981-
return UnderlyingTy;
2983+
void setUnderlyingTypeRepr(TypeRepr *repr) {
2984+
UnderlyingTy = repr;
29822985
}
2983-
2986+
2987+
/// Retrieve the interface type of the underlying type.
2988+
Type getUnderlyingType() const;
29842989
void setUnderlyingType(Type type);
29852990

29862991
/// For generic typealiases, return the unbound generic type.
29872992
UnboundGenericType *getUnboundGenericType() const;
29882993

2994+
/// Retrieve a sugared interface type containing the structure of the interface
2995+
/// type before any semantic validation has occured.
29892996
Type getStructuralType() const;
29902997

2998+
/// Set the interface type of this typealias declaration from the underlying type.
2999+
void computeType();
3000+
29913001
bool isCompatibilityAlias() const {
29923002
return Bits.TypeAliasDecl.IsCompatibilityAlias;
29933003
}

include/swift/AST/TypeCheckRequests.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,9 @@ class RequirementRequest :
434434
// Source location
435435
SourceLoc getNearestLoc() const;
436436

437+
// Cycle handling.
438+
void noteCycleStep(DiagnosticEngine &diags) const;
439+
437440
// Separate caching.
438441
bool isCached() const;
439442
Optional<Requirement> getCachedResult() const;
@@ -1120,6 +1123,9 @@ class InferredGenericSignatureRequest :
11201123
SourceLoc getNearestLoc() const {
11211124
return SourceLoc();
11221125
}
1126+
1127+
// Cycle handling.
1128+
void noteCycleStep(DiagnosticEngine &diags) const;
11231129
};
11241130

11251131
void simple_display(llvm::raw_ostream &out, const TypeLoc source);
@@ -1174,13 +1180,35 @@ class GenericSignatureRequest :
11741180
llvm::Expected<GenericSignature *>
11751181
evaluate(Evaluator &evaluator, GenericContext *value) const;
11761182

1177-
public:
1183+
public:
11781184
// Separate caching.
11791185
bool isCached() const { return true; }
11801186
Optional<GenericSignature *> getCachedResult() const;
11811187
void cacheResult(GenericSignature *value) const;
11821188
};
11831189

1190+
/// Compute the interface type of the underlying definition type of a typealias declaration.
1191+
class UnderlyingTypeRequest :
1192+
public SimpleRequest<UnderlyingTypeRequest,
1193+
Type(TypeAliasDecl *),
1194+
CacheKind::SeparatelyCached> {
1195+
public:
1196+
using SimpleRequest::SimpleRequest;
1197+
1198+
private:
1199+
friend SimpleRequest;
1200+
1201+
// Evaluation.
1202+
llvm::Expected<Type> evaluate(Evaluator &evaluator,
1203+
TypeAliasDecl *decl) const;
1204+
1205+
public:
1206+
// Caching.
1207+
bool isCached() const { return true; }
1208+
Optional<Type> getCachedResult() const;
1209+
void cacheResult(Type value) const;
1210+
};
1211+
11841212
// Allow AnyValue to compare two Type values, even though Type doesn't
11851213
// support ==.
11861214
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,7 @@ SWIFT_REQUEST(TypeChecker, SynthesizeAccessorRequest,
132132
SeparatelyCached, NoLocationInfo)
133133
SWIFT_REQUEST(TypeChecker, TypeCheckFunctionBodyUntilRequest,
134134
bool(AbstractFunctionDecl *, SourceLoc), Cached, NoLocationInfo)
135+
SWIFT_REQUEST(TypeChecker, UnderlyingTypeRequest, Type(TypeAliasDecl *),
136+
SeparatelyCached, NoLocationInfo)
135137
SWIFT_REQUEST(TypeChecker, USRGenerationRequest, std::string(const ValueDecl *),
136138
Cached, NoLocationInfo)

lib/AST/ASTDumper.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -617,9 +617,9 @@ namespace {
617617
void visitTypeAliasDecl(TypeAliasDecl *TAD) {
618618
printCommon(TAD, "typealias");
619619
PrintWithColorRAII(OS, TypeColor) << " type='";
620-
if (TAD->getUnderlyingTypeLoc().getType()) {
620+
if (auto underlying = TAD->getUnderlyingType()) {
621621
PrintWithColorRAII(OS, TypeColor)
622-
<< TAD->getUnderlyingTypeLoc().getType().getString();
622+
<< underlying.getString();
623623
} else {
624624
PrintWithColorRAII(OS, TypeColor) << "<<<unresolved>>>";
625625
}
@@ -3387,6 +3387,12 @@ namespace {
33873387
void visitTypeAliasType(TypeAliasType *T, StringRef label) {
33883388
printCommon(label, "type_alias_type");
33893389
printField("decl", T->getDecl()->printRef());
3390+
PrintWithColorRAII(OS, TypeColor) << " underlying='";
3391+
if (auto underlying = T->getSinglyDesugaredType()) {
3392+
PrintWithColorRAII(OS, TypeColor) << underlying->getString();
3393+
} else {
3394+
PrintWithColorRAII(OS, TypeColor) << "<<<unresolved>>>";
3395+
}
33903396
if (T->getParent())
33913397
printRec("parent", T->getParent());
33923398

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,7 +2277,7 @@ void PrintAST::visitTypeAliasDecl(TypeAliasDecl *decl) {
22772277
printGenericDeclGenericParams(decl);
22782278
});
22792279
bool ShouldPrint = true;
2280-
Type Ty = decl->getUnderlyingTypeLoc().getType();
2280+
Type Ty = decl->getUnderlyingType();
22812281

22822282
// If the underlying type is private, don't print it.
22832283
if (Options.SkipPrivateStdlibDecls && Ty && Ty.isPrivateStdlibType())
@@ -2295,7 +2295,7 @@ void PrintAST::visitTypeAliasDecl(TypeAliasDecl *decl) {
22952295
// preserving sugar.
22962296
llvm::SaveAndRestore<GenericEnvironment*> setGenericEnv(Options.GenericEnv,
22972297
decl->getGenericEnvironment());
2298-
printTypeLoc(decl->getUnderlyingTypeLoc());
2298+
printTypeLoc(TypeLoc(decl->getUnderlyingTypeRepr(), Ty));
22992299
printGenericDeclGenericRequirements(decl);
23002300
}
23012301
}

lib/AST/ASTWalker.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,10 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
232232
return true;
233233
}
234234

235-
return doIt(TAD->getUnderlyingTypeLoc());
235+
if (auto typerepr = TAD->getUnderlyingTypeRepr())
236+
if (doIt(typerepr))
237+
return true;
238+
return false;
236239
}
237240

238241
bool visitOpaqueTypeDecl(OpaqueTypeDecl *OTD) {

lib/AST/Decl.cpp

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3528,34 +3528,42 @@ SourceRange TypeAliasDecl::getSourceRange() const {
35283528
return { TypeAliasLoc, getNameLoc() };
35293529
}
35303530

3531-
void TypeAliasDecl::setUnderlyingType(Type underlying) {
3532-
setValidationToChecked();
3531+
void TypeAliasDecl::computeType() {
3532+
assert(!hasInterfaceType());
3533+
3534+
// Set the interface type of this declaration.
3535+
ASTContext &ctx = getASTContext();
3536+
3537+
auto *genericSig = getGenericSignature();
3538+
SubstitutionMap subs;
3539+
if (genericSig)
3540+
subs = genericSig->getIdentitySubstitutionMap();
35333541

3542+
Type parent;
3543+
auto parentDC = getDeclContext();
3544+
if (parentDC->isTypeContext())
3545+
parent = parentDC->getDeclaredInterfaceType();
3546+
auto sugaredType = TypeAliasType::get(this, parent, subs, getUnderlyingType());
3547+
setInterfaceType(MetatypeType::get(sugaredType, ctx));
3548+
}
3549+
3550+
Type TypeAliasDecl::getUnderlyingType() const {
3551+
return evaluateOrDefault(getASTContext().evaluator,
3552+
UnderlyingTypeRequest{const_cast<TypeAliasDecl *>(this)},
3553+
Type());
3554+
}
3555+
3556+
void TypeAliasDecl::setUnderlyingType(Type underlying) {
35343557
// lldb creates global typealiases containing archetypes
35353558
// sometimes...
35363559
if (underlying->hasArchetype() && isGenericContext())
35373560
underlying = underlying->mapTypeOutOfContext();
3538-
UnderlyingTy.setType(underlying);
3539-
3540-
// FIXME -- if we already have an interface type, we're changing the
3541-
// underlying type. See the comment in the ProtocolDecl case of
3542-
// validateDecl().
3543-
if (!hasInterfaceType()) {
3544-
// Set the interface type of this declaration.
3545-
ASTContext &ctx = getASTContext();
3546-
3547-
auto *genericSig = getGenericSignature();
3548-
SubstitutionMap subs;
3549-
if (genericSig)
3550-
subs = genericSig->getIdentitySubstitutionMap();
3551-
3552-
Type parent;
3553-
auto parentDC = getDeclContext();
3554-
if (parentDC->isTypeContext())
3555-
parent = parentDC->getDeclaredInterfaceType();
3556-
auto sugaredType = TypeAliasType::get(this, parent, subs, underlying);
3557-
setInterfaceType(MetatypeType::get(sugaredType, ctx));
3558-
}
3561+
getASTContext().evaluator.cacheOutput(
3562+
StructuralTypeRequest{const_cast<TypeAliasDecl *>(this)},
3563+
std::move(underlying));
3564+
getASTContext().evaluator.cacheOutput(
3565+
UnderlyingTypeRequest{const_cast<TypeAliasDecl *>(this)},
3566+
std::move(underlying));
35593567
}
35603568

35613569
UnboundGenericType *TypeAliasDecl::getUnboundGenericType() const {
@@ -3572,12 +3580,10 @@ UnboundGenericType *TypeAliasDecl::getUnboundGenericType() const {
35723580
}
35733581

35743582
Type TypeAliasDecl::getStructuralType() const {
3575-
assert(!getGenericParams());
3576-
35773583
auto &context = getASTContext();
3578-
return evaluateOrDefault(context.evaluator,
3579-
StructuralTypeRequest { const_cast<TypeAliasDecl *>(this) },
3580-
Type());
3584+
return evaluateOrDefault(
3585+
context.evaluator,
3586+
StructuralTypeRequest{const_cast<TypeAliasDecl *>(this)}, Type());
35813587
}
35823588

35833589
Type AbstractTypeParamDecl::getSuperclass() const {

lib/AST/DiagnosticEngine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ static bool isInterestingTypealias(Type type) {
380380
// Compatibility aliases are only interesting insofar as their underlying
381381
// types are interesting.
382382
if (aliasDecl->isCompatibilityAlias()) {
383-
auto underlyingTy = aliasDecl->getUnderlyingTypeLoc().getType();
383+
auto underlyingTy = aliasDecl->getUnderlyingType();
384384
return isInterestingTypealias(underlyingTy);
385385
}
386386

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3786,10 +3786,13 @@ PotentialArchetype *GenericSignatureBuilder::realizePotentialArchetype(
37863786

37873787
static Type getStructuralType(TypeDecl *typeDecl) {
37883788
if (auto typealias = dyn_cast<TypeAliasDecl>(typeDecl)) {
3789-
if (auto resolved = typealias->getUnderlyingTypeLoc().getType())
3790-
return resolved;
3791-
3792-
return typealias->getStructuralType();
3789+
// When we're computing requirement signatures, the structural type
3790+
// suffices. Otherwise we'll potentially try to validate incomplete
3791+
// requirements.
3792+
auto *proto = dyn_cast_or_null<ProtocolDecl>(typealias->getDeclContext()->getAsDecl());
3793+
if (proto && proto->isComputingRequirementSignature())
3794+
return typealias->getStructuralType();
3795+
return typealias->getUnderlyingType();
37933796
}
37943797

37953798
return typeDecl->getDeclaredInterfaceType();
@@ -4197,11 +4200,10 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
41974200
out << start;
41984201
out << type->getFullName() << " == ";
41994202
if (auto typealias = dyn_cast<TypeAliasDecl>(type)) {
4200-
if (auto underlyingTypeRepr =
4201-
typealias->getUnderlyingTypeLoc().getTypeRepr())
4203+
if (auto underlyingTypeRepr = typealias->getUnderlyingTypeRepr())
42024204
underlyingTypeRepr->print(out);
42034205
else
4204-
typealias->getUnderlyingTypeLoc().getType().print(out);
4206+
typealias->getUnderlyingType().print(out);
42054207
} else {
42064208
type->print(out);
42074209
}

lib/AST/Module.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ void BuiltinUnit::LookupCache::lookupValue(
103103
const_cast<BuiltinUnit*>(&M));
104104
TAD->setUnderlyingType(Ty);
105105
TAD->setAccess(AccessLevel::Public);
106+
TAD->setValidationToChecked();
107+
TAD->computeType();
106108
Entry = TAD;
107109
}
108110
}

0 commit comments

Comments
 (0)