Skip to content

[Sema] SR-15807: Associated Type Inference fails across module boundaries #42293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 20, 2022

Conversation

hank121314
Copy link
Contributor

Summary

This PR fixes: SR-15807

When ExtensionDecl is in the module file(created by deserializeExtension) using getSelfBoundsFromWhereClause will always get default value. Because extensionDecl->getTrailingWhereClause will always be nullptr.

Solution

This PR tries to create another function getSelfBoundsFromGenericSignature to resolve this issue.
getSelfBoundsFromGenericSignature will get SelfBounds using generic signature instead of trailingWhereClause.

Thanks

This is my first contribution, please feel free to critique, and thanks for your code review 😄 .

@xedin xedin requested a review from slavapestov April 11, 2022 02:50
Copy link
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.

Nice fix, thanks! I have a few minor comments but the overall approach looks great.

SelfBounds SelfBoundsFromGenericSignatureRequest::evaluate(
Evaluator &evaluator, const ExtensionDecl *extDecl) const {
SelfBounds result;
if (!extDecl->hasComputedGenericSignature())
Copy link
Contributor

Choose a reason for hiding this comment

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

This is brittle because it assumes someone else forced the computation by calling getGenericSignature() first. We want to trigger request computation lazily and not write code that depends on other requests having been executed first. You can just remove this conditional.

@@ -220,8 +220,8 @@ AssociatedTypeInference::inferTypeWitnessesViaValueWitnesses(
if (!checkConformance(proto))
return false;

// Now check any additional bounds on 'Self' from the where clause.
auto bounds = getSelfBoundsFromWhereClause(extension);
Copy link
Contributor

Choose a reason for hiding this comment

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

If the extension came from a source file, then it might still have a trailing where clause, so we still want to prefer to do it the old way since it avoids computing a generic signature and therefore it is faster. You can check if 'extension->getParentSourceFile() != nullptr' to determine which method to use.

@@ -0,0 +1,9 @@
// RUN: %empty-directory(%t)
Copy link
Contributor

Choose a reason for hiding this comment

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

A more descriptive name for the test, or a comment in the source file that explains this is about where clause Self bounds across module boundaries, might be good.

@hank121314
Copy link
Contributor Author

Thank you for the review and detailed explanation, I really appreciate it!
I have applied the suggestions in the last commit.

Thanks for your code review!

@@ -68,6 +68,9 @@ SWIFT_REQUEST(NameLookup, SelfBoundsFromWhereClauseRequest,
SelfBounds(llvm::PointerUnion<const TypeDecl *,
const ExtensionDecl *>),
Uncached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, SelfBoundsFromGenericSignatureRequest,
SelfBounds(const ExtensionDecl * extDecl),
Uncached, NoLocationInfo)
Copy link
Contributor

@slavapestov slavapestov Apr 12, 2022

Choose a reason for hiding this comment

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

Can you try making this request and SelfBoundsFromWhereClauseRequest Cached? (In a separate PR, if you like)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is my pleasure! I will do it!

@slavapestov
Copy link
Contributor

@swift-ci Please smoke test

@slavapestov
Copy link
Contributor

@swift-ci Please test source compatibility

@hank121314
Copy link
Contributor Author

Linux smoke test fails because of import Foundation. Already remove it. Sorry about that 😭 .
Not sure why source compatibility will fail when building GDRB.swift in release mode.
But I was able to pass this test in my local environment.
CI Failure:
https://ci.swift.org/view/Pull%20Requests/job/swift-PR-source-compat-suite-macos/136/console.

@@ -0,0 +1,16 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -o %t/ModuleA.swiftmodule %S/Inputs/where_clause_across_module_boundaries_module.swift
// RUN: %target-swift-frontend -I %t -emit-sil -verify %s
Copy link
Collaborator

Choose a reason for hiding this comment

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

Although there is no formal convention, it is preferable to align the compilation mode with the scope of the test, in this case -typecheck (or %target-typecheck-verify-swift) rather than -emit-sil.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it! Thanks for the review!

@CodaFi
Copy link
Contributor

CodaFi commented Apr 14, 2022

@swift-ci smoke test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants