Merge pull request #42257 from hborla/concrete-generic-params

[RequirementMachine] Diagnose type parameters that are made concrete by a same-type requirement.
This commit is contained in:
Holly Borla
2022-04-12 18:27:43 -07:00
committed by GitHub
12 changed files with 80 additions and 30 deletions

View File

@@ -413,6 +413,18 @@ RequirementSignatureRequestRQM::evaluate(Evaluator &evaluator,
machine->computeRequirementDiagnostics(errors, proto->getLoc());
diagnoseRequirementErrors(ctx, errors,
AllowConcreteTypePolicy::NestedAssocTypes);
for (auto *protocol : machine->System.getProtocols()) {
auto selfType = protocol->getSelfInterfaceType();
auto concrete = machine->getConcreteType(selfType,
machine->getGenericParams(),
protocol);
if (!concrete || concrete->hasError())
continue;
protocol->diagnose(diag::requires_generic_param_made_equal_to_concrete,
selfType);
}
}
if (!machine->getErrors()) {
@@ -859,8 +871,6 @@ InferredGenericSignatureRequestRQM::evaluate(
: AllowConcreteTypePolicy::AssocTypes);
}
// FIXME: Handle allowConcreteGenericParams
// Don't bother splitting concrete equivalence classes if there were invalid
// requirements, because the signature is not going to be ABI anyway.
if (!errorFlags.contains(GenericSignatureErrorFlags::HasInvalidRequirements)) {
@@ -887,6 +897,28 @@ InferredGenericSignatureRequestRQM::evaluate(
std::move(machine));
}
if (!allowConcreteGenericParams &&
ctx.LangOpts.RequirementMachineInferredSignatures ==
RequirementMachineMode::Enabled) {
for (auto genericParam : result.getInnermostGenericParams()) {
auto canonical = result.getCanonicalTypeInContext(genericParam);
if (canonical->hasError() || canonical->isEqual(genericParam))
continue;
if (canonical->isTypeParameter()) {
ctx.Diags.diagnose(loc, diag::requires_generic_params_made_equal,
genericParam, result->getSugaredType(canonical))
.warnUntilSwiftVersion(6);
} else {
ctx.Diags.diagnose(loc,
diag::requires_generic_param_made_equal_to_concrete,
genericParam)
.warnUntilSwiftVersion(6);
}
}
}
if (!errorFlags.contains(GenericSignatureErrorFlags::HasInvalidRequirements)) {
// Check invariants.
result.verify();