Skip to content
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

Refine the handling of pointers in TypeAsDeepType #251

Merged
merged 10 commits into from
Aug 15, 2024

Conversation

sonalmahajan15
Copy link
Contributor

This PR refines the handling of *types.Pointer in TypeAsDeepType to only consider a pointer type deep if its underlying elements are of a deep type. The implication of always considering a pointer deep was that for type like var x *int; foo(x), unnecessary deep triggers were being created. The change in this PR reduces the creation of these redundant triggers.

a1 := new(int)
b1 := foo(a1)
print(*b1)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Earlier, total 5 triggers were created across these two functions, now only the required 3 are being created.

Copy link

codecov bot commented May 24, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 87.60%. Comparing base (4f33d8c) to head (0204bd5).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #251      +/-   ##
==========================================
- Coverage   87.63%   87.60%   -0.03%     
==========================================
  Files          63       63              
  Lines        7926     7916      -10     
==========================================
- Hits         6946     6935      -11     
+ Misses        800      799       -1     
- Partials      180      182       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Guards: consumer.Guards,
GuardMatched: true,
}
consumers[i].GuardMatched = true
Copy link
Contributor Author

@sonalmahajan15 sonalmahajan15 May 24, 2024

Choose a reason for hiding this comment

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

This change is not particularly related to the PR, but it is a small enough code cleanup, hence included in the same PR. The change is as following: since we have made our consumers as pointers, we can simply go ahead and modify its GuardMatched field, instead of having to override the object.

@sonalmahajan15 sonalmahajan15 marked this pull request as draft May 24, 2024 17:54
@sonalmahajan15 sonalmahajan15 force-pushed the sonalmahajan15/refine-type-as-deep branch from 2fea270 to eb7ecd5 Compare May 24, 2024 18:29
Copy link

github-actions bot commented May 24, 2024

Golden Test

Note

✅ NilAway errors reported on standard libraries are identical.

3271 errors on base branch (main, 4f33d8c)
3271 errors on test branch (b2560db)

@sonalmahajan15 sonalmahajan15 marked this pull request as ready for review May 24, 2024 19:02
Copy link
Contributor

@yuxincs yuxincs left a comment

Choose a reason for hiding this comment

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

Nice find!! I just have a quick question :)

util/util.go Outdated
Comment on lines 60 to 58
// Only consider pointers to deep types (e.g., `var x *[]int`) as deep type, not pointers to basic types (e.g., `var x *int`)
if _, ok := t.Elem().(*types.Basic); !ok {
return t.Elem(), true
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would this actually work for cases where it's a pointer to struct?

Do we actually want to call TypeAsDeepType recursively here? return TypeAsDeepType(t.Elem())?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah yes, good point. Now added support for pointer to struct. Added more test cases too, to cover this and a named deep type case.

I actually did do it the recursive way first, but quickly realized that if there exists a circular named type dependency then this goes into an infinite loop. But moreover, we were missing deep type cases like pointer of pointer (**x), causing a change in number of errors as well. The hypothesis of this PR was to only remove the redundant triggers without affecting the number of errors, hence backtracked from the recursive approach.

Copy link
Contributor

@yuxincs yuxincs May 29, 2024

Choose a reason for hiding this comment

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

exists a circular named type dependency then this goes into an infinite loop

Hmmm, is it something like this?

type A *B
type B *A

It's definitely weird, and the compiler doesn't complain (it complains if you do type A B; type B A though...).

(it would probably be good to add the pattern to the test suite to avoid accidental regressions)

But moreover, we were missing deep type cases like pointer of pointer (**x), causing a change in number of errors as well.

Are you suggesting pointer of a named type, where the named type is also a pointer (e.g., type A *B; type B *int)? I think by default double pointers aren't allowed. I think other helper functions probably suffer from the same double-ptr problem, and we definitely don't need to handle them in this PR :) Also, are we missing cases like named types, i.e., type A []int where A should be considered deep as well, right?

Another proposal for simpler handling:

Instead of recursions, should we unwrap the ptr first, and then check it's type (like other utility functions in this package), e.g.,

switch UnwrapPtr(t).(type) {
case ....
// no case for `*types.Pointer`
}

This definitely would miss the cases discussed above:
(1) double-ptrs: we're only unwrapping the ptr once, but it avoids infinite loops (and handling double ptrs should be more complex and in separate PRs).
(2) named types: well, if we do UnwrapPtr(t.Underlying()), we should be handling it fine? we can put those in separate PRs as well (with more test cases perhaps)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We had discussed this point extensively internally. Updating the logic accordingly, incorporating your suggestion and internal discussion.

@sonalmahajan15 sonalmahajan15 force-pushed the sonalmahajan15/refine-type-as-deep branch from d22dfba to bb822fa Compare May 25, 2024 00:26
@sonalmahajan15 sonalmahajan15 force-pushed the sonalmahajan15/refine-type-as-deep branch from 3285cec to 0204bd5 Compare July 28, 2024 22:30
@sonalmahajan15 sonalmahajan15 merged commit 8ff8105 into main Aug 15, 2024
8 checks passed
@sonalmahajan15 sonalmahajan15 deleted the sonalmahajan15/refine-type-as-deep branch August 15, 2024 18:05
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.

2 participants