mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
IDE+Evaluator: converge multiple type relation checks into a single sema request, NFC
From libIDE, the utility functions will invoke the request in the implementation.
This commit is contained in:
@@ -51,8 +51,6 @@ namespace swift {
|
|||||||
|
|
||||||
bool canPossiblyEqual(Type T1, Type T2, DeclContext &DC);
|
bool canPossiblyEqual(Type T1, Type T2, DeclContext &DC);
|
||||||
|
|
||||||
bool canPossiblyConvertTo(Type T1, Type T2, DeclContext &DC);
|
|
||||||
|
|
||||||
void collectDefaultImplementationForProtocolMembers(ProtocolDecl *PD,
|
void collectDefaultImplementationForProtocolMembers(ProtocolDecl *PD,
|
||||||
llvm::SmallDenseMap<ValueDecl*, ValueDecl*> &DefaultMap);
|
llvm::SmallDenseMap<ValueDecl*, ValueDecl*> &DefaultMap);
|
||||||
|
|
||||||
|
|||||||
@@ -15,3 +15,4 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
SWIFT_TYPEID(IsDeclApplicableRequest)
|
SWIFT_TYPEID(IsDeclApplicableRequest)
|
||||||
|
SWIFT_TYPEID(TypeRelationCheckRequest)
|
||||||
|
|||||||
@@ -83,6 +83,83 @@ public:
|
|||||||
SourceLoc getNearestLoc() const { return SourceLoc(); };
|
SourceLoc getNearestLoc() const { return SourceLoc(); };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// Type relation checking
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
enum class TypeRelation: uint8_t {
|
||||||
|
EqualTo,
|
||||||
|
PossiblyEqualTo,
|
||||||
|
ConvertTo,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TypeRelationCheckInput {
|
||||||
|
DeclContext *DC;
|
||||||
|
Type FirstType;
|
||||||
|
Type SecondType;
|
||||||
|
TypeRelation Relation;
|
||||||
|
bool OpenArchetypes;
|
||||||
|
|
||||||
|
TypeRelationCheckInput(DeclContext *DC, Type FirstType, Type SecondType,
|
||||||
|
TypeRelation Relation, bool OpenArchetypes = true):
|
||||||
|
DC(DC), FirstType(FirstType), SecondType(SecondType), Relation(Relation),
|
||||||
|
OpenArchetypes(OpenArchetypes) {}
|
||||||
|
|
||||||
|
friend llvm::hash_code hash_value(const TypeRelationCheckInput &TI) {
|
||||||
|
return hash_combine(hash_value(TI.FirstType.getPointer()),
|
||||||
|
hash_value(TI.SecondType.getPointer()),
|
||||||
|
hash_value(TI.Relation),
|
||||||
|
hash_value(TI.OpenArchetypes));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const TypeRelationCheckInput &lhs,
|
||||||
|
const TypeRelationCheckInput &rhs) {
|
||||||
|
return lhs.FirstType.getPointer() == rhs.FirstType.getPointer() &&
|
||||||
|
lhs.SecondType.getPointer() == rhs.SecondType.getPointer() &&
|
||||||
|
lhs.Relation == rhs.Relation &&
|
||||||
|
lhs.OpenArchetypes == rhs.OpenArchetypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const TypeRelationCheckInput &lhs,
|
||||||
|
const TypeRelationCheckInput &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend void simple_display(llvm::raw_ostream &out,
|
||||||
|
const TypeRelationCheckInput &owner) {
|
||||||
|
out << "Check if ";
|
||||||
|
simple_display(out, owner.FirstType);
|
||||||
|
out << " is ";
|
||||||
|
switch(owner.Relation) {
|
||||||
|
#define CASE(NAME) case TypeRelation::NAME: out << #NAME << " "; break;
|
||||||
|
CASE(EqualTo)
|
||||||
|
CASE(PossiblyEqualTo)
|
||||||
|
CASE(ConvertTo)
|
||||||
|
#undef CASE
|
||||||
|
}
|
||||||
|
simple_display(out, owner.SecondType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TypeRelationCheckRequest:
|
||||||
|
public SimpleRequest<TypeRelationCheckRequest,
|
||||||
|
bool(TypeRelationCheckInput),
|
||||||
|
CacheKind::Cached> {
|
||||||
|
public:
|
||||||
|
using SimpleRequest::SimpleRequest;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend SimpleRequest;
|
||||||
|
|
||||||
|
// Evaluation.
|
||||||
|
llvm::Expected<bool> evaluate(Evaluator &evaluator,
|
||||||
|
TypeRelationCheckInput Owner) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Caching
|
||||||
|
bool isCached() const { return true; }
|
||||||
|
// Source location
|
||||||
|
SourceLoc getNearestLoc() const { return SourceLoc(); };
|
||||||
|
};
|
||||||
|
|
||||||
/// The zone number for the IDE.
|
/// The zone number for the IDE.
|
||||||
#define SWIFT_IDE_TYPE_CHECK_REQUESTS_TYPEID_ZONE 97
|
#define SWIFT_IDE_TYPE_CHECK_REQUESTS_TYPEID_ZONE 97
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ struct SynthesizedExtensionAnalyzer::Implementation {
|
|||||||
case RequirementKind::Superclass:
|
case RequirementKind::Superclass:
|
||||||
// FIXME: This could be more accurate; check
|
// FIXME: This could be more accurate; check
|
||||||
// conformance instead of subtyping
|
// conformance instead of subtyping
|
||||||
if (!canPossiblyConvertTo(First, Second, *DC))
|
if (!isConvertibleTo(First, Second, /*openArchetypes=*/true, *DC))
|
||||||
return true;
|
return true;
|
||||||
else if (!isConvertibleTo(First, Second, /*openArchetypes=*/false,
|
else if (!isConvertibleTo(First, Second, /*openArchetypes=*/false,
|
||||||
*DC))
|
*DC))
|
||||||
@@ -751,3 +751,23 @@ bool swift::isMemberDeclApplied(const DeclContext *DC, Type BaseTy,
|
|||||||
return evaluateOrDefault(DC->getASTContext().evaluator,
|
return evaluateOrDefault(DC->getASTContext().evaluator,
|
||||||
IsDeclApplicableRequest(DeclApplicabilityOwner(DC, BaseTy, VD)), false);
|
IsDeclApplicableRequest(DeclApplicabilityOwner(DC, BaseTy, VD)), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool swift::canPossiblyEqual(Type T1, Type T2, DeclContext &DC) {
|
||||||
|
return evaluateOrDefault(DC.getASTContext().evaluator,
|
||||||
|
TypeRelationCheckRequest(TypeRelationCheckInput(&DC, T1, T2,
|
||||||
|
TypeRelation::PossiblyEqualTo, true)), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool swift::isEqual(Type T1, Type T2, DeclContext &DC) {
|
||||||
|
return evaluateOrDefault(DC.getASTContext().evaluator,
|
||||||
|
TypeRelationCheckRequest(TypeRelationCheckInput(&DC, T1, T2,
|
||||||
|
TypeRelation::EqualTo, true)), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool swift::isConvertibleTo(Type T1, Type T2, bool openArchetypes,
|
||||||
|
DeclContext &DC) {
|
||||||
|
return evaluateOrDefault(DC.getASTContext().evaluator,
|
||||||
|
TypeRelationCheckRequest(TypeRelationCheckInput(&DC, T1, T2,
|
||||||
|
TypeRelation::ConvertTo, openArchetypes)), false);
|
||||||
|
}
|
||||||
|
|||||||
@@ -3769,7 +3769,7 @@ bool swift::areGenericRequirementsSatisfied(
|
|||||||
return CS.solveSingle().hasValue();
|
return CS.solveSingle().hasValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool canSatisfy(Type type1, Type type2, bool openArchetypes,
|
bool swift::canSatisfy(Type type1, Type type2, bool openArchetypes,
|
||||||
ConstraintKind kind, DeclContext *dc) {
|
ConstraintKind kind, DeclContext *dc) {
|
||||||
std::unique_ptr<TypeChecker> CreatedTC;
|
std::unique_ptr<TypeChecker> CreatedTC;
|
||||||
auto &TC = TypeChecker::createForContext(dc->getASTContext());
|
auto &TC = TypeChecker::createForContext(dc->getASTContext());
|
||||||
@@ -3777,23 +3777,6 @@ static bool canSatisfy(Type type1, Type type2, bool openArchetypes,
|
|||||||
/*unwrappedIUO=*/nullptr);
|
/*unwrappedIUO=*/nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool swift::canPossiblyEqual(Type T1, Type T2, DeclContext &DC) {
|
|
||||||
return canSatisfy(T1, T2, true, ConstraintKind::Bind, &DC);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool swift::canPossiblyConvertTo(Type T1, Type T2, DeclContext &DC) {
|
|
||||||
return canSatisfy(T1, T2, true, ConstraintKind::Conversion, &DC);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool swift::isEqual(Type T1, Type T2, DeclContext &DC) {
|
|
||||||
return T1->isEqual(T2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool swift::isConvertibleTo(Type T1, Type T2, bool openArchetypes,
|
|
||||||
DeclContext &DC) {
|
|
||||||
return canSatisfy(T1, T2, openArchetypes, ConstraintKind::Conversion, &DC);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swift::eraseOpenedExistentials(ConstraintSystem &CS, Expr *&expr) {
|
void swift::eraseOpenedExistentials(ConstraintSystem &CS, Expr *&expr) {
|
||||||
expr = expr->walk(SanitizeExpr(CS, /*eraseOEsOnly=*/true));
|
expr = expr->walk(SanitizeExpr(CS, /*eraseOEsOnly=*/true));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#include "swift/Sema/IDETypeCheckingRequests.h"
|
#include "swift/Sema/IDETypeCheckingRequests.h"
|
||||||
#include "swift/Subsystems.h"
|
#include "swift/Subsystems.h"
|
||||||
#include "TypeChecker.h"
|
#include "TypeChecker.h"
|
||||||
|
#include "ConstraintGraph.h"
|
||||||
|
#include "ConstraintSystem.h"
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
@@ -96,3 +98,22 @@ IsDeclApplicableRequest::evaluate(Evaluator &evaluator,
|
|||||||
llvm_unreachable("unhandled decl kind");
|
llvm_unreachable("unhandled decl kind");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::Expected<bool>
|
||||||
|
TypeRelationCheckRequest::evaluate(Evaluator &evaluator,
|
||||||
|
TypeRelationCheckInput Owner) const {
|
||||||
|
Optional<constraints::ConstraintKind> CKind;
|
||||||
|
switch (Owner.Relation) {
|
||||||
|
case TypeRelation::EqualTo:
|
||||||
|
return Owner.FirstType->isEqual(Owner.SecondType);
|
||||||
|
case TypeRelation::PossiblyEqualTo:
|
||||||
|
CKind = constraints::ConstraintKind::Bind;
|
||||||
|
break;
|
||||||
|
case TypeRelation::ConvertTo:
|
||||||
|
CKind = constraints::ConstraintKind::Conversion;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(CKind.hasValue());
|
||||||
|
return canSatisfy(Owner.FirstType, Owner.SecondType, Owner.OpenArchetypes,
|
||||||
|
*CKind, Owner.DC);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2172,6 +2172,8 @@ bool areGenericRequirementsSatisfied(const DeclContext *DC,
|
|||||||
const SubstitutionMap &Substitutions,
|
const SubstitutionMap &Substitutions,
|
||||||
bool isExtension);
|
bool isExtension);
|
||||||
|
|
||||||
|
bool canSatisfy(Type type1, Type type2, bool openArchetypes,
|
||||||
|
constraints::ConstraintKind kind, DeclContext *dc);
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -969,6 +969,7 @@ static bool reportModuleDocInfo(CompilerInvocation Invocation,
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
ASTContext &Ctx = CI.getASTContext();
|
ASTContext &Ctx = CI.getASTContext();
|
||||||
|
registerIDERequestFunctions(Ctx.evaluator);
|
||||||
(void)createTypeChecker(Ctx);
|
(void)createTypeChecker(Ctx);
|
||||||
|
|
||||||
SourceTextInfo IFaceInfo;
|
SourceTextInfo IFaceInfo;
|
||||||
|
|||||||
Reference in New Issue
Block a user