Merge pull request #71780 from slavapestov/remove-non-experimental-assoc-type-inference

Remove old associated type inference implementation
This commit is contained in:
Slava Pestov
2024-03-07 22:14:06 -05:00
committed by GitHub
57 changed files with 156 additions and 1505 deletions

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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">;

View File

@@ -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))
}

View File

@@ -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.

View File

@@ -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))

View File

@@ -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.

View File

@@ -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

View File

@@ -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)

View File

@@ -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, *)

View File

@@ -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

View File

@@ -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) {}

View File

@@ -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 {}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {}

View File

@@ -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.

View File

@@ -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 {}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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) {}

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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!

View File

@@ -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

View File

@@ -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.

View File

@@ -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.

View File

@@ -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> {}

View File

@@ -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 {}

View File

@@ -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

View File

@@ -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 {}

View File

@@ -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 {}

View File

@@ -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

View File

@@ -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]

View File

@@ -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

View File

@@ -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 {}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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 {}

View File

@@ -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 {
}

View File

@@ -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>

View File

@@ -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> {}

View File

@@ -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, *)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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