Fix ICE in read_discriminant for enums with non-contiguous discriminants#154776
Conversation
|
r? @mati865 rustbot has assigned @mati865. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
72cf8ac to
a082578
Compare
| // layout range above, this cannot fail. | ||
| // Convert discriminant to variant index. The tag may pass the layout range | ||
| // check above but still not match any actual variant discriminant (e.g., | ||
| // non-contiguous discriminants with a wrapping valid_range). |
|
@bors r+ rollup The change and test look good, thanks. I'm not sure of the relation to #153758 but the PR also isn't marked as fixing that issue so that's not a blocker. The ICE site is indeed exactly what this PR works on so -- I guess it could really fix that issue as well. Did you manually check that? |
|
yes, I've tested it - all three reproducers from #153758 (original, refined, and with generic_assert) ICE at the same line 128 without the fix. the path is |
FWIW that is also a bug that should be fixed IMO. |
agreed, that's a separate issue though, i will work on this |
Rollup of 5 pull requests Successful merges: - #154376 (Remove more BuiltinLintDiag variants - part 4) - #154731 (llvm: Fix array ABI test to not check equality implementation) - #127534 (feat(core): impl Step for NonZero<u*>) - #154703 (Fix trailing comma in lifetime suggestion for empty angle brackets) - #154776 (Fix ICE in read_discriminant for enums with non-contiguous discriminants)
Rollup merge of #154776 - enthropy7:fix-ice-discriminant-none, r=RalfJung Fix ICE in read_discriminant for enums with non-contiguous discriminants so, investigation of #153758 took a while. it seems, that reverting back to older approach is the best we can do there. > `read_discriminant `ICEs (unwrap on `None`) when an enum's `valid_range` is wider than its set of actual discriminants. this happens for enums with gaps in their discriminant values — e.g. `{0, 2, 3, 4, 5} `has `` valid_range`` 0..=5 `` which includes `1`, or `{i64::MIN, i64::MAX}` has a wrapping range covering everything. [b840338](b840338) commit added a `valid_range` check and replaced the prior `.ok_or_else(|| err_ub!(InvalidTag(...)))` with `.unwrap()`, assuming the range check would guarantee a matching variant. that assumption is wrong for non-contiguous discriminants. my fix restores the fallible lookup, returning `InvalidTag` UB instead of panicking. also it affected crates - **sec1, ntex-mqtt**, when compiled with optimizations, where the `jump_threading` MIR pass constructs constants with tag values inside the `valid_range` but not matching any actual variant.
so, investigation of #153758 took a while. it seems, that reverting back to older approach is the best we can do there.