Skip to content

[Sema] Handle invalid @_specialize generic signatures#89239

Open
Jiaxu-Li wants to merge 1 commit into
swiftlang:mainfrom
Jiaxu-Li:fix-89154-specialize-invalid-signature
Open

[Sema] Handle invalid @_specialize generic signatures#89239
Jiaxu-Li wants to merge 1 commit into
swiftlang:mainfrom
Jiaxu-Li:fix-89154-specialize-invalid-signature

Conversation

@Jiaxu-Li
Copy link
Copy Markdown

Reject invalid @_specialize generic signatures before serialization can reconstruct interface types from inconsistent requirement-machine state.

Add a reduced regression test for swiftlang#89154.

Resolves swiftlang#89154
Copy link
Copy Markdown
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you spilt this up into multiple commits? It's a pretty involved set of changes and I'd like to go through them one by one.

// not in protocol requirement signatures.
if (conformance.isConcrete() &&
key.getRootProtocol() == nullptr)
inferConditionalRequirements(conformance.getConcrete(), substitutions);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you're plumbing through invalidTypeWitness to avoid a crash in inferConditionalRequirements()? Perhaps there's a better way to address the root cause.

if (errors.contains(GenericSignatureErrorFlags::HasInvalidRequirements) ||
errors.contains(GenericSignatureErrorFlags::CompletionFailed) ||
errors.contains(GenericSignatureErrorFlags::CircularReference)) {
attr->setInvalid();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If any of these conditions happened, we should have diagnosed an error in InferredGenericSignatureRequest. What does setting the invalid flag on top of that achieve?

auto conformsTo = props->getConformsTo();
if (std::find(conformsTo.begin(), conformsTo.end(),
symbol.getProtocol()) == conformsTo.end()) {
if (astCtx.hadError())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, we have a couple of open bugs here where it's possible to form a type term like T.[P:A].[Q:B] where T.[P:A] doesn't conform to Q.

Here is a crash in another spot that's related, the problem here is that Slice is malformed because Element doesn't conform to Collection:

protocol ElementProtocol {}
protocol MyCollection: RandomAccessCollection, MutableCollection, RangeReplaceableCollection where Index == Int, Element: ElementProtocol, SubSequence == Slice<Element> {
}

I'm not sure what the best fix is, though. Perhaps when expanding a concrete conformance, we should add any missing conformance rules and record the fact that we did.


auto recordInvalidTypeWitness = [&] {
if (requirementKind == RequirementKind::SameType)
System.recordConflict(conformanceRuleID, concreteRuleID);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this diagnose an error in a case that wasn't previously being diagnosed? Do you have an example not involving @_specialize?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants