Make LookupConformanceFn callbacks return Optional<ProtocolConformanceRef>.

NFC yet, but this is a step toward centralizing error handling policy for failed conformance lookups instead of leaving it ad-hoc.
This commit is contained in:
Joe Groff
2016-12-14 18:04:35 -08:00
parent 55bdf5954c
commit ccfabd1118
5 changed files with 38 additions and 37 deletions

View File

@@ -129,9 +129,10 @@ public:
SubstitutionMap &subMap) const;
using LookupConformanceFn =
llvm::function_ref<ProtocolConformanceRef(CanType dependentType,
llvm::function_ref<auto(CanType dependentType,
Type conformingReplacementType,
ProtocolType *conformedProtocol)>;
ProtocolType *conformedProtocol)
-> Optional<ProtocolConformanceRef>>;
/// Build an array of substitutions from an interface type substitution map,
/// using the given function to look up conformances.

View File

@@ -277,7 +277,7 @@ ArrayRef<Substitution>
GenericEnvironment::getForwardingSubstitutions(ModuleDecl *M) const {
auto lookupConformanceFn =
[&](CanType original, Type replacement, ProtocolType *protoType)
-> ProtocolConformanceRef {
-> Optional<ProtocolConformanceRef> {
return ProtocolConformanceRef(protoType->getDecl());
};

View File

@@ -315,8 +315,9 @@ getSubstitutions(ModuleDecl &mod,
for (auto req: reqs) {
assert(req.getKind() == RequirementKind::Conformance);
auto protoType = req.getSecondType()->castTo<ProtocolType>();
// TODO: Error handling for failed conformance lookup.
currentConformances.push_back(
lookupConformance(depTy->getCanonicalType(), currentReplacement,
*lookupConformance(depTy->getCanonicalType(), currentReplacement,
protoType));
}
@@ -336,8 +337,8 @@ getSubstitutions(ModuleDecl &mod,
SmallVectorImpl<Substitution> &result) const {
auto lookupConformanceFn =
[&](CanType original, Type replacement, ProtocolType *protoType)
-> ProtocolConformanceRef {
return *subMap.lookupConformance(original, protoType->getDecl());
-> Optional<ProtocolConformanceRef> {
return subMap.lookupConformance(original, protoType->getDecl());
};
getSubstitutions(mod, subMap.getMap(), lookupConformanceFn, result);

View File

@@ -628,8 +628,7 @@ TypeBase::gatherAllSubstitutions(Module *module,
auto lookupConformanceFn =
[&](CanType original, Type replacement, ProtocolType *protoType)
-> ProtocolConformanceRef {
-> Optional<ProtocolConformanceRef> {
auto *proto = protoType->getDecl();
// If the type is a type variable or is dependent, just fill in empty
@@ -638,12 +637,14 @@ TypeBase::gatherAllSubstitutions(Module *module,
replacement->isTypeParameter())
return ProtocolConformanceRef(proto);
// Otherwise, find the conformance.
// Otherwise, try to find the conformance.
auto conforms = module->lookupConformance(replacement, proto, resolver);
if (conforms)
return *conforms;
// FIXME: Should we ever end up here?
// We should return None and let getSubstitutions handle the error
// if we do.
return ProtocolConformanceRef(proto);
};

View File

@@ -108,20 +108,18 @@ Type Solution::computeSubstitutions(
auto lookupConformanceFn =
[&](CanType original, Type replacement, ProtocolType *protoType)
-> ProtocolConformanceRef {
-> Optional<ProtocolConformanceRef> {
if (replacement->hasError() ||
isOpenedAnyObject(replacement) ||
replacement->is<GenericTypeParamType>()) {
return ProtocolConformanceRef(protoType->getDecl());
}
auto conformance = tc.conformsToProtocol(
replacement,
return tc.conformsToProtocol(replacement,
protoType->getDecl(),
getConstraintSystem().DC,
(ConformanceCheckFlags::InExpression|
ConformanceCheckFlags::Used));
return *conformance;
};
sig->getSubstitutions(*mod, subs, lookupConformanceFn, result);