mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Factor our the selection of "alternative" literal type suggestions.
Swift SVN r11035
This commit is contained in:
@@ -859,13 +859,7 @@ static bool tryTypeVariableBindings(
|
||||
continue;
|
||||
|
||||
KnownProtocolKind knownKind = *proto->getKnownProtocolKind();
|
||||
for (auto decl : tc.Context.getTypesThatConformTo(knownKind)) {
|
||||
Type type;
|
||||
if (auto nominal = dyn_cast<NominalTypeDecl>(decl))
|
||||
type = nominal->getDeclaredTypeOfContext();
|
||||
else
|
||||
type = cast<ExtensionDecl>(decl)->getDeclaredTypeOfContext();
|
||||
|
||||
for (auto type : cs.getAlternativeLiteralTypes(knownKind)) {
|
||||
if (exploredTypes.insert(type->getCanonicalType()))
|
||||
newBindings.push_back({type, true});
|
||||
}
|
||||
|
||||
@@ -221,6 +221,65 @@ LookupResult &ConstraintSystem::lookupMember(Type base, Identifier name) {
|
||||
return *result;
|
||||
}
|
||||
|
||||
ArrayRef<Type> ConstraintSystem::getAlternativeLiteralTypes(
|
||||
KnownProtocolKind kind) {
|
||||
unsigned index;
|
||||
|
||||
switch (kind) {
|
||||
#define PROTOCOL(Protocol) \
|
||||
case KnownProtocolKind::Protocol: llvm_unreachable("Not a literal protocol");
|
||||
#define LITERAL_CONVERTIBLE_PROTOCOL(Protocol)
|
||||
#include "swift/AST/KnownProtocols.def"
|
||||
|
||||
case KnownProtocolKind::ArrayLiteralConvertible:
|
||||
index = 0;
|
||||
break;
|
||||
|
||||
case KnownProtocolKind::CharacterLiteralConvertible:
|
||||
index = 1;
|
||||
break;
|
||||
|
||||
case KnownProtocolKind::DictionaryLiteralConvertible:
|
||||
index = 2;
|
||||
break;
|
||||
|
||||
case KnownProtocolKind::FloatLiteralConvertible:
|
||||
index = 3;
|
||||
break;
|
||||
|
||||
case KnownProtocolKind::IntegerLiteralConvertible:
|
||||
index = 4;
|
||||
break;
|
||||
|
||||
case KnownProtocolKind::StringInterpolationConvertible:
|
||||
index = 5;
|
||||
break;
|
||||
|
||||
case KnownProtocolKind::StringLiteralConvertible:
|
||||
index = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we already looked for alternative literal types, return those results.
|
||||
if (AlternativeLiteralTypes[index])
|
||||
return *AlternativeLiteralTypes[index];
|
||||
|
||||
// Collect all of the types that conform to the given literal protocol.
|
||||
SmallVector<Type, 4> types;
|
||||
for (auto decl : TC.Context.getTypesThatConformTo(kind)) {
|
||||
Type type;
|
||||
if (auto nominal = dyn_cast<NominalTypeDecl>(decl))
|
||||
type = nominal->getDeclaredTypeOfContext();
|
||||
else
|
||||
type = cast<ExtensionDecl>(decl)->getDeclaredTypeOfContext();
|
||||
|
||||
types.push_back(type);
|
||||
}
|
||||
|
||||
AlternativeLiteralTypes[index] = allocateCopy(types);
|
||||
return *AlternativeLiteralTypes[index];
|
||||
}
|
||||
|
||||
ConstraintLocator *ConstraintSystem::getConstraintLocator(
|
||||
Expr *anchor,
|
||||
ArrayRef<ConstraintLocator::PathElement> path) {
|
||||
|
||||
@@ -968,6 +968,9 @@ private:
|
||||
llvm::DenseMap<std::pair<Type, Identifier>, Optional<LookupResult>>
|
||||
MemberLookups;
|
||||
|
||||
/// Cached sets of "alternative" literal types.
|
||||
Optional<ArrayRef<Type>> AlternativeLiteralTypes[7];
|
||||
|
||||
/// \brief Folding set containing all of the locators used in this
|
||||
/// constraint system.
|
||||
llvm::FoldingSet<ConstraintLocator> ConstraintLocators;
|
||||
@@ -1171,6 +1174,10 @@ public:
|
||||
/// \returns A reference to the member-lookup result.
|
||||
LookupResult &lookupMember(Type base, Identifier name);
|
||||
|
||||
/// Retrieve the set of "alternative" literal types that we'll explore
|
||||
/// for a given literal protocol kind.
|
||||
ArrayRef<Type> getAlternativeLiteralTypes(KnownProtocolKind kind);
|
||||
|
||||
/// \brief Create a new type variable.
|
||||
TypeVariableType *createTypeVariable(ConstraintLocator *locator,
|
||||
unsigned options) {
|
||||
@@ -1545,6 +1552,11 @@ public:
|
||||
return allocateCopy(array.begin(), array.end());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ArrayRef<T> allocateCopy(SmallVectorImpl<T> &vec) {
|
||||
return allocateCopy(vec.begin(), vec.end());
|
||||
}
|
||||
|
||||
/// \brief Generate constraints for the given (unchecked) expression.
|
||||
///
|
||||
/// \returns a possibly-sanitized expression, or null if an error occurred.
|
||||
|
||||
Reference in New Issue
Block a user