Skip to content

Reset partial memberlist on defered circularity to calculate the correct members #20179

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 2 commits into from
Dec 22, 2017

Conversation

weswigham
Copy link
Member

@weswigham weswigham commented Nov 21, 2017

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 an undefined 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 the baseType of the class was still resolving (as the generic default C["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 calling getPropertyOfType on it, and instead attempt to just instantiate the single target symbol - there may even be a perf benefit to doing so.

@@ -5057,11 +5057,11 @@ namespace ts {
return type.resolvedBaseTypes;
}

function resolveBaseTypesOfClass(type: InterfaceType): void {
type.resolvedBaseTypes = emptyArray;
function resolveBaseTypesOfClass(type: InterfaceType): BaseType[] {
Copy link
Contributor

Choose a reason for hiding this comment

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

It doesn't look like you are using this return type.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, I was just using it to ensure I set resolvedBaseType at each exit point. I can replace it with void if you'd like.

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

My only concern is interaction with my fix in #20400, but I think it will be fine -- at most we should see an two recursions instead of one. I will test after you merge.

@weswigham weswigham merged commit cedcba9 into microsoft:master Dec 22, 2017
@weswigham weswigham deleted the fix-assertion branch December 22, 2017 19:41
errendir added a commit to errendir/TypeScript that referenced this pull request Jan 7, 2018
* origin/master: (216 commits)
  Accepted baselines.
  Check whether we have a class before testing whether we have a super-class.
  Added tests.
  LEGO: check in for master to temporary branch.
  LEGO: check in for master to temporary branch.
  Add method signature handler to getTypeOfVariableOrParameterOrProperty (microsoft#20825)
  LEGO: check in for master to temporary branch.
  Simplify test and add explanatory assertion
  LEGO: check in for master to temporary branch.
  Add dynamic file open test
  Allow dynamic files script info to be created when not opened by client
  LEGO: check in for master to temporary branch.
  Accept new baselines
  Add regression test
  Fix narrowTypeBySwitchOnDiscriminant function
  LEGO: check in for master to temporary branch.
  LEGO: check in for master to temporary branch.
  Move recursion limiter to individual resolve* functions
  User runner submodule improvements (microsoft#20868)
  Reset partial memberlist on defered circularity to calculate the correct members (microsoft#20179)
  ...
@microsoft microsoft locked and limited conversation to collaborators Jun 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

tsc TypeError: Cannot read property 'flags' of undefined
3 participants