GenericEnvironment: Replace 'substDependentTypesWithErrorTypes' with an assertion

This commit is contained in:
Anthony Latsis
2021-10-25 05:11:34 +03:00
parent 127f2f5cd0
commit 1cf9622f32
6 changed files with 28 additions and 13 deletions

View File

@@ -317,9 +317,6 @@ public:
LookupConformanceFn conformances,
SubstOptions options=None) const;
/// Replace references to substitutable types with error types.
Type substDependentTypesWithErrorTypes() const;
bool isPrivateStdlibType(bool treatNonBuiltinProtocolsAsPublic = true) const;
SWIFT_DEBUG_DUMP;

View File

@@ -87,9 +87,12 @@ Optional<Type> GenericEnvironment::getMappingIfPresent(
Type GenericEnvironment::mapTypeIntoContext(GenericEnvironment *env,
Type type) {
assert(!type->hasArchetype() && "already have a contextual type");
assert((env || !type->hasTypeParameter()) &&
"no generic environment provided for type with type parameters");
if (!env)
return type.substDependentTypesWithErrorTypes();
if (!env) {
return type;
}
return env->mapTypeIntoContext(type);
}

View File

@@ -4151,13 +4151,6 @@ Type Type::subst(TypeSubstitutionFn substitutions,
return substType(*this, substitutions, conformances, options);
}
Type Type::substDependentTypesWithErrorTypes() const {
return substType(*this,
[](SubstitutableType *t) -> Type { return Type(); },
MakeAbstractConformanceForGenericType(),
SubstFlags::AllowLoweredTypes);
}
const DependentMemberType *TypeBase::findUnresolvedDependentMemberType() {
if (!hasTypeParameter()) return nullptr;

View File

@@ -1011,7 +1011,7 @@ ValueDecl *DerivedConformance::deriveHashable(ValueDecl *requirement) {
// Hashable because DerivedConformance::canDeriveHashable returns true
// even if the conformance can't be derived. See the note there for
// details.
auto *dc = ConformanceDecl->getDeclContext();
auto *dc = cast<DeclContext>(ConformanceDecl);
tryDiagnoseFailedHashableDerivation(dc, Nominal);
return nullptr;
}

View File

@@ -1199,7 +1199,23 @@ AssociatedTypeDecl *AssociatedTypeInference::completeSolution(
// If the substitution produced an error, we're done.
if (type->hasError())
return witness.getAssocType();
// FIXME: If we still have a type parameter and it isn't a generic
// parameter of the conforming nominal, it's either a cycle or a
// solution that is beyond the current algorithm, i.e.
//
// protocol P {
// associatedtype A = B
// associatedtype B = C
// associatedtype C = Int
// }
// struct Conformer: P {}
if (type->hasTypeParameter() &&
!adoptee->getAnyNominal()->isGeneric()) {
return witness.getAssocType();
}
}
type = dc->mapTypeIntoContext(type);
}

View File

@@ -173,6 +173,12 @@ func genericNotHashable() {
GenericNotHashable<String>.A("a").hash(into: &hasher) // expected-error {{value of type 'GenericNotHashable<String>' has no member 'hash'}}
}
enum GenericNotHashable2<T: Equatable, U: Hashable>: Hashable {
// expected-error@-1 {{type 'GenericNotHashable2' does not conform to protocol 'Hashable'}}
case A(U, T) // expected-note {{associated value type 'T' does not conform to protocol 'Hashable', preventing synthesized conformance of 'GenericNotHashable2<T, U>' to 'Hashable'}}
case B
}
// An enum with no cases should also derive conformance.
enum NoCases: Hashable {}