Wrap _checkGenericRequirements instead for _instantiateCheckedGenericMetadata

This commit is contained in:
Alejandro Alonso
2023-10-09 15:02:29 -07:00
parent 90506909d3
commit 3ddec4fd83
4 changed files with 137 additions and 23 deletions

View File

@@ -1344,24 +1344,37 @@ static llvm::Optional<TypeLookupError>
checkGenericRequirement(const GenericRequirementDescriptor &req,
llvm::SmallVectorImpl<const void *> &extraArguments,
SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable) {
SubstDependentWitnessTableFn substWitnessTable,
bool allowsUnresolvedSubject) {
assert(!req.getFlags().isPackRequirement());
// Make sure we understand the requirement we're dealing with.
if (!req.hasKnownKind())
return TypeLookupError("unknown kind");
const Metadata *subjectType = nullptr;
// Resolve the subject generic parameter.
auto result = swift_getTypeByMangledName(
MetadataState::Abstract, req.getParam(), extraArguments.data(),
substGenericParam, substWitnessTable);
if (result.getError())
if (!allowsUnresolvedSubject && result.isError()) {
return *result.getError();
const Metadata *subjectType = result.getType().getMetadata();
}
if (!result.isError()) {
subjectType = result.getType().getMetadata();
}
// Check the requirement.
switch (req.getKind()) {
case GenericRequirementKind::Protocol: {
// Protocol requirements _require_ a subject type.
if (result.isError()) {
return *result.getError();
}
const WitnessTable *witnessTable = nullptr;
if (!_conformsToProtocol(nullptr, subjectType, req.getProtocol(),
&witnessTable)) {
@@ -1382,16 +1395,37 @@ checkGenericRequirement(const GenericRequirementDescriptor &req,
}
case GenericRequirementKind::SameType: {
// Same type requirements don't require a valid subject.
const Metadata *sameType = nullptr;
// Demangle the second type under the given substitutions.
auto result = swift_getTypeByMangledName(
MetadataState::Abstract, req.getMangledTypeName(),
extraArguments.data(), substGenericParam, substWitnessTable);
if (result.getError())
if (!allowsUnresolvedSubject && result.isError()) {
return *result.getError();
auto otherType = result.getType().getMetadata();
}
if (!result.isError()) {
sameType = result.getType().getMetadata();
}
// If we don't have one of either the subject type or the same type and we
// have the other, then return this as a success. This assumes the given
// extra arguments have provided only the required key arguments in which
// case some same type constraints may concretize some generic arguments
// making them non-key.
//
// Note: We don't need to check for allowsUnresolvedSubject here because
// these can only be null in the case where we do allow it.
if ((!subjectType && sameType) || (subjectType && !sameType)) {
return llvm::None;
}
// Check that the types are equivalent.
if (subjectType != otherType) {
if (subjectType != sameType) {
return TYPE_LOOKUP_ERROR_FMT(
"subject type %.*s does not match %.*s", (int)req.getParam().size(),
req.getParam().data(), (int)req.getMangledTypeName().size(),
@@ -1402,10 +1436,20 @@ checkGenericRequirement(const GenericRequirementDescriptor &req,
}
case GenericRequirementKind::Layout: {
// Layout requirements _require_ a subject type.
if (result.isError()) {
return *result.getError();
}
return satisfiesLayoutConstraint(req, subjectType);
}
case GenericRequirementKind::BaseClass: {
// Base class requirements _require_ a subject type.
if (result.isError()) {
return *result.getError();
}
// Demangle the base type under the given substitutions.
auto result = swift_getTypeByMangledName(
MetadataState::Abstract, req.getMangledTypeName(),
@@ -1594,7 +1638,8 @@ llvm::Optional<TypeLookupError> swift::_checkGenericRequirements(
llvm::ArrayRef<GenericRequirementDescriptor> requirements,
llvm::SmallVectorImpl<const void *> &extraArguments,
SubstGenericParameterFn substGenericParam,
SubstDependentWitnessTableFn substWitnessTable) {
SubstDependentWitnessTableFn substWitnessTable,
bool allowsUnresolvedSubject) {
for (const auto &req : requirements) {
if (req.getFlags().isPackRequirement()) {
auto error = checkGenericPackRequirement(req, extraArguments,
@@ -1605,7 +1650,8 @@ llvm::Optional<TypeLookupError> swift::_checkGenericRequirements(
} else {
auto error = checkGenericRequirement(req, extraArguments,
substGenericParam,
substWitnessTable);
substWitnessTable,
allowsUnresolvedSubject);
if (error)
return error;
}