mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #71780 from slavapestov/remove-non-experimental-assoc-type-inference
Remove old associated type inference implementation
This commit is contained in:
@@ -747,10 +747,6 @@ public:
|
||||
/// Override the witness for a given requirement.
|
||||
void overrideWitness(ValueDecl *requirement, Witness newWitness);
|
||||
|
||||
/// Populate the signature conformances without checking if they satisfy
|
||||
/// requirements. Can only be used with parsed or imported conformances.
|
||||
void finishSignatureConformances();
|
||||
|
||||
/// Determine whether the witness for the given type requirement
|
||||
/// is the default definition.
|
||||
bool usesDefaultDefinition(AssociatedTypeDecl *requirement) const {
|
||||
|
||||
@@ -567,9 +567,6 @@ namespace swift {
|
||||
/// rewrite system.
|
||||
bool EnableRequirementMachineOpaqueArchetypes = false;
|
||||
|
||||
/// Enable experimental associated type inference improvements.
|
||||
bool EnableExperimentalAssociatedTypeInference = false;
|
||||
|
||||
/// Enable implicit lifetime dependence for ~Escapable return types.
|
||||
bool EnableExperimentalLifetimeDependenceInference = true;
|
||||
|
||||
|
||||
@@ -657,14 +657,6 @@ def disable_experimental_string_processing :
|
||||
Flag<["-"], "disable-experimental-string-processing">,
|
||||
HelpText<"Disable experimental string processing">;
|
||||
|
||||
def enable_experimental_associated_type_inference :
|
||||
Flag<["-"], "enable-experimental-associated-type-inference">,
|
||||
HelpText<"Enable experimental associated type inference improvements">;
|
||||
|
||||
def disable_experimental_associated_type_inference :
|
||||
Flag<["-"], "disable-experimental-associated-type-inference">,
|
||||
HelpText<"Disable experimental associated type inference improvements">;
|
||||
|
||||
def enable_experimental_lifetime_dependence_inference :
|
||||
Flag<["-"], "enable-experimental-lifetime-dependence-inference">,
|
||||
HelpText<"Enable experimental lifetime dependence inference">;
|
||||
|
||||
@@ -563,14 +563,6 @@ NormalProtocolConformance::getAssociatedConformance(Type assocType,
|
||||
forEachAssociatedConformance(
|
||||
[&](Type t, ProtocolDecl *p, unsigned index) {
|
||||
if (t->isEqual(assocType) && p == protocol) {
|
||||
if (!ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
// Fill in the signature conformances, if we haven't done so yet.
|
||||
if (!hasComputedAssociatedConformances()) {
|
||||
const_cast<NormalProtocolConformance *>(this)
|
||||
->finishSignatureConformances();
|
||||
}
|
||||
}
|
||||
|
||||
// Not strictly necessary, but avoids a bit of request evaluator
|
||||
// overhead in the happy case.
|
||||
if (hasComputedAssociatedConformances()) {
|
||||
@@ -632,28 +624,6 @@ void NormalProtocolConformance::setAssociatedConformance(
|
||||
AssociatedConformances[index] = assocConf;
|
||||
}
|
||||
|
||||
/// Collect conformances for the requirement signature.
|
||||
void NormalProtocolConformance::finishSignatureConformances() {
|
||||
if (Loader)
|
||||
resolveLazyInfo();
|
||||
|
||||
if (hasComputedAssociatedConformances())
|
||||
return;
|
||||
|
||||
createAssociatedConformanceArray();
|
||||
|
||||
auto &ctx = getDeclContext()->getASTContext();
|
||||
|
||||
forEachAssociatedConformance(
|
||||
[&](Type origTy, ProtocolDecl *reqProto, unsigned index) {
|
||||
auto canTy = origTy->getCanonicalType();
|
||||
evaluateOrDefault(ctx.evaluator,
|
||||
AssociatedConformanceRequest{this, canTy, reqProto, index},
|
||||
ProtocolConformanceRef::forInvalid());
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
Witness RootProtocolConformance::getWitness(ValueDecl *requirement) const {
|
||||
ROOT_CONFORMANCE_SUBCLASS_DISPATCH(getWitness, (requirement))
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ LangOptions::LangOptions() {
|
||||
// Default-on NoncopyableGenerics when the build-script setting is enabled.
|
||||
if (SWIFT_ENABLE_EXPERIMENTAL_NONCOPYABLE_GENERICS) {
|
||||
Features.insert(Feature::NoncopyableGenerics);
|
||||
EnableExperimentalAssociatedTypeInference = true;
|
||||
}
|
||||
|
||||
// Enable any playground options that are enabled by default.
|
||||
|
||||
@@ -1390,13 +1390,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
if (Args.hasArg(OPT_enable_requirement_machine_opaque_archetypes))
|
||||
Opts.EnableRequirementMachineOpaqueArchetypes = true;
|
||||
|
||||
Opts.EnableExperimentalAssociatedTypeInference = true;
|
||||
|
||||
if (Args.hasArg(OPT_enable_experimental_associated_type_inference))
|
||||
Opts.EnableExperimentalAssociatedTypeInference = true;
|
||||
if (Args.hasArg(OPT_disable_experimental_associated_type_inference))
|
||||
Opts.EnableExperimentalAssociatedTypeInference = false;
|
||||
|
||||
if (Args.hasArg(OPT_enable_experimental_lifetime_dependence_inference))
|
||||
Opts.EnableExperimentalLifetimeDependenceInference = true;
|
||||
if (Args.hasArg(OPT_disable_experimental_lifetime_dependence_inference))
|
||||
|
||||
@@ -1656,8 +1656,6 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
|
||||
if (bool(requireNCGenerics)) {
|
||||
genericSubInvocation.getLangOptions()
|
||||
.enableFeature(Feature::NoncopyableGenerics);
|
||||
genericSubInvocation.getLangOptions()
|
||||
.EnableExperimentalAssociatedTypeInference = true;
|
||||
}
|
||||
|
||||
// Pass-down the obfuscators so we can get the serialized search paths properly.
|
||||
|
||||
@@ -144,21 +144,9 @@ checkTypeWitness(Type type, AssociatedTypeDecl *assocType,
|
||||
if (type->hasError())
|
||||
return CheckTypeWitnessResult::forError();
|
||||
|
||||
// If the type witness is equivalent to some other unresolved witness,
|
||||
// we cannot check anything, so accept the witness.
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
|
||||
if (type->isTypeParameter())
|
||||
return CheckTypeWitnessResult::forSuccess();
|
||||
|
||||
} else {
|
||||
|
||||
assert(!type->hasTypeParameter());
|
||||
if (type->is<DependentMemberType>())
|
||||
return CheckTypeWitnessResult::forSuccess();
|
||||
|
||||
}
|
||||
|
||||
const auto proto = Conf->getProtocol();
|
||||
const auto dc = Conf->getDeclContext();
|
||||
const auto sig = proto->getGenericSignature();
|
||||
@@ -1016,10 +1004,6 @@ class AssociatedTypeInference {
|
||||
Type failedDefaultedWitness;
|
||||
CheckTypeWitnessResult failedDefaultedResult = CheckTypeWitnessResult::forSuccess();
|
||||
|
||||
/// Information about a failed, derived associated type.
|
||||
AssociatedTypeDecl *failedDerivedAssocType = nullptr;
|
||||
Type failedDerivedWitness;
|
||||
|
||||
// Which type witness was missing?
|
||||
AssociatedTypeDecl *missingTypeWitness = nullptr;
|
||||
|
||||
@@ -1081,10 +1065,6 @@ private:
|
||||
/// type.
|
||||
Type computeGenericParamWitness(AssociatedTypeDecl *assocType) const;
|
||||
|
||||
/// Compute a type witness without using a specific potential witness.
|
||||
std::optional<AbstractTypeWitness>
|
||||
computeAbstractTypeWitness(AssociatedTypeDecl *assocType);
|
||||
|
||||
/// Collect abstract type witnesses and feed them to the given system.
|
||||
void collectAbstractTypeWitnesses(
|
||||
TypeWitnessSystem &system,
|
||||
@@ -1094,9 +1074,6 @@ private:
|
||||
/// any remain unsubstituted.
|
||||
bool simplifyCurrentTypeWitnesses();
|
||||
|
||||
/// Substitute the current type witnesses into the given interface type.
|
||||
Type substCurrentTypeWitnesses(Type type);
|
||||
|
||||
/// Retrieve substitution options with a tentative type witness
|
||||
/// operation that queries the current set of type witnesses.
|
||||
SubstOptions getSubstOptionsWithCurrentTypeWitnesses();
|
||||
@@ -1458,43 +1435,21 @@ static InferenceCandidateKind checkInferenceCandidate(
|
||||
auto genericSig = witness->getInnermostDeclContext()
|
||||
->getGenericSignatureOfContext();
|
||||
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
// If the witness is in a protocol extension for a completely unrelated
|
||||
// protocol that doesn't declare an associated type with the same name as
|
||||
// the one we are trying to infer, then it will never be tautological.
|
||||
if (!genericSig->isValidTypeParameter(selfAssocTy))
|
||||
return InferenceCandidateKind::Good;
|
||||
}
|
||||
// If the witness is in a protocol extension for a completely unrelated
|
||||
// protocol that doesn't declare an associated type with the same name as
|
||||
// the one we are trying to infer, then it will never be tautological.
|
||||
if (!genericSig->isValidTypeParameter(selfAssocTy))
|
||||
return InferenceCandidateKind::Good;
|
||||
|
||||
// A tautological binding is one where the left-hand side has the same
|
||||
// reduced type as the right-hand side in the generic signature of the
|
||||
// witness.
|
||||
auto isTautological = [&](Type t) -> bool {
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
|
||||
auto dmt = t->getAs<DependentMemberType>();
|
||||
if (!dmt)
|
||||
return false;
|
||||
|
||||
return genericSig->areReducedTypeParametersEqual(dmt, selfAssocTy);
|
||||
|
||||
} else {
|
||||
|
||||
auto dmt = t->getAs<DependentMemberType>();
|
||||
if (!dmt)
|
||||
return false;
|
||||
if (!associatedTypesAreSameEquivalenceClass(dmt->getAssocType(),
|
||||
result->first))
|
||||
return false;
|
||||
|
||||
Type typeInContext =
|
||||
conformance->getDeclContext()->mapTypeIntoContext(conformance->getType());
|
||||
if (!dmt->getBase()->isEqual(typeInContext))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// Self.X == Self.X doesn't give us any new information, nor does it
|
||||
@@ -1518,8 +1473,6 @@ static InferenceCandidateKind checkInferenceCandidate(
|
||||
break;
|
||||
|
||||
case RequirementKind::SameType:
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
|
||||
auto matches = [&](Type t) {
|
||||
if (auto *dmt = t->getAs<DependentMemberType>()) {
|
||||
return (dmt->getName() == result->first->getName() &&
|
||||
@@ -1552,37 +1505,6 @@ static InferenceCandidateKind checkInferenceCandidate(
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
auto *dmt = result->second->castTo<DependentMemberType>();
|
||||
auto selfAssocTy = DependentMemberType::get(selfTy, dmt->getAssocType());
|
||||
|
||||
Type other;
|
||||
if (reqt.getFirstType()->isEqual(selfAssocTy)) {
|
||||
other = reqt.getSecondType();
|
||||
} else if (reqt.getSecondType()->isEqual(selfAssocTy)) {
|
||||
other = reqt.getFirstType();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto otherAssoc = other->getAs<DependentMemberType>()) {
|
||||
if (otherAssoc->getBase()->isEqual(selfTy)) {
|
||||
auto *otherDMT = DependentMemberType::get(dmt->getBase(),
|
||||
otherAssoc->getAssocType());
|
||||
|
||||
result->second = result->second.transform([&](Type t) -> Type{
|
||||
if (t->isEqual(dmt))
|
||||
return otherDMT;
|
||||
return t;
|
||||
});
|
||||
LLVM_DEBUG(llvm::dbgs() << "++ we can same-type to:\n";
|
||||
result->second->dump(llvm::dbgs()));
|
||||
return InferenceCandidateKind::Good;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1799,7 +1721,6 @@ AssociatedTypeInference::getPotentialTypeWitnessesFromRequirement(
|
||||
// FIXME: Generate new constraints by matching the two types.
|
||||
auto newWitness = result.second->getCanonicalType();
|
||||
if (!newWitness->hasTypeParameter() &&
|
||||
!newWitness->hasDependentMember() &&
|
||||
!existingWitness->isEqual(newWitness)) {
|
||||
LLVM_DEBUG(llvm::dbgs() << "** contradicts explicit type witness, "
|
||||
"rejecting inference from this decl\n");
|
||||
@@ -2021,33 +1942,6 @@ static Type getWitnessTypeForMatching(NormalProtocolConformance *conformance,
|
||||
auto proto = conformance->getProtocol();
|
||||
auto selfTy = proto->getSelfInterfaceType();
|
||||
|
||||
if (!ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
// Remap associated types that reference other protocols into this
|
||||
// protocol.
|
||||
auto resultType = Type(type).transformRec([proto](TypeBase *type)
|
||||
-> std::optional<Type> {
|
||||
if (auto depMemTy = dyn_cast<DependentMemberType>(type)) {
|
||||
if (depMemTy->getAssocType() &&
|
||||
depMemTy->getAssocType()->getProtocol() != proto) {
|
||||
if (auto *assocType = proto->getAssociatedType(depMemTy->getName())) {
|
||||
auto origProto = depMemTy->getAssocType()->getProtocol();
|
||||
if (proto->inheritsFrom(origProto))
|
||||
return Type(DependentMemberType::get(depMemTy->getBase(),
|
||||
assocType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
});
|
||||
resultType = resultType.subst(QueryTypeSubstitutionMap{substitutions},
|
||||
LookUpConformanceInModule(module));
|
||||
if (!resultType->hasError()) return resultType;
|
||||
|
||||
// Map error types with original types *back* to the original, dependent type.
|
||||
return resultType.transform(mapErrorTypeToOriginal);
|
||||
}
|
||||
|
||||
return type.transformRec([&](TypeBase *type) -> std::optional<Type> {
|
||||
// Skip.
|
||||
if (!type->hasTypeParameter())
|
||||
@@ -2117,18 +2011,16 @@ AssociatedTypeInference::inferTypeWitnessesViaAssociatedType(
|
||||
//
|
||||
// We handle the fully concrete case here, which completely rules out
|
||||
// certain invalid solutions.
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
if (auto fixedType = computeFixedTypeWitness(assocType)) {
|
||||
if (!fixedType->hasTypeParameter()) {
|
||||
InferredAssociatedTypesByWitness inferred;
|
||||
inferred.Witness = assocType;
|
||||
inferred.Inferred.push_back({assocType, fixedType});
|
||||
result.push_back(std::move(inferred));
|
||||
if (auto fixedType = computeFixedTypeWitness(assocType)) {
|
||||
if (!fixedType->hasTypeParameter()) {
|
||||
InferredAssociatedTypesByWitness inferred;
|
||||
inferred.Witness = assocType;
|
||||
inferred.Inferred.push_back({assocType, fixedType});
|
||||
result.push_back(std::move(inferred));
|
||||
|
||||
// That's it; we're forced into this binding, so we're not adding another
|
||||
// tautology below.
|
||||
return result;
|
||||
}
|
||||
// That's it; we're forced into this binding, so we're not adding another
|
||||
// tautology below.
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2331,8 +2223,6 @@ AssociatedTypeInference::getPotentialTypeWitnessesByMatchingTypes(ValueDecl *req
|
||||
if (auto *paramTy = t->getAs<GenericTypeParamType>()) {
|
||||
// But if the witness is in a protocol extension, an unsimplified
|
||||
// Self-rooted type parameter is OK.
|
||||
if (!paramTy->getASTContext().LangOpts.EnableExperimentalAssociatedTypeInference)
|
||||
return true;
|
||||
return !(SelfTy && paramTy->isEqual(SelfTy));
|
||||
}
|
||||
return false;
|
||||
@@ -2474,89 +2364,45 @@ Type AssociatedTypeInference::computeFixedTypeWitness(
|
||||
AssociatedTypeDecl *assocType) {
|
||||
Type resultType;
|
||||
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
auto selfTy = assocType->getProtocol()->getSelfInterfaceType();
|
||||
auto selfTy = assocType->getProtocol()->getSelfInterfaceType();
|
||||
|
||||
// Look through other local conformances of our declaration context to see if
|
||||
// any fix this associated type to a concrete type.
|
||||
for (auto conformance : getPeerConformances(conformance)) {
|
||||
auto *conformedProto = conformance->getProtocol();
|
||||
// Look through other local conformances of our declaration context to see if
|
||||
// any fix this associated type to a concrete type.
|
||||
for (auto conformance : getPeerConformances(conformance)) {
|
||||
auto *conformedProto = conformance->getProtocol();
|
||||
|
||||
auto sig = conformedProto->getGenericSignature();
|
||||
auto sig = conformedProto->getGenericSignature();
|
||||
|
||||
// FIXME: The RequirementMachine will assert on re-entrant construction.
|
||||
// We should find a more principled way of breaking this cycle.
|
||||
if (ctx.isRecursivelyConstructingRequirementMachine(sig.getCanonicalSignature()) ||
|
||||
ctx.isRecursivelyConstructingRequirementMachine(conformedProto) ||
|
||||
conformedProto->isComputingRequirementSignature())
|
||||
// FIXME: The RequirementMachine will assert on re-entrant construction.
|
||||
// We should find a more principled way of breaking this cycle.
|
||||
if (ctx.isRecursivelyConstructingRequirementMachine(sig.getCanonicalSignature()) ||
|
||||
ctx.isRecursivelyConstructingRequirementMachine(conformedProto) ||
|
||||
conformedProto->isComputingRequirementSignature())
|
||||
continue;
|
||||
|
||||
auto structuralTy = DependentMemberType::get(selfTy, assocType->getName());
|
||||
if (!sig->isValidTypeParameter(structuralTy))
|
||||
continue;
|
||||
|
||||
const auto ty = sig.getReducedType(structuralTy);
|
||||
|
||||
// A dependent member type with an identical base and name indicates that
|
||||
// the protocol does not same-type constrain it in any way; move on to
|
||||
// the next protocol.
|
||||
if (auto *const memberTy = ty->getAs<DependentMemberType>()) {
|
||||
if (memberTy->getBase()->isEqual(selfTy) &&
|
||||
memberTy->getName() == assocType->getName())
|
||||
continue;
|
||||
|
||||
auto structuralTy = DependentMemberType::get(selfTy, assocType->getName());
|
||||
if (!sig->isValidTypeParameter(structuralTy))
|
||||
continue;
|
||||
|
||||
const auto ty = sig.getReducedType(structuralTy);
|
||||
|
||||
// A dependent member type with an identical base and name indicates that
|
||||
// the protocol does not same-type constrain it in any way; move on to
|
||||
// the next protocol.
|
||||
if (auto *const memberTy = ty->getAs<DependentMemberType>()) {
|
||||
if (memberTy->getBase()->isEqual(selfTy) &&
|
||||
memberTy->getName() == assocType->getName())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!resultType) {
|
||||
resultType = ty;
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: Bailing out on ambiguity.
|
||||
if (!resultType->isEqual(ty))
|
||||
return Type();
|
||||
}
|
||||
} else {
|
||||
// Look at all of the inherited protocols to determine whether they
|
||||
// require a fixed type for this associated type.
|
||||
for (auto conformedProto : dc->getSelfNominalTypeDecl()->getAllProtocols()) {
|
||||
if (conformedProto != assocType->getProtocol() &&
|
||||
!conformedProto->inheritsFrom(assocType->getProtocol()))
|
||||
continue;
|
||||
|
||||
auto sig = conformedProto->getGenericSignature();
|
||||
|
||||
// FIXME: The RequirementMachine will assert on re-entrant construction.
|
||||
// We should find a more principled way of breaking this cycle.
|
||||
if (ctx.isRecursivelyConstructingRequirementMachine(sig.getCanonicalSignature()) ||
|
||||
ctx.isRecursivelyConstructingRequirementMachine(conformedProto) ||
|
||||
conformedProto->isComputingRequirementSignature())
|
||||
continue;
|
||||
|
||||
auto selfTy = conformedProto->getSelfInterfaceType();
|
||||
if (!sig->requiresProtocol(selfTy, assocType->getProtocol()))
|
||||
continue;
|
||||
|
||||
auto structuralTy = DependentMemberType::get(selfTy, assocType->getName());
|
||||
const auto ty = sig.getReducedType(structuralTy);
|
||||
|
||||
// A dependent member type with an identical base and name indicates that
|
||||
// the protocol does not same-type constrain it in any way; move on to
|
||||
// the next protocol.
|
||||
if (auto *const memberTy = ty->getAs<DependentMemberType>()) {
|
||||
if (memberTy->getBase()->isEqual(selfTy) &&
|
||||
memberTy->getName() == assocType->getName())
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!resultType) {
|
||||
resultType = ty;
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: Bailing out on ambiguity.
|
||||
if (!resultType->isEqual(ty))
|
||||
return Type();
|
||||
if (!resultType) {
|
||||
resultType = ty;
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: Bailing out on ambiguity.
|
||||
if (!resultType->isEqual(ty))
|
||||
return Type();
|
||||
}
|
||||
|
||||
return resultType;
|
||||
@@ -2687,67 +2533,12 @@ AssociatedTypeInference::computeDerivedTypeWitness(
|
||||
// Make sure that the derived type satisfies requirements.
|
||||
if (checkTypeWitness(result.first, assocType, conformance)) {
|
||||
/// FIXME: Diagnose based on this.
|
||||
failedDerivedAssocType = assocType;
|
||||
failedDerivedWitness = result.first;
|
||||
return std::make_pair(Type(), nullptr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<AbstractTypeWitness>
|
||||
AssociatedTypeInference::computeAbstractTypeWitness(
|
||||
AssociatedTypeDecl *assocType) {
|
||||
assert(!ctx.LangOpts.EnableExperimentalAssociatedTypeInference);
|
||||
|
||||
// We don't have a type witness for this associated type, so go
|
||||
// looking for more options.
|
||||
if (Type concreteType = computeFixedTypeWitness(assocType))
|
||||
return AbstractTypeWitness(assocType, concreteType);
|
||||
|
||||
// If we can form a default type, do so.
|
||||
if (const auto &typeWitness = computeDefaultTypeWitness(assocType))
|
||||
return typeWitness;
|
||||
|
||||
// Don't consider the generic parameter names for AsyncSequence.Failure or
|
||||
// AsyncIteratorProtocol.Failure; we always rely on inference from next() or
|
||||
// next(isolation:).
|
||||
if (isAsyncIteratorOrSequenceFailure(assocType)) {
|
||||
// If this is specifically AsyncSequence.Failure with the older associated
|
||||
// type inference implementation, our abstract witness is
|
||||
// "AsyncIterator.Failure". The new implementation is smart enough to do
|
||||
// this from the same-type constraint.
|
||||
if (!ctx.LangOpts.EnableExperimentalAssociatedTypeInference &&
|
||||
proto == assocType->getProtocol() &&
|
||||
proto->isSpecificProtocol(KnownProtocolKind::AsyncSequence)) {
|
||||
auto iterAssoc = proto->getAssociatedType(ctx.Id_AsyncIterator);
|
||||
auto iteratorProto =
|
||||
ctx.getProtocol(KnownProtocolKind::AsyncIteratorProtocol);
|
||||
auto iteratorFailure = iteratorProto->getAssociatedType(ctx.Id_Failure);
|
||||
Type iterType = DependentMemberType::get(
|
||||
proto->getSelfInterfaceType(), iterAssoc);
|
||||
Type depType = DependentMemberType::get(iterType, iteratorFailure);
|
||||
return AbstractTypeWitness(assocType, depType);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// If there is a generic parameter of the named type, use that.
|
||||
if (auto genericSig = dc->getGenericSignatureOfContext()) {
|
||||
for (auto gp : genericSig.getInnermostGenericParams()) {
|
||||
// Packs cannot witness associated type requirements.
|
||||
if (gp->isParameterPack())
|
||||
continue;
|
||||
|
||||
if (gp->getName() == assocType->getName())
|
||||
return AbstractTypeWitness(assocType, dc->mapTypeIntoContext(gp));
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/// Look for a generic parameter that matches the name of the
|
||||
/// associated type.
|
||||
Type AssociatedTypeInference::computeGenericParamWitness(
|
||||
@@ -2927,68 +2718,6 @@ bool AssociatedTypeInference::simplifyCurrentTypeWitnesses() {
|
||||
return anyUnsubstituted;
|
||||
}
|
||||
|
||||
Type AssociatedTypeInference::substCurrentTypeWitnesses(Type type) {
|
||||
assert(!ctx.LangOpts.EnableExperimentalAssociatedTypeInference);
|
||||
|
||||
auto substOptions = getSubstOptionsWithCurrentTypeWitnesses();
|
||||
|
||||
// Local function that folds dependent member types with non-dependent
|
||||
// bases into actual member references.
|
||||
std::function<Type(Type)> foldDependentMemberTypes;
|
||||
llvm::DenseSet<AssociatedTypeDecl *> recursionCheck;
|
||||
foldDependentMemberTypes = [&](Type type) -> Type {
|
||||
if (auto depMemTy = type->getAs<DependentMemberType>()) {
|
||||
auto baseTy = depMemTy->getBase().transform(foldDependentMemberTypes);
|
||||
if (baseTy.isNull() || baseTy->hasTypeParameter())
|
||||
return nullptr;
|
||||
|
||||
auto assocType = depMemTy->getAssocType();
|
||||
if (!assocType)
|
||||
return nullptr;
|
||||
|
||||
if (!recursionCheck.insert(assocType).second)
|
||||
return nullptr;
|
||||
|
||||
SWIFT_DEFER { recursionCheck.erase(assocType); };
|
||||
|
||||
auto *module = dc->getParentModule();
|
||||
|
||||
// Try to substitute into the base type.
|
||||
Type result = depMemTy->substBaseType(
|
||||
baseTy, LookUpConformanceInModule(module), substOptions);
|
||||
if (!result->hasError())
|
||||
return result;
|
||||
|
||||
// If that failed, check whether it's because of the conformance we're
|
||||
// evaluating.
|
||||
auto localConformance
|
||||
= module->lookupConformance(baseTy, assocType->getProtocol());
|
||||
if (localConformance.isInvalid() || localConformance.isAbstract() ||
|
||||
(localConformance.getConcrete()->getRootConformance() !=
|
||||
conformance)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Find the tentative type witness for this associated type.
|
||||
auto known = typeWitnesses.begin(assocType);
|
||||
if (known == typeWitnesses.end())
|
||||
return nullptr;
|
||||
|
||||
return known->first.transform(foldDependentMemberTypes);
|
||||
}
|
||||
|
||||
// The presence of a generic type parameter indicates that we
|
||||
// cannot use this type binding.
|
||||
if (type->is<GenericTypeParamType>()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return type;
|
||||
};
|
||||
|
||||
return type.transform(foldDependentMemberTypes);
|
||||
}
|
||||
|
||||
/// "Sanitize" requirements for conformance checking, removing any requirements
|
||||
/// that unnecessarily refer to associated types of other protocols.
|
||||
static void sanitizeProtocolRequirements(
|
||||
@@ -3071,32 +2800,12 @@ AssociatedTypeInference::getSubstOptionsWithCurrentTypeWitnesses() {
|
||||
}
|
||||
|
||||
Type type = self->typeWitnesses.begin(assocType)->first;
|
||||
|
||||
if (!thisProto->getASTContext().LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
// FIXME: Get rid of this hack.
|
||||
if (auto *aliasTy = dyn_cast<TypeAliasType>(type.getPointer()))
|
||||
type = aliasTy->getSinglyDesugaredType();
|
||||
|
||||
if (type->hasArchetype()) {
|
||||
type = type.transformRec([&](Type t) -> std::optional<Type> {
|
||||
if (auto *archetypeTy = dyn_cast<ArchetypeType>(t.getPointer())) {
|
||||
if (!isa<OpaqueTypeArchetypeType>(archetypeTy))
|
||||
return archetypeTy->getInterfaceType();
|
||||
}
|
||||
return std::nullopt;
|
||||
});
|
||||
}
|
||||
|
||||
return type.getPointer();
|
||||
} else {
|
||||
Type type = self->typeWitnesses.begin(assocType)->first;
|
||||
if (type->hasTypeParameter()) {
|
||||
// Not fully substituted yet.
|
||||
return ErrorType::get(type->getASTContext()).getPointer();
|
||||
}
|
||||
|
||||
return type->mapTypeOutOfContext().getPointer();
|
||||
if (type->hasTypeParameter()) {
|
||||
// Not fully substituted yet.
|
||||
return ErrorType::get(type->getASTContext()).getPointer();
|
||||
}
|
||||
|
||||
return type->mapTypeOutOfContext().getPointer();
|
||||
};
|
||||
return options;
|
||||
}
|
||||
@@ -3199,8 +2908,6 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
|
||||
|
||||
auto selfTypeInContext = dc->getSelfTypeInContext();
|
||||
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
|
||||
TypeWitnessSystem system(unresolvedAssocTypes);
|
||||
collectAbstractTypeWitnesses(system, unresolvedAssocTypes);
|
||||
|
||||
@@ -3273,196 +2980,6 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for (auto *const assocType : unresolvedAssocTypes) {
|
||||
// Try to compute the type without the aid of a specific potential
|
||||
// witness.
|
||||
if (const auto &typeWitness = computeAbstractTypeWitness(assocType)) {
|
||||
auto resolvedTy = typeWitness->getType();
|
||||
|
||||
resolvedTy = resolvedTy.transformRec([&](Type ty) -> std::optional<Type> {
|
||||
if (auto *gp = ty->getAs<GenericTypeParamType>()) {
|
||||
assert(gp->getDepth() == 0);
|
||||
assert(gp->getIndex() == 0);
|
||||
return selfTypeInContext;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
});
|
||||
|
||||
// Record the type witness immediately to make it available
|
||||
// for substitutions into other tentative type witnesses.
|
||||
LLVM_DEBUG(llvm::dbgs() << "Inserting tentative witness for "
|
||||
<< assocType->getName() << ": "; resolvedTy.dump(llvm::dbgs()););
|
||||
typeWitnesses.insert(assocType, {resolvedTy, reqDepth});
|
||||
|
||||
abstractTypeWitnesses.emplace_back(assocType, resolvedTy,
|
||||
typeWitness->getDefaultedAssocType());
|
||||
continue;
|
||||
}
|
||||
|
||||
// The solution is incomplete.
|
||||
return assocType;
|
||||
}
|
||||
|
||||
// Check each abstract type witness against the generic requirements on the
|
||||
// corresponding associated type.
|
||||
//
|
||||
// FIXME: Consider checking non-dependent type witnesses first. Checking in
|
||||
// default order can lead to the creation and exposure of malformed types in
|
||||
// diagnostics. For example, we would diagnose that 'G<Never>' (!) does not
|
||||
// conform to 'Sequence' in the below.
|
||||
//
|
||||
// struct G<S: Sequence> {}
|
||||
// protocol P {
|
||||
// associatedtype A: Sequence = G<B>
|
||||
// associatedtype B: Sequence = Never
|
||||
// }
|
||||
const auto substOptions = getSubstOptionsWithCurrentTypeWitnesses();
|
||||
for (const auto &witness : abstractTypeWitnesses) {
|
||||
auto *const assocType = witness.getAssocType();
|
||||
Type type = witness.getType();
|
||||
|
||||
LLVM_DEBUG(llvm::dbgs() << "Checking witness for " << assocType->getName()
|
||||
<< " " << type << "\n";);
|
||||
|
||||
assert(!type->hasTypeParameter());
|
||||
|
||||
// Replace type parameters with other known or tentative type witnesses.
|
||||
if (type->hasDependentMember()) {
|
||||
// FIXME: We should find a better way to detect and reason about these
|
||||
// cyclic solutions so that we can spot them earlier and express them in
|
||||
// diagnostics.
|
||||
llvm::SmallPtrSet<AssociatedTypeDecl *, 4> circularityCheck;
|
||||
circularityCheck.insert(assocType);
|
||||
|
||||
std::function<std::optional<Type>(Type)> substCurrentTypeWitnesses;
|
||||
substCurrentTypeWitnesses = [&](Type ty) -> std::optional<Type> {
|
||||
auto *const dmt = ty->getAs<DependentMemberType>();
|
||||
if (!dmt) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto substBase =
|
||||
dmt->getBase().transformRec(substCurrentTypeWitnesses);
|
||||
if (!substBase) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If the transformed base has the same nominal as the adoptee, we may
|
||||
// need to look up a tentative type witness. Otherwise, just substitute
|
||||
// the base.
|
||||
if (substBase->getAnyNominal() != dc->getSelfNominalTypeDecl()) {
|
||||
auto substTy = dmt->substBaseType(
|
||||
substBase,
|
||||
LookUpConformanceInModule(dc->getParentModule()),
|
||||
substOptions);
|
||||
|
||||
// If any unresolved dependent member types remain, give up.
|
||||
if (containsConcreteDependentMemberType(substTy))
|
||||
return nullptr;
|
||||
|
||||
return substTy;
|
||||
}
|
||||
|
||||
auto *assocTy = dmt->getAssocType();
|
||||
assert(
|
||||
assocTy &&
|
||||
"found structural DependentMemberType in tentative type witness");
|
||||
|
||||
// Intercept recursive solutions.
|
||||
if (!circularityCheck.insert(assocTy).second) {
|
||||
return nullptr;
|
||||
}
|
||||
SWIFT_DEFER { circularityCheck.erase(dmt->getAssocType()); };
|
||||
|
||||
if (assocTy->getProtocol() == proto) {
|
||||
// We have the associated type we need.
|
||||
} else if (proto->inheritsFrom(assocTy->getProtocol())) {
|
||||
// See if there is an associated type with the same name in our
|
||||
// protocol. If there isn't, keep the original associated type:
|
||||
// we'll be falling back to a base substitution.
|
||||
if (auto *decl = proto->getAssociatedType(assocTy->getName())) {
|
||||
assocTy = decl;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the type witness for this associated type.
|
||||
Type tyWitness;
|
||||
if (assocTy->getProtocol() == proto && typeWitnesses.count(assocTy)) {
|
||||
tyWitness = typeWitnesses.begin(assocTy)->first;
|
||||
assert(!tyWitness->hasTypeParameter());
|
||||
|
||||
// A tentative type witness may contain a 'Self'-rooted type
|
||||
// parameter,
|
||||
// FIXME: or a weird concrete-type-rooted dependent member type
|
||||
// coming from inference via a value witness. Make sure we sort these
|
||||
// out so that we don't break any subst() invariants.
|
||||
if (tyWitness->hasDependentMember()) {
|
||||
tyWitness = tyWitness.transformRec(substCurrentTypeWitnesses);
|
||||
}
|
||||
|
||||
if (tyWitness) {
|
||||
// If the transformed base is specialized, apply substitutions.
|
||||
if (tyWitness->hasArchetype()) {
|
||||
const auto conf = dc->getParentModule()->lookupConformance(
|
||||
substBase, assocTy->getProtocol(), /*allowMissing=*/true);
|
||||
if (auto *specialized = dyn_cast<SpecializedProtocolConformance>(
|
||||
conf.getConcrete())) {
|
||||
tyWitness = tyWitness.subst(specialized->getSubstitutionMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The associated type has a recorded type witness, or comes from a
|
||||
// different, possibly unrelated protocol; fall back to a base
|
||||
// substitution to find the type witness.
|
||||
tyWitness =
|
||||
DependentMemberType::get(proto->getSelfInterfaceType(), assocTy)
|
||||
->substBaseType(dc->getParentModule(), substBase);
|
||||
}
|
||||
|
||||
return tyWitness;
|
||||
};
|
||||
|
||||
type = type.transformRec(substCurrentTypeWitnesses);
|
||||
|
||||
// If substitution failed, give up.
|
||||
if (!type || type->hasError()) {
|
||||
LLVM_DEBUG(llvm::dbgs() << "-- Simplification failed\n");
|
||||
return assocType;
|
||||
}
|
||||
|
||||
// If any unresolved dependent member types remain, give up.
|
||||
assert(!containsConcreteDependentMemberType(type));
|
||||
|
||||
// Update the entry for this associated type.
|
||||
LLVM_DEBUG(llvm::dbgs() << "Updating tentative witness for "
|
||||
<< assocType->getName() << ": "; type.dump(llvm::dbgs()););
|
||||
typeWitnesses.insert(assocType, {type, reqDepth});
|
||||
}
|
||||
|
||||
if (const auto failed =
|
||||
checkTypeWitness(type, assocType, conformance)) {
|
||||
LLVM_DEBUG(llvm::dbgs() << "- Type witness does not satisfy requirements\n";);
|
||||
|
||||
// We failed to satisfy a requirement. If this is a default type
|
||||
// witness failure and we haven't seen one already, write it down.
|
||||
auto *defaultedAssocType = witness.getDefaultedAssocType();
|
||||
if (defaultedAssocType && !failedDefaultedAssocType &&
|
||||
failed.getKind() != CheckTypeWitnessResult::Error) {
|
||||
failedDefaultedAssocType = defaultedAssocType;
|
||||
failedDefaultedWitness = type;
|
||||
failedDefaultedResult = failed;
|
||||
}
|
||||
|
||||
return assocType;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -3560,72 +3077,12 @@ void AssociatedTypeInference::findSolutionsRec(
|
||||
|
||||
++NumSolutionStates;
|
||||
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
|
||||
if (simplifyCurrentTypeWitnesses()) {
|
||||
LLVM_DEBUG(llvm::dbgs() << std::string(valueWitnesses.size(), '+')
|
||||
<< "+ Unsubstituted witnesses remain\n";);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Fold any concrete dependent member types that remain among our
|
||||
// tentative type witnesses.
|
||||
//
|
||||
// FIXME: inferAbstractTypeWitnesses() also does this in a different way;
|
||||
// combine the two.
|
||||
for (auto assocType : proto->getAssociatedTypeMembers()) {
|
||||
if (conformance->hasTypeWitness(assocType))
|
||||
continue;
|
||||
|
||||
// If the type binding does not have a type parameter, there's nothing
|
||||
// to do.
|
||||
auto known = typeWitnesses.begin(assocType);
|
||||
assert(known != typeWitnesses.end());
|
||||
if (!known->first->hasTypeParameter() &&
|
||||
!known->first->hasDependentMember())
|
||||
continue;
|
||||
|
||||
Type replaced = substCurrentTypeWitnesses(known->first);
|
||||
if (replaced.isNull()) {
|
||||
LLVM_DEBUG(llvm::dbgs() << std::string(valueWitnesses.size(), '+')
|
||||
<< "+ Failed substitution of " << known->first << "\n";);
|
||||
return;
|
||||
}
|
||||
|
||||
known->first = replaced;
|
||||
}
|
||||
|
||||
// Check whether our current solution matches the given solution.
|
||||
auto matchesSolution =
|
||||
[&](const InferredTypeWitnessesSolution &solution) {
|
||||
for (const auto &existingTypeWitness : solution.TypeWitnesses) {
|
||||
auto typeWitness = typeWitnesses.begin(existingTypeWitness.first);
|
||||
if (!typeWitness->first->isEqual(existingTypeWitness.second.first))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// If we've seen this solution already, bail out; there's no point in
|
||||
// checking further.
|
||||
if (llvm::any_of(solutions, matchesSolution)) {
|
||||
LLVM_DEBUG(llvm::dbgs() << std::string(valueWitnesses.size(), '+')
|
||||
<< "+ Duplicate valid solution found\n";);
|
||||
++NumDuplicateSolutionStates;
|
||||
return;
|
||||
}
|
||||
if (llvm::any_of(nonViableSolutions, matchesSolution)) {
|
||||
LLVM_DEBUG(llvm::dbgs() << std::string(valueWitnesses.size(), '+')
|
||||
<< "+ Duplicate invalid solution found\n";);
|
||||
++NumDuplicateSolutionStates;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Check the current set of type witnesses.
|
||||
bool invalid = checkCurrentTypeWitnesses(valueWitnesses);
|
||||
|
||||
@@ -3652,8 +3109,6 @@ void AssociatedTypeInference::findSolutionsRec(
|
||||
= numValueWitnessesInProtocolExtensions;
|
||||
|
||||
// We fold away non-viable solutions that have the same type witnesses.
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
|
||||
if (invalid) {
|
||||
if (llvm::find(nonViableSolutions, solution) != nonViableSolutions.end()) {
|
||||
LLVM_DEBUG(llvm::dbgs() << std::string(valueWitnesses.size(), '+')
|
||||
@@ -3666,22 +3121,6 @@ void AssociatedTypeInference::findSolutionsRec(
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
|
||||
auto &solutionList = invalid ? nonViableSolutions : solutions;
|
||||
solutionList.push_back(solution);
|
||||
|
||||
// If this solution was clearly better than the previous best solution,
|
||||
// swap them.
|
||||
if (solutionList.back().NumValueWitnessesInProtocolExtensions
|
||||
< solutionList.front().NumValueWitnessesInProtocolExtensions) {
|
||||
std::swap(solutionList.front(), solutionList.back());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// For valid solutions, we want to find the best solution if one exists.
|
||||
// We maintain the invariant that no viable solution is clearly worse than
|
||||
// any other viable solution. If multiple viable solutions remain after
|
||||
@@ -3712,7 +3151,6 @@ void AssociatedTypeInference::findSolutionsRec(
|
||||
|
||||
solutions.push_back(std::move(solution));
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3822,12 +3260,9 @@ void AssociatedTypeInference::findSolutionsRec(
|
||||
// drop the one with the type parameter.
|
||||
//
|
||||
// FIXME: This is too ad-hoc. Generate new constraints instead.
|
||||
if ((known->first->hasTypeParameter() ||
|
||||
known->first->hasDependentMember())
|
||||
!= (typeWitness.second->hasTypeParameter() ||
|
||||
typeWitness.second->hasDependentMember())) {
|
||||
if (typeWitness.second->hasTypeParameter() ||
|
||||
typeWitness.second->hasDependentMember())
|
||||
if (known->first->hasTypeParameter()
|
||||
!= typeWitness.second->hasTypeParameter()) {
|
||||
if (typeWitness.second->hasTypeParameter())
|
||||
continue;
|
||||
|
||||
known->first = typeWitness.second;
|
||||
@@ -4548,10 +3983,7 @@ auto AssociatedTypeInference::solve() -> std::optional<InferredTypeWitnesses> {
|
||||
for (auto assocType : unresolvedAssocTypes) {
|
||||
assert(typeWitnesses.count(assocType) == 1 && "missing witness");
|
||||
auto replacement = typeWitnesses[assocType].first;
|
||||
// FIXME: We can end up here with dependent types that were not folded
|
||||
// away for some reason.
|
||||
if (replacement->hasDependentMember())
|
||||
return std::nullopt;
|
||||
assert(!replacement->hasTypeParameter());
|
||||
|
||||
if (replacement->hasArchetype()) {
|
||||
replacement = replacement->mapTypeOutOfContext();
|
||||
@@ -4978,32 +4410,30 @@ TypeWitnessRequest::evaluate(Evaluator &eval,
|
||||
case ResolveWitnessResult::Missing: {
|
||||
auto &ctx = requirement->getASTContext();
|
||||
|
||||
if (ctx.LangOpts.EnableExperimentalAssociatedTypeInference) {
|
||||
// Let's see if there is a better conformance we can perform associated
|
||||
// type inference on.
|
||||
auto *better = getBetterConformanceForResolvingTypeWitnesses(
|
||||
conformance, requirement);
|
||||
// Let's see if there is a better conformance we can perform associated
|
||||
// type inference on.
|
||||
auto *better = getBetterConformanceForResolvingTypeWitnesses(
|
||||
conformance, requirement);
|
||||
|
||||
if (better == conformance) {
|
||||
LLVM_DEBUG(llvm::dbgs() << "Conformance to " << conformance->getProtocol()->getName()
|
||||
<< " is best\n";);
|
||||
} else {
|
||||
LLVM_DEBUG(llvm::dbgs() << "Conformance to " << better->getProtocol()->getName()
|
||||
<< " is better than " << conformance->getProtocol()->getName()
|
||||
<< "\n";);
|
||||
}
|
||||
if (better != conformance &&
|
||||
!ctx.evaluator.hasActiveRequest(ResolveTypeWitnessesRequest{better})) {
|
||||
// Let's try to resolve type witnesses in the better conformance.
|
||||
evaluateOrDefault(ctx.evaluator,
|
||||
ResolveTypeWitnessesRequest{better},
|
||||
evaluator::SideEffect());
|
||||
if (better == conformance) {
|
||||
LLVM_DEBUG(llvm::dbgs() << "Conformance to " << conformance->getProtocol()->getName()
|
||||
<< " is best\n";);
|
||||
} else {
|
||||
LLVM_DEBUG(llvm::dbgs() << "Conformance to " << better->getProtocol()->getName()
|
||||
<< " is better than " << conformance->getProtocol()->getName()
|
||||
<< "\n";);
|
||||
}
|
||||
if (better != conformance &&
|
||||
!ctx.evaluator.hasActiveRequest(ResolveTypeWitnessesRequest{better})) {
|
||||
// Let's try to resolve type witnesses in the better conformance.
|
||||
evaluateOrDefault(ctx.evaluator,
|
||||
ResolveTypeWitnessesRequest{better},
|
||||
evaluator::SideEffect());
|
||||
|
||||
// Check whether the above populated the type witness of our conformance.
|
||||
auto known = conformance->TypeWitnesses.find(requirement);
|
||||
if (known != conformance->TypeWitnesses.end())
|
||||
return known->second;
|
||||
}
|
||||
// Check whether the above populated the type witness of our conformance.
|
||||
auto known = conformance->TypeWitnesses.find(requirement);
|
||||
if (known != conformance->TypeWitnesses.end())
|
||||
return known->second;
|
||||
}
|
||||
|
||||
// The type witness is still missing. Resolve all of the type witnesses
|
||||
|
||||
@@ -614,7 +614,6 @@ function(_compile_swift_files
|
||||
|
||||
if(SWIFT_ENABLE_EXPERIMENTAL_NONCOPYABLE_GENERICS)
|
||||
list(APPEND swift_flags "-enable-experimental-feature" "NoncopyableGenerics")
|
||||
list(APPEND swift_flags "-Xfrontend" "-enable-experimental-associated-type-inference")
|
||||
endif()
|
||||
|
||||
if(SWIFT_ENABLE_EXPERIMENTAL_NONESCAPABLE_TYPES)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-swift-frontend -strict-concurrency=complete -emit-sil -o /dev/null %s -verify -disable-availability-checking -enable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -strict-concurrency=complete -emit-sil -o /dev/null %s -verify -disable-availability-checking -disable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -strict-concurrency=complete -emit-sil -o /dev/null %s -verify -disable-availability-checking
|
||||
// REQUIRES: concurrency
|
||||
|
||||
@available(SwiftStdlib 5.1, *)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/Inputs/FakeDistributedActorSystems.swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -typecheck -verify -disable-availability-checking -I %t -enable-experimental-associated-type-inference 2>&1 %s
|
||||
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/Inputs/FakeDistributedActorSystems.swift
|
||||
// RUN: %target-swift-frontend -typecheck -verify -disable-availability-checking -I %t 2>&1 %s
|
||||
// REQUIRES: concurrency
|
||||
// REQUIRES: distributed
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -swift-version 4 -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -swift-version 4
|
||||
|
||||
func needsSameType<T>(_: T.Type, _: T.Type) {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct Row {}
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s -module-name protocol_extension_type_witness -enable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -module-name protocol_extension_type_witness
|
||||
// RUN: %FileCheck %s < %t.swiftinterface
|
||||
|
||||
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s -module-name protocol_extension_type_witness -disable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s -module-name protocol_extension_type_witness
|
||||
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -module-name protocol_extension_type_witness
|
||||
// RUN: %FileCheck %s < %t.swiftinterface
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-swift-frontend -emit-module -o %t/ModuleA.swiftmodule %S/Inputs/where_clause_across_module_boundaries_module.swift
|
||||
// RUN: %target-typecheck-verify-swift -I %t -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -I %t -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -I %t
|
||||
|
||||
// https://github.com/apple/swift/issues/58084
|
||||
// Associated Type Inference fails across module boundaries
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
protocol P {
|
||||
associatedtype A = Int
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
protocol Q {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// Reduced from the distributed actors implementation. This didn't type check in 5.10
|
||||
// but works now.
|
||||
|
||||
@@ -1,634 +0,0 @@
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
|
||||
protocol P1 where A == Never {
|
||||
associatedtype A
|
||||
}
|
||||
struct S1: P1 {}
|
||||
|
||||
protocol P2a {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P2b: P2a where A == Never {}
|
||||
protocol P2c: P2b {}
|
||||
struct S2a: P2b {}
|
||||
struct S2b: P2c {}
|
||||
|
||||
// Fixed type witnesses can reference dependent members.
|
||||
protocol P3a {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
}
|
||||
protocol P3b: P3a where A == [B] {}
|
||||
struct S3: P3b {
|
||||
typealias B = Never
|
||||
}
|
||||
|
||||
protocol P4a where A == [B] {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
}
|
||||
protocol P4b {}
|
||||
extension P4b {
|
||||
typealias B = Self
|
||||
}
|
||||
struct S4: P4a, P4b {}
|
||||
|
||||
// Self is a valid fixed type witness.
|
||||
protocol P5a {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P5b: P5a where A == Self {}
|
||||
struct S5<X>: P5b {} // OK, A := S5<X>
|
||||
|
||||
|
||||
protocol P6 where A == Never { // expected-error {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A : P6'}}
|
||||
// expected-note@+1 {{protocol requires nested type 'A}}
|
||||
associatedtype A: P6
|
||||
}
|
||||
struct S6: P6 {} // expected-error {{type 'S6' does not conform to protocol 'P6'}}
|
||||
|
||||
protocol P7a where A == Never {
|
||||
associatedtype A
|
||||
}
|
||||
// expected-error@+1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Bool'}}
|
||||
protocol P7b: P7a where A == Bool {}
|
||||
struct S7: P7b {}
|
||||
|
||||
protocol P8a where A == Never {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P8b where A == Bool {
|
||||
associatedtype A
|
||||
}
|
||||
do {
|
||||
struct Conformer: P8a, P8b {}
|
||||
// expected-error@-1 {{'P8b' requires the types 'Conformer.A' (aka 'Never') and 'Bool' be equivalent}}
|
||||
// expected-note@-2 {{requirement specified as 'Self.A' == 'Bool' [with Self = Conformer]}}
|
||||
// expected-error@-3 {{type 'Conformer' does not conform to protocol 'P8b'}}
|
||||
}
|
||||
|
||||
protocol P9a where A == Never {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P9b: P9a {
|
||||
associatedtype A
|
||||
}
|
||||
struct S9a: P9b {}
|
||||
// expected-error@+3 {{type 'S9b' does not conform to protocol 'P9a'}}
|
||||
// expected-error@+2 {{'P9a' requires the types 'S9b.A' (aka 'Bool') and 'Never' be equivalent}}
|
||||
// expected-note@+1 {{requirement specified as 'Self.A' == 'Never' [with Self = S9b]}}
|
||||
struct S9b: P9b {
|
||||
typealias A = Bool
|
||||
}
|
||||
struct S9c: P9b { // OK, S9c.A does not contradict Self.A == Never.
|
||||
typealias Sugar = Never
|
||||
typealias A = Sugar
|
||||
}
|
||||
|
||||
protocol P10a where A == Never {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P10b {}
|
||||
extension P10b {
|
||||
typealias A = Bool
|
||||
}
|
||||
// FIXME: 'P10 extension.A' should not be considered a viable type witness;
|
||||
// instead, the compiler should infer A := Never and synthesize S10.A.
|
||||
// expected-error@+3 {{type 'S10' does not conform to protocol 'P10a'}}
|
||||
// expected-error@+2 {{'P10a' requires the types 'S10.A' (aka 'Bool') and 'Never' be equivalent}}
|
||||
// expected-note@+1 {{requirement specified as 'Self.A' == 'Never' [with Self = S10]}}
|
||||
struct S10: P10b, P10a {}
|
||||
|
||||
protocol P11a {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P11b: P11a where A == Never {}
|
||||
protocol Q11 {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer: Q11, P11b {}
|
||||
// expected-error@-1 {{type 'Conformer' does not conform to protocol 'P11a'}}
|
||||
// expected-error@-2 {{type 'Conformer' does not conform to protocol 'Q11'}}
|
||||
}
|
||||
|
||||
protocol P12 where A == B {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
func foo(arg: A)
|
||||
}
|
||||
struct S12: P12 {
|
||||
func foo(arg: Never) {}
|
||||
}
|
||||
|
||||
protocol P13a {
|
||||
associatedtype A
|
||||
func foo(arg: A)
|
||||
}
|
||||
protocol P13b {
|
||||
associatedtype B
|
||||
}
|
||||
protocol P13c: P13a, P13b where A == B {}
|
||||
struct S13: P13c {
|
||||
func foo(arg: Never) {}
|
||||
}
|
||||
|
||||
protocol P14 {
|
||||
associatedtype A = Array<Self>
|
||||
}
|
||||
do {
|
||||
struct Outer<Element> {
|
||||
struct Conformer: P14 {}
|
||||
}
|
||||
}
|
||||
|
||||
protocol P15a {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B = Never // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
protocol P15b: P15a where A == B {}
|
||||
do {
|
||||
struct Conformer: P15b {}
|
||||
// expected-error@-1 {{type 'Conformer' does not conform to protocol 'P15a'}}
|
||||
}
|
||||
|
||||
protocol P16a where A == B {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B = Never // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
protocol P16b: P16a {}
|
||||
do {
|
||||
struct Conformer: P16b {}
|
||||
// expected-error@-1 {{type 'Conformer' does not conform to protocol 'P16a'}}
|
||||
}
|
||||
|
||||
protocol P17a where A == Never {
|
||||
associatedtype A = B // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
protocol P17b {
|
||||
associatedtype A = B // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
protocol P17c where A == Never {
|
||||
associatedtype A
|
||||
associatedtype B = A
|
||||
}
|
||||
protocol P17d {
|
||||
associatedtype A = B
|
||||
associatedtype B = Int
|
||||
}
|
||||
do {
|
||||
struct Conformer1: P17a {} // expected-error {{type 'Conformer1' does not conform to protocol 'P17a'}}
|
||||
struct Conformer2<A>: P17b {} // expected-error {{type 'Conformer2<A>' does not conform to protocol 'P17b'}}
|
||||
struct Conformer3: P17c {}
|
||||
struct Conformer4<A>: P17d {}
|
||||
}
|
||||
|
||||
protocol P18 {
|
||||
associatedtype A = B
|
||||
associatedtype B = C
|
||||
associatedtype C = (D) -> D
|
||||
associatedtype D
|
||||
}
|
||||
do {
|
||||
struct Conformer<D>: P18 {}
|
||||
}
|
||||
|
||||
protocol P19 where Self == A {
|
||||
associatedtype A
|
||||
associatedtype B = (A, A)
|
||||
}
|
||||
do {
|
||||
struct Conformer: P19 {}
|
||||
}
|
||||
|
||||
protocol P20 where A == B.Element, B == B.SubSequence, C.Element == B.Element {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B: Collection
|
||||
associatedtype C: Collection = Array<Character> // expected-note {{protocol requires nested type 'C'; add nested type 'C' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer: P20 { // expected-error {{type 'Conformer' does not conform to protocol 'P20'}}
|
||||
typealias B = Substring
|
||||
}
|
||||
}
|
||||
|
||||
protocol P21 where A == B {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B = C // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
associatedtype C // expected-note {{protocol requires nested type 'C'; add nested type 'C' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer<C>: P21 {} // expected-error {{type 'Conformer<C>' does not conform to protocol 'P21'}}
|
||||
}
|
||||
|
||||
protocol P22 where A == B, C == D {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
associatedtype C = B
|
||||
associatedtype D
|
||||
}
|
||||
do {
|
||||
struct Conformer<A>: P22 {}
|
||||
}
|
||||
|
||||
protocol P23 {
|
||||
associatedtype A: P23 = B.A // expected-note 2 {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B: P23 = A.B // expected-note 2 {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer: P23 {} // expected-error {{type 'Conformer' does not conform to protocol 'P23'}}
|
||||
struct ConformerGeneric<T>: P23 {} // expected-error {{type 'ConformerGeneric<T>' does not conform to protocol 'P23'}}
|
||||
}
|
||||
|
||||
protocol P24 where A == B.A {
|
||||
associatedtype A: P24 // expected-note 2 {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B: P24 = A.B // expected-note 2 {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer: P24 {} // expected-error {{type 'Conformer' does not conform to protocol 'P24'}}
|
||||
struct ConformerGeneric<T>: P24 {} // expected-error {{type 'ConformerGeneric<T>' does not conform to protocol 'P24'}}
|
||||
}
|
||||
|
||||
protocol P25a_1 where A == Int, B == C.Element {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
associatedtype C: Sequence
|
||||
}
|
||||
protocol P25a_2 where A == C.Element, B == Int {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
associatedtype C: Sequence
|
||||
}
|
||||
protocol P25b where A == B {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
}
|
||||
protocol P25c_1: P25a_1, P25b {}
|
||||
protocol P25c_2: P25a_2, P25b {}
|
||||
do {
|
||||
struct Conformer1<C: Sequence>: P25c_1 where C.Element == Int {}
|
||||
struct Conformer2<C: Sequence>: P25c_2 where C.Element == Int {}
|
||||
}
|
||||
|
||||
protocol P26 where C == B, F == G {
|
||||
associatedtype A = Int // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B = A // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
associatedtype C // expected-note {{protocol requires nested type 'C'; add nested type 'C' for conformance}}
|
||||
|
||||
associatedtype D // expected-note {{protocol requires nested type 'D'; add nested type 'D' for conformance}}
|
||||
associatedtype E = D // expected-note {{protocol requires nested type 'E'; add nested type 'E' for conformance}}
|
||||
|
||||
associatedtype F // expected-note {{protocol requires nested type 'F'; add nested type 'F' for conformance}}
|
||||
associatedtype G = [B] // expected-note {{protocol requires nested type 'G'; add nested type 'G' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer<D>: P26 {} // expected-error {{type 'Conformer<D>' does not conform to protocol 'P26'}}
|
||||
}
|
||||
|
||||
protocol P27a where A == Int {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P27b where A == B.Element {
|
||||
associatedtype A
|
||||
associatedtype B: Sequence
|
||||
}
|
||||
protocol P27c_1: P27a, P27b {}
|
||||
protocol P27c_2: P27b, P27a {}
|
||||
do {
|
||||
struct Conformer1<B: Sequence>: P27c_1 where B.Element == Int {}
|
||||
struct Conformer2<B: Sequence>: P27c_2 where B.Element == Int {}
|
||||
}
|
||||
|
||||
protocol P28a where A == Int {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P28b where A == Bool {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P28c where A == Never {
|
||||
associatedtype A
|
||||
}
|
||||
protocol Q28a: P28a, P28b {}
|
||||
// expected-error@-1 {{no type for 'Self.A' can satisfy both 'Self.A == Bool' and 'Self.A == Int'}}
|
||||
protocol Q28b: P28a, P28b, P28c {}
|
||||
// expected-error@-1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Bool'}}
|
||||
// expected-error@-2 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Int'}}
|
||||
// expected-error@-3 {{no type for 'Self.A' can satisfy both 'Self.A == Bool' and 'Self.A == Int'}}
|
||||
do {
|
||||
struct Conformer1: Q28a {}
|
||||
// expected-error@-1 {{'P28b' requires the types 'Conformer1.A' (aka 'Int') and 'Bool' be equivalent}}
|
||||
// expected-note@-2 {{requirement specified as 'Self.A' == 'Bool' [with Self = Conformer1]}}
|
||||
// expected-error@-3 {{type 'Conformer1' does not conform to protocol 'P28b'}}
|
||||
|
||||
struct Conformer2: Q28b {}
|
||||
// expected-error@-1 {{'P28c' requires the types 'Conformer2.A' (aka 'Int') and 'Never' be equivalent}}
|
||||
// expected-error@-2 {{'P28b' requires the types 'Conformer2.A' (aka 'Int') and 'Bool' be equivalent}}
|
||||
// expected-note@-3 {{requirement specified as 'Self.A' == 'Never' [with Self = Conformer2]}}
|
||||
// expected-note@-4 {{requirement specified as 'Self.A' == 'Bool' [with Self = Conformer2]}}
|
||||
// expected-error@-5 {{type 'Conformer2' does not conform to protocol 'P28b'}}
|
||||
// expected-error@-6 {{type 'Conformer2' does not conform to protocol 'P28c'}}
|
||||
}
|
||||
|
||||
protocol P29a where A == Int {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
}
|
||||
protocol P29b where B == Never {
|
||||
associatedtype B
|
||||
}
|
||||
protocol P29c where A == B {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
protocol Q29a: P29a, P29b, P29c {}
|
||||
// expected-error@-1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Int'}}
|
||||
protocol Q29b: P29c, P29a, P29b {}
|
||||
// expected-error@-1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Int'}}
|
||||
do {
|
||||
struct Conformer1: Q29a {}
|
||||
// expected-error@-1 {{'P29b' requires the types 'Conformer1.B' (aka 'Int') and 'Never' be equivalent}}
|
||||
// expected-note@-2 {{requirement specified as 'Self.B' == 'Never' [with Self = Conformer1]}}
|
||||
// expected-error@-3 {{type 'Conformer1' does not conform to protocol 'P29b'}}
|
||||
|
||||
|
||||
struct Conformer2: Q29b {}
|
||||
// expected-error@-1 {{type 'Conformer2' does not conform to protocol 'P29a'}}
|
||||
// expected-error@-2 {{type 'Conformer2' does not conform to protocol 'P29b'}}
|
||||
// expected-error@-3 {{type 'Conformer2' does not conform to protocol 'P29c'}}
|
||||
}
|
||||
|
||||
protocol P30a where A == Int {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P30b where A == Never {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P30c where A == B {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
protocol Q30: P30c, P30a, P30b {}
|
||||
// expected-error@-1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Int'}}
|
||||
do {
|
||||
struct Conformer: Q30 {}
|
||||
// expected-error@-1 {{type 'Conformer' does not conform to protocol 'P30a'}}
|
||||
// expected-error@-2 {{type 'Conformer' does not conform to protocol 'P30b'}}
|
||||
// expected-error@-3 {{type 'Conformer' does not conform to protocol 'P30c'}}
|
||||
}
|
||||
|
||||
protocol P31a where B == Int {
|
||||
associatedtype B
|
||||
}
|
||||
protocol P31b where B == Never {
|
||||
associatedtype B
|
||||
}
|
||||
protocol P31c where B == A {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
protocol Q31: P31c, P31a, P31b {}
|
||||
// expected-error@-1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Int'}}
|
||||
do {
|
||||
struct Conformer: Q31 {}
|
||||
// expected-error@-1 {{type 'Conformer' does not conform to protocol 'P31a'}}
|
||||
// expected-error@-2 {{type 'Conformer' does not conform to protocol 'P31b'}}
|
||||
// expected-error@-3 {{type 'Conformer' does not conform to protocol 'P31c'}}
|
||||
}
|
||||
|
||||
protocol P32a where A == Int {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P32b where A == Bool {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P32c where B == Void {
|
||||
associatedtype B
|
||||
}
|
||||
protocol P32d where B == Never {
|
||||
associatedtype B
|
||||
}
|
||||
protocol P32e where A == B {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
protocol Q32: P32e, P32a, P32b, P32c, P32d {}
|
||||
// expected-error@-1 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == ()'}}
|
||||
// expected-error@-2 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Bool'}}
|
||||
// expected-error@-3 {{no type for 'Self.A' can satisfy both 'Self.A == Never' and 'Self.A == Int'}}
|
||||
// expected-error@-4 {{no type for 'Self.A' can satisfy both 'Self.A == Bool' and 'Self.A == Int'}}
|
||||
// expected-error@-5 {{no type for 'Self.A' can satisfy both 'Self.A == ()' and 'Self.A == Int'}}
|
||||
// expected-error@-6 {{no type for 'Self.A' can satisfy both 'Self.A == ()' and 'Self.A == Bool'}}
|
||||
do {
|
||||
struct Conformer: Q32 {}
|
||||
// expected-error@-1 {{type 'Conformer' does not conform to protocol 'P32a'}}
|
||||
// expected-error@-2 {{type 'Conformer' does not conform to protocol 'P32b'}}
|
||||
// expected-error@-3 {{type 'Conformer' does not conform to protocol 'P32c'}}
|
||||
// expected-error@-4 {{type 'Conformer' does not conform to protocol 'P32d'}}
|
||||
// expected-error@-5 {{type 'Conformer' does not conform to protocol 'P32e'}}
|
||||
}
|
||||
|
||||
protocol P33a where A == Int {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P33b where A == Int {
|
||||
associatedtype A
|
||||
}
|
||||
protocol Q33: P33a, P33b {}
|
||||
do {
|
||||
struct Conformer: Q33 {}
|
||||
}
|
||||
|
||||
protocol P34a {
|
||||
associatedtype A = Void
|
||||
}
|
||||
protocol P34b {
|
||||
associatedtype A = Never
|
||||
}
|
||||
protocol Q34a: P34a, P34b {}
|
||||
protocol Q34b: P34b, P34a {}
|
||||
protocol Q34c: P34a, P34b {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer1: Q34a {}
|
||||
struct Conformer2: Q34b {}
|
||||
struct Conformer3: Q34c {} // expected-error {{type 'Conformer3' does not conform to protocol 'Q34c'}}
|
||||
}
|
||||
|
||||
protocol P35 {
|
||||
associatedtype A
|
||||
associatedtype B = Array<C>
|
||||
associatedtype C = Array<D>
|
||||
associatedtype D = Array<A>
|
||||
}
|
||||
do {
|
||||
struct Conformer: P35 {
|
||||
typealias A = Never
|
||||
}
|
||||
struct ConformerGeneric<A>: P35 {}
|
||||
}
|
||||
|
||||
struct G36<S: P36> {}
|
||||
protocol P36 {
|
||||
// FIXME: Don't create and expose malformed types like 'G36<Never>' -- check
|
||||
// non-dependent type witnesses first.
|
||||
// expected-note@+1 {{default type 'G36<Never>' for associated type 'A' (from protocol 'P36') does not conform to 'P36'}}
|
||||
associatedtype A: P36 = G36<B>
|
||||
associatedtype B: P36 = Never
|
||||
}
|
||||
do {
|
||||
struct Conformer: P36 {} // expected-error {{type 'Conformer' does not conform to protocol 'P36'}}
|
||||
}
|
||||
|
||||
protocol P37a {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P37b {
|
||||
associatedtype B : P37a
|
||||
associatedtype C where C == B.A // expected-note {{protocol requires nested type 'C'; add nested type 'C' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer1<C>: P37b {
|
||||
struct Inner: P37a { typealias A = C }
|
||||
|
||||
typealias B = Inner
|
||||
}
|
||||
|
||||
struct Conformer2<T>: P37b { // expected-error {{type 'Conformer2<T>' does not conform to protocol 'P37b'}}
|
||||
struct Inner: P37a { typealias A = T }
|
||||
|
||||
typealias B = Inner
|
||||
}
|
||||
}
|
||||
|
||||
protocol P38a {
|
||||
associatedtype A
|
||||
}
|
||||
protocol P38b {
|
||||
associatedtype B
|
||||
}
|
||||
protocol P38c: P38a, P38b where A == B {}
|
||||
do {
|
||||
struct Conformer<T>: P38c {
|
||||
typealias A = Self
|
||||
}
|
||||
}
|
||||
|
||||
protocol P39 {
|
||||
associatedtype A: P39
|
||||
associatedtype B = A.C
|
||||
associatedtype C = Never
|
||||
}
|
||||
do {
|
||||
struct Conformer: P39 {
|
||||
typealias A = Self
|
||||
}
|
||||
}
|
||||
|
||||
protocol P40a {
|
||||
associatedtype A
|
||||
associatedtype B = (A, A)
|
||||
}
|
||||
protocol P40b: P40a {
|
||||
override associatedtype A = Int
|
||||
}
|
||||
protocol P40c: P40b {
|
||||
override associatedtype A
|
||||
override associatedtype B
|
||||
}
|
||||
do {
|
||||
struct Conformer: P40c {}
|
||||
}
|
||||
|
||||
protocol P41 {
|
||||
associatedtype A where A == B.A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B: P41 = Self // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer: P41 {} // expected-error{{type 'Conformer' does not conform to protocol 'P41'}}
|
||||
}
|
||||
|
||||
protocol P42a {
|
||||
associatedtype B: P42b
|
||||
}
|
||||
protocol P42b: P42a {
|
||||
associatedtype A = B.A
|
||||
}
|
||||
do {
|
||||
struct Conformer<B: P42b>: P42b {}
|
||||
}
|
||||
|
||||
protocol P43a {
|
||||
associatedtype A: P43a
|
||||
associatedtype B
|
||||
}
|
||||
protocol P43b: P43a {
|
||||
associatedtype C where C == A.B // expected-note {{protocol requires nested type 'C'; add nested type 'C' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer<B: P43a>: P43b { // expected-error {{type 'Conformer<B>' does not conform to protocol 'P43b'}}
|
||||
typealias A = Conformer<B.A>
|
||||
}
|
||||
}
|
||||
|
||||
protocol P44 {
|
||||
associatedtype A: P44
|
||||
associatedtype B // expected-note 2{{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
associatedtype C where C == A.B // expected-note 3{{protocol requires nested type 'C'; add nested type 'C' for conformance}}
|
||||
}
|
||||
do {
|
||||
struct Conformer1<T: P44>: P44 { // expected-error {{type 'Conformer1<T>' does not conform to protocol 'P44'}}
|
||||
typealias B = T.A
|
||||
typealias A = Conformer1<T.A>
|
||||
}
|
||||
|
||||
struct Conformer2<B: P44>: P44 { // expected-error {{type 'Conformer2<B>' does not conform to protocol 'P44'}}
|
||||
typealias A = Conformer2<B.A>
|
||||
}
|
||||
|
||||
struct Conformer3<B>: P44 { // expected-error {{type 'Conformer3<B>' does not conform to protocol 'P44'}}
|
||||
typealias A = Conformer3<Int>
|
||||
}
|
||||
}
|
||||
|
||||
protocol P45 {
|
||||
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
|
||||
associatedtype B: P45 = Conformer45<D> // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
associatedtype C where C == B.A // expected-note {{protocol requires nested type 'C'; add nested type 'C' for conformance}}
|
||||
associatedtype D = Never // expected-note {{protocol requires nested type 'D'; add nested type 'D' for conformance}}
|
||||
}
|
||||
struct Conformer45<A>: P45 {} // expected-error {{type 'Conformer45<A>' does not conform to protocol 'P45'}}
|
||||
|
||||
protocol P46 {
|
||||
associatedtype A: P46
|
||||
associatedtype B // expected-note {{protocol requires nested type 'B'; add nested type 'B' for conformance}}
|
||||
associatedtype C where C == A.B // expected-note {{protocol requires nested type 'C'; add nested type 'C' for conformance}}
|
||||
|
||||
func method(_: B)
|
||||
}
|
||||
do {
|
||||
struct Conformer<T: P46>: P46 { // expected-error {{type 'Conformer<T>' does not conform to protocol 'P46'}}
|
||||
typealias A = Conformer<T.A>
|
||||
|
||||
func method(_: T) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protocol P47 {
|
||||
associatedtype A
|
||||
}
|
||||
do {
|
||||
struct Outer<A> {
|
||||
struct Inner: P47 {}
|
||||
}
|
||||
}
|
||||
|
||||
protocol P48a { associatedtype A = Int }
|
||||
protocol P48b { associatedtype B }
|
||||
protocol P48c: P48a, P48b where A == B {}
|
||||
do {
|
||||
struct Conformer: P48c {}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-swift-frontend -typecheck -enable-experimental-associated-type-inference -dump-type-witness-systems %s 2>&1 | %FileCheck %s
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
// RUN: not %target-swift-frontend -typecheck -dump-type-witness-systems %s 2>&1 | %FileCheck %s
|
||||
|
||||
protocol P1 where A == Never {
|
||||
associatedtype A
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// REQUIRES: objc_interop
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: not %target-swift-frontend -typecheck %s -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
protocol P {
|
||||
associatedtype A
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
func assertEqualTypes<T>(_: T.Type, _: T.Type) {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// We would fail here when Indices was explicitly specified, as in X2.
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
protocol IP {
|
||||
associatedtype E
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct FooIterator<T: Sequence>: IteratorProtocol {
|
||||
typealias Element = T.Element
|
||||
|
||||
@@ -1,32 +1,17 @@
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA1
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA2
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA3
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA4
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA5
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA6
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA7
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA8
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA9
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA10
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA11
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA12
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA13
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA14
|
||||
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA1
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA2
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA3
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA4
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA5
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA6
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA7
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA8
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA9
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA10
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA11
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA12
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA13
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA14
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA1
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA2
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA3
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA4
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA5
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA6
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA7
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA8
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA9
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA10
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA11
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA12
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA13
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA14
|
||||
|
||||
#if A1
|
||||
|
||||
|
||||
@@ -1,32 +1,17 @@
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA1
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA2
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA3
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA4
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA5
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA6
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA7
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA8
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA9
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA10
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA11
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA12
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA13
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA14
|
||||
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA1
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA2
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA3
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA4
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA5
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA6
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA7
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA8
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA9
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA10
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA11
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA12
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA13
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA14
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA1
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA2
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA3
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA4
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA5
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA6
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA7
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA8
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA9
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA10
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA11
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA12
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA13
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -DA14
|
||||
|
||||
#if A1
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// A := G<A> is unsatisfiable and not a tautology!
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
protocol P {
|
||||
associatedtype A: Q = Int
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// We can't infer anything from 'Self', but we must still validate the
|
||||
// binding.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
// An inner generic parameter of the protocol requirement should not
|
||||
// match against a concrete type in the witness.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct G<T> {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public protocol FakeCopyable {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public protocol LazySequenceProtocol: Sequence {
|
||||
associatedtype Elements: Sequence = Self where Elements.Element == Element
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public struct DefaultA {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public struct S: P {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public protocol P1 {
|
||||
associatedtype A
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public struct S<Element: Hashable> {
|
||||
public typealias A = [Element: Int]
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference -DNEW
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference -DOLD
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct S<Element> {}
|
||||
|
||||
@@ -27,10 +26,4 @@ extension S: Collection {
|
||||
}
|
||||
}
|
||||
|
||||
// The old behavior didn't make much sense.
|
||||
|
||||
#if NEW
|
||||
let x: S<Int>.Type = S<Int>.Iterator.self
|
||||
#elseif OLD
|
||||
let x: IndexingIterator<S<Int>>.Type = S<Int>.Iterator.self
|
||||
#endif
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct G<T> {
|
||||
class Nested {}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
protocol P1 {
|
||||
associatedtype A
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public protocol P1 {
|
||||
associatedtype A = Void
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference -disable-availability-checking
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference -disable-availability-checking
|
||||
// RUN: %target-typecheck-verify-swift -disable-availability-checking
|
||||
|
||||
public protocol P<A> {
|
||||
associatedtype A
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct CustomCollection<T>: RandomAccessCollection {
|
||||
struct CustomIndices: RandomAccessCollection {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public protocol P {
|
||||
associatedtype A = Never
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
func f<T: Sequence>(_: T) -> T.Element {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
protocol Task1: AnyObject {
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -emit-silgen %s
|
||||
|
||||
public struct G<A, B, C>: P {
|
||||
public typealias D = G<A, C, B>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct G1<T> {}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
extension LazySequenceProtocol {
|
||||
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
public typealias A = UInt32
|
||||
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
// RUN: not %target-swift-frontend -emit-sil -module-name main -primary-file %s %S/Inputs/protocol-conformance-issue-53408-other.swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main %s -primary-file %S/Inputs/protocol-conformance-issue-53408-other.swift -disable-experimental-associated-type-inference
|
||||
// RUN: not %target-swift-frontend -emit-sil -module-name main %s %S/Inputs/protocol-conformance-issue-53408-other.swift -disable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main %S/Inputs/protocol-conformance-issue-53408-other.swift %s -disable-experimental-associated-type-inference
|
||||
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main -primary-file %s %S/Inputs/protocol-conformance-issue-53408-other.swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main %s -primary-file %S/Inputs/protocol-conformance-issue-53408-other.swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main %s %S/Inputs/protocol-conformance-issue-53408-other.swift -enable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main %S/Inputs/protocol-conformance-issue-53408-other.swift %s -enable-experimental-associated-type-inference
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main -primary-file %s %S/Inputs/protocol-conformance-issue-53408-other.swift
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main %s -primary-file %S/Inputs/protocol-conformance-issue-53408-other.swift
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main %s %S/Inputs/protocol-conformance-issue-53408-other.swift
|
||||
// RUN: %target-swift-frontend -emit-sil -module-name main %S/Inputs/protocol-conformance-issue-53408-other.swift %s
|
||||
|
||||
// https://github.com/apple/swift/issues/53408
|
||||
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
// RUN: %target-swift-frontend -disable-experimental-associated-type-inference -verify -emit-ir %s
|
||||
|
||||
// Works with experimental associated type inference.
|
||||
// RUN: %target-swift-frontend -enable-experimental-associated-type-inference -emit-ir %s
|
||||
// RUN: %target-swift-frontend -emit-ir %s
|
||||
|
||||
// https://github.com/apple/swift/issues/53793
|
||||
|
||||
protocol P1 {
|
||||
associatedtype X
|
||||
// expected-note@-1 {{protocol requires nested type 'X'; add nested type 'X' for conformance}}
|
||||
associatedtype A: P2 where A.X == X
|
||||
}
|
||||
|
||||
@@ -25,6 +21,5 @@ extension S {
|
||||
|
||||
|
||||
extension S: P1 {}
|
||||
// expected-error@-1 {{type 'S' does not conform to protocol 'P1'}}
|
||||
|
||||
print(S.X.self)
|
||||
let x: Int.Type = S.X.self
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// RUN: not %target-swift-frontend -typecheck %s -enable-experimental-associated-type-inference
|
||||
// RUN: not %target-swift-frontend -typecheck %s
|
||||
|
||||
// This code is invalid, but we shouldn't crash.
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
|
||||
|
||||
// FIXME: Figure this out before removing -disable-experimental-associated-type-inference
|
||||
// RUN: not %target-swift-frontend %s -emit-ir -disable-experimental-associated-type-inference
|
||||
// RUN: not %target-swift-frontend %s -emit-ir
|
||||
class a:A
|
||||
protocol A:a{typealias a:=a
|
||||
|
||||
Reference in New Issue
Block a user