Skip to content

[Sema] Fix compiler error when extending a typealias of a partially specialized generic type #73169

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

Open
wants to merge 61 commits into
base: main
Choose a base branch
from

Conversation

xavgru12
Copy link

@xavgru12 xavgru12 commented Apr 21, 2024

Resolves #68212.

@AnthonyLatsis
Copy link
Collaborator

@swift-ci please smoke test Linux

@saehejkang
Copy link
Contributor

saehejkang commented Apr 21, 2024

i was curious to see how this was solved and guess I was overcomplicating the issue 😭

@AnthonyLatsis
Copy link
Collaborator

This is far from solved, FWIW 🙂. I only triggered the tests to encourage the author to iterate on failures before any feedback arrives.

@xedin
Copy link
Contributor

xedin commented Apr 24, 2024

Is it possible to make this PR as a draft?

@AnthonyLatsis AnthonyLatsis marked this pull request as draft April 24, 2024 20:59
@xavgru12
Copy link
Author

I was converting to draft but Anthony was faster

@AnthonyLatsis
Copy link
Collaborator

For posterity, the convert to draft button is at the bottom of the Reviewers section.

@AnthonyLatsis AnthonyLatsis self-requested a review April 26, 2024 21:19
@AnthonyLatsis AnthonyLatsis self-assigned this Jan 27, 2025
@xavgru12 xavgru12 closed this Mar 10, 2025
@xavgru12 xavgru12 deleted the genericTypealias branch March 10, 2025 17:26
@xavgru12 xavgru12 reopened this Mar 10, 2025
@xavgru12
Copy link
Author

xavgru12 commented May 4, 2025

@AnthonyLatsis
I changed the code according review and added test cases. Let me know what you think about this.

@xavgru12 xavgru12 requested a review from AnthonyLatsis May 4, 2025 20:42
@xavgru12
Copy link
Author

@AnthonyLatsis reminder

@xavgru12
Copy link
Author

You once said a ping every two weeks is fine. So here I am pinging you @AnthonyLatsis

Copy link
Collaborator

@AnthonyLatsis AnthonyLatsis left a comment

Choose a reason for hiding this comment

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

Thank you for the reminders and the patience. Another somewhat random test case I think worth having:

struct S1<T> {
  struct Inner<U> {}
}

struct S2<T> {
  typealias A1<U> = S1<T>.Inner<U>
  typealias A2<U> = S1<T>.Inner<U> where T == Int
}

extension S2<Int>.A1 {
  func foo1() {
    let int: Int
    let _: T = int // OK
  }
}

extension S2.A2 {
  func foo2() {
    let int: Int
    let _: T = int // OK
  }
}

Comment on lines 3040 to 3045
if (!typealiasBoundGenericType->hasTypeParameter()) {
isInferredType = true;
} else {
isInferredType = false;
break;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we remove isInferredType, this can be

Suggested change
if (!typealiasBoundGenericType->hasTypeParameter()) {
isInferredType = true;
} else {
isInferredType = false;
break;
}
if (typealiasBoundGenericType->hasTypeParameter()) {
return false;
}

Copy link
Author

Choose a reason for hiding this comment

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

I removed isInferredType. I dislike the new solution because I have to write return true at the end of the function and I would like to have return false as default.

Comment on lines +3097 to +3103
if (!std::equal(nominalGenericParams.begin(), nominalGenericParams.end(),
typealiasGenericParams.begin(),
[](GenericTypeParamType *gp1, GenericTypeParamType *gp2) {
return gp1->isEqual(gp2);
})) {
return false;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

We need to perform this check regardless of whether the original number of generic params matched.

Copy link
Author

Choose a reason for hiding this comment

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

Confused here, added a comment above about this

Comment on lines 3081 to 3085
for (const auto &type : nominalGenericParams) {
if (type->getDepth() == maxDepth) {
nominalGenericParams = nominalGenericParams.drop_back();
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I like how this appears to be unsafe but is actually safe because we are trimming a non-owning view into the array. But this is probably better:

Suggested change
for (const auto &type : nominalGenericParams) {
if (type->getDepth() == maxDepth) {
nominalGenericParams = nominalGenericParams.drop_back();
}
}
while (!nominalGenericParams.empty() &&
nominalGenericParams.back().getDepth() == maxDepth) {
nominalGenericParams = nominalGenericParams.drop_back();
}

Test case for why we need !nominalGenericParams.empty():

struct S1<T> {
  struct Inner<U> {}
}
struct S2 {
  typealias A<T> = S1<T>.Inner<Int>
}
extension S2.A {
  func test() {
    let int: Int
    let _: U = int // error
  }
}

Copy link
Author

Choose a reason for hiding this comment

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

I add the test case and changed it to while.
The test does not produce an error.

So the nested struct parameter becomes Int. Then it checks for U which is Int now. Why is it supposed to produce an error?

@xavgru12
Copy link
Author

xavgru12 commented Jun 5, 2025

@AnthonyLatsis
I iterated over it and added some comments unresolving threads. Please review again and I hope you are able to keep the overview over this, so let me know if something is unclear.

@xavgru12
Copy link
Author

@AnthonyLatsis reminder

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.

Compiler error when extending a typealias of a partially specialized generic type
4 participants