type certainty: clear DefId when an expression's type changes to non-adt
#12591
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 #12585
The root cause of the ICE in the linked issue was in the expression
one.x, in the array literal.The type of
oneis theOnestruct: an adt with a DefId, so its certainty isCertain(def_id_of_one). However, the field access.xcan then change the type (toi32here) and that should update thatDefIdaccordingly. It does do that correctly whenone.xwould be another adt with a DefId:rust-clippy/clippy_utils/src/ty/type_certainty/mod.rs
Lines 90 to 91 in 97ba291
but when it isn't an adt and there is no def id (which is the case in the linked issue:
one.xis an i32), it keeps theDefIdofOne, even though that's the wrong type (which would then lead to a contradiction later when joiningCertaintys):rust-clippy/clippy_utils/src/ty/type_certainty/mod.rs
Lines 92 to 93 in 97ba291
In particular, in the linked issue,
from_array([one.x, two.x])would try to join theCertaintyof the two array elements, which should have been[Certain(None), Certain(None)], becausei32s have noDefId, but instead it was[Certain(One), Certain(Two)], because the DefId wasn't cleared from when it was visitingoneandtwo. This is the "contradiction" that could be seen in the ICE message... so this changes it to clear the
DefIdwhen it isn't an adt.cc @smoelius you implemented this initially in #11135, does this change make sense to you?
changelog: none