Skip to content

Commit 09fbdc2

Browse files
committed
Sema: intro a request evaluator to get the structural type of type aliases
This request evaluator doesn't rely on the previous execution of a compilation phase but it caches the result in a compatible way.
1 parent 155a155 commit 09fbdc2

File tree

6 files changed

+70
-0
lines changed

6 files changed

+70
-0
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2893,6 +2893,8 @@ class TypeAliasDecl : public GenericTypeDecl {
28932893
/// For generic typealiases, return the unbound generic type.
28942894
UnboundGenericType *getUnboundGenericType() const;
28952895

2896+
Type getStructuralType() const;
2897+
28962898
bool isCompatibilityAlias() const {
28972899
return Bits.TypeAliasDecl.IsCompatibilityAlias;
28982900
}

include/swift/AST/TypeCheckRequests.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class GenericParamList;
3333
struct PropertyDelegateBackingPropertyInfo;
3434
class RequirementRepr;
3535
class SpecializeAttr;
36+
class TypeAliasDecl;
3637
struct TypeLoc;
3738

3839
/// Display a nominal type or extension thereof.
@@ -547,6 +548,33 @@ class PropertyDelegateBackingPropertyInfoRequest :
547548
void noteCycleStep(DiagnosticEngine &diags) const;
548549
};
549550

551+
/// Retrieve the structural type of an alias type.
552+
class StructuralTypeRequest :
553+
public SimpleRequest<StructuralTypeRequest,
554+
CacheKind::SeparatelyCached,
555+
Type,
556+
TypeAliasDecl*> {
557+
public:
558+
using SimpleRequest::SimpleRequest;
559+
560+
private:
561+
friend SimpleRequest;
562+
563+
// Evaluation.
564+
llvm::Expected<Type> evaluate(Evaluator &eval, TypeAliasDecl *d) const;
565+
566+
public:
567+
// Cycle handling.
568+
void diagnoseCycle(DiagnosticEngine &diags) const;
569+
void noteCycleStep(DiagnosticEngine &diags) const;
570+
571+
// Separate caching.
572+
bool isCached() const { return true; };
573+
Optional<Type> getCachedResult() const;
574+
void cacheResult(Type value) const;
575+
};
576+
577+
550578
// Allow AnyValue to compare two Type values, even though Type doesn't
551579
// support ==.
552580
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ SWIFT_TYPEID(IsFinalRequest)
2323
SWIFT_TYPEID(IsDynamicRequest)
2424
SWIFT_TYPEID(RequirementRequest)
2525
SWIFT_TYPEID(USRGenerationRequest)
26+
SWIFT_TYPEID(StructuralTypeRequest)
2627
SWIFT_TYPEID(DefaultTypeRequest)
2728
SWIFT_TYPEID(MangleLocalTypeDeclRequest)
2829
SWIFT_TYPEID(PropertyDelegateTypeInfoRequest)

lib/AST/Decl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3436,6 +3436,13 @@ UnboundGenericType *TypeAliasDecl::getUnboundGenericType() const {
34363436
parentTy, getASTContext());
34373437
}
34383438

3439+
Type TypeAliasDecl::getStructuralType() const {
3440+
auto &context = getASTContext();
3441+
return evaluateOrDefault(context.evaluator,
3442+
StructuralTypeRequest { const_cast<TypeAliasDecl *>(this) },
3443+
Type());
3444+
}
3445+
34393446
Type AbstractTypeParamDecl::getSuperclass() const {
34403447
auto *genericEnv = getDeclContext()->getGenericEnvironmentOfContext();
34413448
assert(genericEnv != nullptr && "Too much circularity");

lib/AST/TypeCheckRequests.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,3 +660,27 @@ void swift::simple_display(llvm::raw_ostream &out, const Type &type) {
660660
else
661661
out << "null";
662662
}
663+
664+
//----------------------------------------------------------------------------//
665+
// StructuralTypeRequest.
666+
//----------------------------------------------------------------------------//
667+
668+
void StructuralTypeRequest::diagnoseCycle(DiagnosticEngine &diags) const {
669+
diags.diagnose(SourceLoc(), diag::circular_reference);
670+
}
671+
672+
void StructuralTypeRequest::noteCycleStep(DiagnosticEngine &diags) const {
673+
diags.diagnose(SourceLoc(), diag::circular_reference_through);
674+
}
675+
676+
Optional<Type> StructuralTypeRequest::getCachedResult() const {
677+
auto decl = std::get<0>(getStorage());
678+
if (decl->getUnderlyingTypeLoc().getType())
679+
return decl->getUnderlyingTypeLoc().getType();
680+
return None;
681+
}
682+
683+
void StructuralTypeRequest::cacheResult(Type value) const {
684+
auto decl = std::get<0>(getStorage());
685+
decl->getUnderlyingTypeLoc().setType(value);
686+
}

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,3 +1008,11 @@ RequirementRequest::evaluate(Evaluator &evaluator,
10081008
}
10091009
llvm_unreachable("unhandled kind");
10101010
}
1011+
1012+
llvm::Expected<Type>
1013+
swift::StructuralTypeRequest::evaluate(Evaluator &evaluator,
1014+
TypeAliasDecl *D) const {
1015+
auto typeRepr = D->getUnderlyingTypeLoc().getTypeRepr();
1016+
auto resolution = TypeResolution::forStructural(D);
1017+
return resolution.resolveType(typeRepr, None);
1018+
}

0 commit comments

Comments
 (0)