mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
More progress towards getting same-type constraints working correctly.
Swift SVN r16023
This commit is contained in:
@@ -40,7 +40,7 @@ enum class AllocationArena;
|
|||||||
|
|
||||||
/// \brief Type substitution mapping from substitutable types to their
|
/// \brief Type substitution mapping from substitutable types to their
|
||||||
/// replacements.
|
/// replacements.
|
||||||
typedef llvm::DenseMap<SubstitutableType *, Type> TypeSubstitutionMap;
|
typedef llvm::DenseMap<TypeBase *, Type> TypeSubstitutionMap;
|
||||||
|
|
||||||
/// Map from non-type requirements to the corresponding conformance witnesses.
|
/// Map from non-type requirements to the corresponding conformance witnesses.
|
||||||
typedef llvm::DenseMap<ValueDecl *, ConcreteDeclRef> WitnessMap;
|
typedef llvm::DenseMap<ValueDecl *, ConcreteDeclRef> WitnessMap;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class TypeWalker;
|
|||||||
|
|
||||||
/// \brief Type substitution mapping from substitutable types to their
|
/// \brief Type substitution mapping from substitutable types to their
|
||||||
/// replacements.
|
/// replacements.
|
||||||
typedef llvm::DenseMap<SubstitutableType *, Type> TypeSubstitutionMap;
|
typedef llvm::DenseMap<TypeBase *, Type> TypeSubstitutionMap;
|
||||||
|
|
||||||
/// Type - This is a simple value object that contains a pointer to a type
|
/// Type - This is a simple value object that contains a pointer to a type
|
||||||
/// class. This is potentially sugared. We use this throughout the codebase
|
/// class. This is potentially sugared. We use this throughout the codebase
|
||||||
|
|||||||
@@ -1640,10 +1640,6 @@ GenericParamList::getSubstitutionMap(ArrayRef<swift::Substitution> Subs) const {
|
|||||||
auto sub = Subs.front();
|
auto sub = Subs.front();
|
||||||
Subs = Subs.slice(1);
|
Subs = Subs.slice(1);
|
||||||
|
|
||||||
// Only substitute primary archetypes.
|
|
||||||
if (!arch->isPrimary())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
map.insert({arch, sub.Replacement});
|
map.insert({arch, sub.Replacement});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1757,15 +1753,24 @@ GenericSignature::getSubstitutionMap(ArrayRef<Substitution> args) const {
|
|||||||
return subs;
|
return subs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Seed the type map with pre-existing substitutions.
|
||||||
|
for (auto sub : args) {
|
||||||
|
subs[sub.Archetype] = sub.Replacement;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto depTy : getAllDependentTypes()) {
|
for (auto depTy : getAllDependentTypes()) {
|
||||||
auto replacement = args.front().Replacement;
|
auto replacement = args.front().Replacement;
|
||||||
args = args.slice(1);
|
args = args.slice(1);
|
||||||
// FIXME: DependentMemberTypes aren't SubstitutableTypes.
|
|
||||||
if (auto subTy = depTy->getAs<SubstitutableType>())
|
if (auto subTy = depTy->getAs<SubstitutableType>()) {
|
||||||
subs[subTy] = replacement;
|
subs[subTy] = replacement;
|
||||||
|
}
|
||||||
|
else if (auto dTy = depTy->getAs<DependentMemberType>()) {
|
||||||
|
subs[dTy] = replacement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(args.empty() && "did not use all substitutions?!");
|
assert(args.empty() && "did not use all substitutions?!");
|
||||||
return subs;
|
return subs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1896,8 +1901,15 @@ Type Type::subst(Module *module, TypeSubstitutionMap &substitutions,
|
|||||||
.subst(module, substitutions, ignoreMissing, resolver);
|
.subst(module, substitutions, ignoreMissing, resolver);
|
||||||
|
|
||||||
// Resolve the member relative to the substituted base.
|
// Resolve the member relative to the substituted base.
|
||||||
if (Type r = depMemTy->substBaseType(module, newBase, resolver))
|
if (Type r = depMemTy->substBaseType(module, newBase, resolver)) {
|
||||||
|
|
||||||
|
// Substitute archtypes for generic type parameters to prevent
|
||||||
|
// dependent types from leaking.
|
||||||
|
if (auto GTPT = r->getAs<GenericTypeParamType>()) {
|
||||||
|
return GTPT->getDecl()->getArchetype();
|
||||||
|
}
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
return failed(type);
|
return failed(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -566,8 +566,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
|
|||||||
// Add a new constraint between these types. We consider the current
|
// Add a new constraint between these types. We consider the current
|
||||||
// type-matching problem to the "solved" by this addition, because
|
// type-matching problem to the "solved" by this addition, because
|
||||||
// this new constraint will be solved at a later point.
|
// this new constraint will be solved at a later point.
|
||||||
// Obviously, this must not happen at the top level, or the algorithm
|
// Obviously, this must not happen at the top level, or the
|
||||||
// would not terminate.
|
// algorithm would not terminate.
|
||||||
addConstraint(getConstraintKind(kind), rep1, rep2,
|
addConstraint(getConstraintKind(kind), rep1, rep2,
|
||||||
getConstraintLocator(locator));
|
getConstraintLocator(locator));
|
||||||
return SolutionKind::Solved;
|
return SolutionKind::Solved;
|
||||||
|
|||||||
@@ -1189,10 +1189,17 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
|
|||||||
// in the case of a conformance check against an associated type rooted off of
|
// in the case of a conformance check against an associated type rooted off of
|
||||||
// "Self"), we'll need to open the type up so as not to short-circuit the
|
// "Self"), we'll need to open the type up so as not to short-circuit the
|
||||||
// binding constraint against the already bound overload type.
|
// binding constraint against the already bound overload type.
|
||||||
if ((choice.getKind() == OverloadChoiceKind::TypeDecl) &&
|
if (refType->isDependentType()) {
|
||||||
refType->getAs<DependentMemberType>()) {
|
openedFullType = openType(openedFullType,
|
||||||
|
choice.getDecl()->
|
||||||
|
getPotentialGenericDeclContext());
|
||||||
refType = openType(refType,
|
refType = openType(refType,
|
||||||
choice.getDecl()->getPotentialGenericDeclContext());
|
choice.getDecl()->getPotentialGenericDeclContext());
|
||||||
|
|
||||||
|
if (auto FT = openedFullType->getAs<FunctionType>()) {
|
||||||
|
auto returnType = FT->getResult();
|
||||||
|
addConstraint(ConstraintKind::Bind, returnType, refType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the type binding constraint.
|
// Add the type binding constraint.
|
||||||
|
|||||||
@@ -824,9 +824,11 @@ bool TypeChecker::checkSubstitutions(TypeSubstitutionMap &Substitutions,
|
|||||||
// Find all of the primary archetypes and enter them into the archetype
|
// Find all of the primary archetypes and enter them into the archetype
|
||||||
// stack.
|
// stack.
|
||||||
for (const auto &sub : Substitutions) {
|
for (const auto &sub : Substitutions) {
|
||||||
auto archetype = sub.first->getArchetype();
|
if (auto subTy = sub.first->getAs<SubstitutableType>()) {
|
||||||
if (archetype->isPrimary() && knownArchetypes.insert(archetype))
|
auto archetype = subTy->getArchetype();
|
||||||
archetypeStack.push_back(archetype);
|
if (archetype->isPrimary() && knownArchetypes.insert(archetype))
|
||||||
|
archetypeStack.push_back(archetype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that each of the replacements for the archetypes conform
|
// Check that each of the replacements for the archetypes conform
|
||||||
|
|||||||
@@ -352,8 +352,8 @@ public:
|
|||||||
// then required to have keywords for every argument that name properties
|
// then required to have keywords for every argument that name properties
|
||||||
// of the type.
|
// of the type.
|
||||||
Pattern *visitCallExpr(CallExpr *ce) {
|
Pattern *visitCallExpr(CallExpr *ce) {
|
||||||
DependentGenericTypeResolver resolver;
|
PartialGenericTypeToArchetypeResolver resolver(TC);
|
||||||
|
|
||||||
SmallVector<ComponentIdentTypeRepr *, 2> components;
|
SmallVector<ComponentIdentTypeRepr *, 2> components;
|
||||||
if (!ExprToIdentTypeRepr(components, TC.Context).visit(ce->getFn()))
|
if (!ExprToIdentTypeRepr(components, TC.Context).visit(ce->getFn()))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user