Reset partial memberlist on defered circularity to calculate the correct members #20179
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #16861
We've had this bug since we released generic defaults, according to my
bisect
test. The root cause of the assertion violation is anundefined
symbol which we expect to be present because of its presence in the class inheritance heirarchy. It is missing because the.members
cache of members was calculated while thebaseType
of the class was still resolving (as the generic defaultC["someProp"]
forces a resolution of them), and that partial list is kept around and reused even once the fully resolved inheritance hierarchy is known. In this PR, I simply clear that cache when I know it is missing values, as the recurrence is valid if the index does not access a member whose type is itself recursive (which will trigger a different recursion guard).Another option (rather than resetting the cache we know is bad) is to issue a circularity error - however since the circularity is indirect (via the index access), I believe it's fine to allow it so long as we acknowledge the partially created member cache we create prior to knowing that the type affects its own base - then deal with it appropriately. The most correct thing to do would probably be making
instantiateType
for an indexed access not instantiate the whole object type (and thereby any base types it may have) before callinggetPropertyOfType
on it, and instead attempt to just instantiate the single target symbol - there may even be a perf benefit to doing so.