mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
GenericEnvironment: Replace 'substDependentTypesWithErrorTypes' with an assertion
This commit is contained in:
@@ -317,9 +317,6 @@ public:
|
|||||||
LookupConformanceFn conformances,
|
LookupConformanceFn conformances,
|
||||||
SubstOptions options=None) const;
|
SubstOptions options=None) const;
|
||||||
|
|
||||||
/// Replace references to substitutable types with error types.
|
|
||||||
Type substDependentTypesWithErrorTypes() const;
|
|
||||||
|
|
||||||
bool isPrivateStdlibType(bool treatNonBuiltinProtocolsAsPublic = true) const;
|
bool isPrivateStdlibType(bool treatNonBuiltinProtocolsAsPublic = true) const;
|
||||||
|
|
||||||
SWIFT_DEBUG_DUMP;
|
SWIFT_DEBUG_DUMP;
|
||||||
|
|||||||
@@ -87,9 +87,12 @@ Optional<Type> GenericEnvironment::getMappingIfPresent(
|
|||||||
Type GenericEnvironment::mapTypeIntoContext(GenericEnvironment *env,
|
Type GenericEnvironment::mapTypeIntoContext(GenericEnvironment *env,
|
||||||
Type type) {
|
Type type) {
|
||||||
assert(!type->hasArchetype() && "already have a contextual type");
|
assert(!type->hasArchetype() && "already have a contextual type");
|
||||||
|
assert((env || !type->hasTypeParameter()) &&
|
||||||
|
"no generic environment provided for type with type parameters");
|
||||||
|
|
||||||
if (!env)
|
if (!env) {
|
||||||
return type.substDependentTypesWithErrorTypes();
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
return env->mapTypeIntoContext(type);
|
return env->mapTypeIntoContext(type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4151,13 +4151,6 @@ Type Type::subst(TypeSubstitutionFn substitutions,
|
|||||||
return substType(*this, substitutions, conformances, options);
|
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() {
|
const DependentMemberType *TypeBase::findUnresolvedDependentMemberType() {
|
||||||
if (!hasTypeParameter()) return nullptr;
|
if (!hasTypeParameter()) return nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -1011,7 +1011,7 @@ ValueDecl *DerivedConformance::deriveHashable(ValueDecl *requirement) {
|
|||||||
// Hashable because DerivedConformance::canDeriveHashable returns true
|
// Hashable because DerivedConformance::canDeriveHashable returns true
|
||||||
// even if the conformance can't be derived. See the note there for
|
// even if the conformance can't be derived. See the note there for
|
||||||
// details.
|
// details.
|
||||||
auto *dc = ConformanceDecl->getDeclContext();
|
auto *dc = cast<DeclContext>(ConformanceDecl);
|
||||||
tryDiagnoseFailedHashableDerivation(dc, Nominal);
|
tryDiagnoseFailedHashableDerivation(dc, Nominal);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1199,7 +1199,23 @@ AssociatedTypeDecl *AssociatedTypeInference::completeSolution(
|
|||||||
// If the substitution produced an error, we're done.
|
// If the substitution produced an error, we're done.
|
||||||
if (type->hasError())
|
if (type->hasError())
|
||||||
return witness.getAssocType();
|
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);
|
type = dc->mapTypeIntoContext(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,12 @@ func genericNotHashable() {
|
|||||||
GenericNotHashable<String>.A("a").hash(into: &hasher) // expected-error {{value of type 'GenericNotHashable<String>' has no member 'hash'}}
|
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.
|
// An enum with no cases should also derive conformance.
|
||||||
enum NoCases: Hashable {}
|
enum NoCases: Hashable {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user