Skip to content

GSB: use a request for the structural type of type aliases #24204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 30, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/AST/ASTTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ SWIFT_TYPEID(Type)
SWIFT_TYPEID(PropertyDelegateBackingPropertyInfo)
SWIFT_TYPEID(PropertyDelegateTypeInfo)
SWIFT_TYPEID_NAMED(CustomAttr *, CustomAttr)
SWIFT_TYPEID_NAMED(TypeAliasDecl *, TypeAliasDecl)
1 change: 1 addition & 0 deletions include/swift/AST/ASTTypeIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct PropertyDelegateBackingPropertyInfo;
struct PropertyDelegateTypeInfo;
class Type;
class VarDecl;
class TypeAliasDecl;

#define SWIFT_AST_TYPEID_ZONE 1

Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2893,6 +2893,8 @@ class TypeAliasDecl : public GenericTypeDecl {
/// For generic typealiases, return the unbound generic type.
UnboundGenericType *getUnboundGenericType() const;

Type getStructuralType() const;

bool isCompatibilityAlias() const {
return Bits.TypeAliasDecl.IsCompatibilityAlias;
}
Expand Down
25 changes: 25 additions & 0 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class GenericParamList;
struct PropertyDelegateBackingPropertyInfo;
class RequirementRepr;
class SpecializeAttr;
class TypeAliasDecl;
struct TypeLoc;

/// Display a nominal type or extension thereof.
Expand Down Expand Up @@ -547,6 +548,30 @@ class PropertyDelegateBackingPropertyInfoRequest :
void noteCycleStep(DiagnosticEngine &diags) const;
};

/// Retrieve the structural type of an alias type.
class StructuralTypeRequest :
public SimpleRequest<StructuralTypeRequest,
CacheKind::Cached,
Type,
TypeAliasDecl*> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<Type> evaluate(Evaluator &eval, TypeAliasDecl *d) const;

public:
// Cycle handling.
void diagnoseCycle(DiagnosticEngine &diags) const;
void noteCycleStep(DiagnosticEngine &diags) const;

// Caching.
bool isCached() const { return true; }
};

// Allow AnyValue to compare two Type values, even though Type doesn't
// support ==.
template<>
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ SWIFT_TYPEID(IsFinalRequest)
SWIFT_TYPEID(IsDynamicRequest)
SWIFT_TYPEID(RequirementRequest)
SWIFT_TYPEID(USRGenerationRequest)
SWIFT_TYPEID(StructuralTypeRequest)
SWIFT_TYPEID(DefaultTypeRequest)
SWIFT_TYPEID(MangleLocalTypeDeclRequest)
SWIFT_TYPEID(PropertyDelegateTypeInfoRequest)
Expand Down
9 changes: 9 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3436,6 +3436,15 @@ UnboundGenericType *TypeAliasDecl::getUnboundGenericType() const {
parentTy, getASTContext());
}

Type TypeAliasDecl::getStructuralType() const {
assert(!getGenericParams());

auto &context = getASTContext();
return evaluateOrDefault(context.evaluator,
StructuralTypeRequest { const_cast<TypeAliasDecl *>(this) },
Type());
}

Type AbstractTypeParamDecl::getSuperclass() const {
auto *genericEnv = getDeclContext()->getGenericEnvironmentOfContext();
assert(genericEnv != nullptr && "Too much circularity");
Expand Down
23 changes: 14 additions & 9 deletions lib/AST/GenericSignatureBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3805,13 +3805,12 @@ PotentialArchetype *GenericSignatureBuilder::realizePotentialArchetype(
return pa;
}

static Type getStructuralType(TypeDecl *typeDecl, LazyResolver *resolver) {
static Type getStructuralType(TypeDecl *typeDecl) {
if (auto typealias = dyn_cast<TypeAliasDecl>(typeDecl)) {
// Resolve the underlying type, if we haven't done so yet.
if (!typealias->hasInterfaceType())
resolver->resolveDeclSignature(typealias);
if (auto resolved = typealias->getUnderlyingTypeLoc().getType())
return resolved;

return typealias->getUnderlyingTypeLoc().getType();
return typealias->getStructuralType();
}

return typeDecl->getDeclaredInterfaceType();
Expand All @@ -3826,7 +3825,7 @@ static Type substituteConcreteType(GenericSignatureBuilder &builder,

// Form an unsubstituted type referring to the given type declaration,
// for use in an inferred same-type requirement.
auto type = getStructuralType(concreteDecl, builder.getLazyResolver());
auto type = getStructuralType(concreteDecl);
if (!type)
return Type();

Expand Down Expand Up @@ -4164,8 +4163,14 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
if (inheritedProto == proto) return TypeWalker::Action::Continue;

for (auto req : inheritedProto->getMembers()) {
if (auto typeReq = dyn_cast<TypeDecl>(req))
if (auto typeReq = dyn_cast<TypeDecl>(req)) {
// Ignore generic types
if (auto genReq = dyn_cast<GenericTypeDecl>(req))
if (genReq->getGenericParams())
continue;

inheritedTypeDecls[typeReq->getFullName()].push_back(typeReq);
}
}
return TypeWalker::Action::Continue;
});
Expand Down Expand Up @@ -4228,10 +4233,10 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
// An inferred same-type requirement between the two type declarations
// within this protocol or a protocol it inherits.
auto addInferredSameTypeReq = [&](TypeDecl *first, TypeDecl *second) {
Type firstType = getStructuralType(first, getLazyResolver());
Type firstType = getStructuralType(first);
if (!firstType) return;

Type secondType = getStructuralType(second, getLazyResolver());
Type secondType = getStructuralType(second);
if (!secondType) return;

auto inferredSameTypeSource =
Expand Down
12 changes: 12 additions & 0 deletions lib/AST/TypeCheckRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,3 +660,15 @@ void swift::simple_display(llvm::raw_ostream &out, const Type &type) {
else
out << "null";
}

//----------------------------------------------------------------------------//
// StructuralTypeRequest.
//----------------------------------------------------------------------------//

void StructuralTypeRequest::diagnoseCycle(DiagnosticEngine &diags) const {
diags.diagnose(SourceLoc(), diag::circular_reference);
}

void StructuralTypeRequest::noteCycleStep(DiagnosticEngine &diags) const {
diags.diagnose(SourceLoc(), diag::circular_reference_through);
}
14 changes: 14 additions & 0 deletions lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1008,3 +1008,17 @@ RequirementRequest::evaluate(Evaluator &evaluator,
}
llvm_unreachable("unhandled kind");
}

llvm::Expected<Type>
swift::StructuralTypeRequest::evaluate(Evaluator &evaluator,
TypeAliasDecl *D) const {
TypeResolutionOptions options(TypeResolverContext::TypeAliasDecl);
if (!D->getDeclContext()->isCascadingContextForLookup(
/*functionsAreNonCascading*/true)) {
options |= TypeResolutionFlags::KnownNonCascadingDependency;
}

auto typeRepr = D->getUnderlyingTypeLoc().getTypeRepr();
auto resolution = TypeResolution::forStructural(D);
return resolution.resolveType(typeRepr, options);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

// REQUIRES: asserts
// RUN: not --crash %target-swift-frontend %s -emit-ir
// RUN: not %target-swift-frontend %s -emit-ir
protocol
P{protocol A:P{{}}typealias e:A{}class a<a{}class a