Make sure ErrorTypes containing type variables are marked as such. #7963
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.
In some cases, the type checker will produce error types with the "original type" intact for recovery purposes. Like other types, when the original type contains a type variable, the ErrorType instance will be allocated in the "temporary" memory arena associated with the active constraint solver, because there's no way that particular error will come up again once the constraint system containing that type variable has been destroyed.
However, we weren't propagating that "contains a type variable" information to the newly-created ErrorType, which meant that any type containing that ErrorType would be allocated in the "permanent" arena. In practice, this would always be a DependentMemberType; not too many types are created without looking at their base types at all. The arena containing the ErrorType would then be deallocated, and its memory reused later on for a different type. If we ever tried to make a DependentMemberType whose base was this new type, we'd find the old DependentMemberType instance in our cache and return that. The result was that we'd have a DependentMemberType whose "HasError" bit was set even though the base type was not an error type, and which was considered canonical whether or not the base type was. This would then either hit an assertion later on or result in nonsensical errors like
'C.Iterator' is not the same type as 'C.Iterator'
.Because the reused address always referred to a valid type, none of the usual dynamic analysis tools could catch the problem. It really comes down to using a pointer address as a key in a map—but even without that, we were allocating types in the permanent arena that really should be temporary, which is a waste of memory.
Likely fixes rdar://problem/30382791, a nondeterministic failure we've been seeing for weeks on the bots and on developer machines.