rust-lang / rust-lang/rustc_public

Expose discriminant values in stable_mir

Open
#93 4 comments 0 reactions 1 assignee View on GitHub

@NotLebedev is already working on this.

Since Mar 18, 2025.

good first issue
Dominant language
Rust
Stars
125
Forks
19
PR merge metrics
No merged PRs in 30d

Description

As far as I can tell, the actual discriminant values of an enum aren't exposed in stable_mir. Which, amongst other things, means we can't tell what branch we traverse in match/if-let statements.

Kani uses discriminant_for_variant on a rustc_middle::ty::Ty for this. discriminant_for_variant returns an Option<Discr<'tcx>> where Discr contains a val: u128, and a ty: Ty<'tcx>.

Would a PR adding this method to stable_mir be welcome?


I think the most natural place for this in stable_mir is RigidTy, which is also where discriminant_ty is in stable_mir.

The value is really meaningful for two variants of RigidTy: AdtDef and Coroutine. rustc_middle::Ty::discriminant_for_variant returns None except on those two types. We could either copy that behavior, or we could follow the definition of stable_mir::Rvalue::Discriminant and return a 0 of the appropriate type for all RigidTys other than AdtDef and Coroutine (probably requiring that variant_idx = 0). The latter seems more consistent with the intent to me, but I don't think it matters a whole lot either way.

Alternatively or additionally we could add it (and maybe discriminant_ty as well) on AdtDef and Coroutine. Or we could follow rustc_middle and put it on Ty, though IMHO that's a strange place to have it.

For context:

rustc_middle exposes discriminant_for_variant on Ty (returning an Option), and directly on AdtDef (which might make sense for us), and CoroutineArgs (which we don't even have, but we could substitute in Coroutine). It also exposes discriminant_ty only on Ty, not on RigidTy (like stable_mir does), nor on AdtDef/Coroutine despite the discriminant_for_variant functions.

discriminant_ty's detailed behavior in rustc_middle is as follows:

  • Bound, Placeholder, Fresh...Ty: bug
  • AdtDef and Coroutine delegate to AdtDef/CourtineArgsExt.
  • Param, Alias, and Infer it returns some projected type (not sure I understand that)
  • ty::Pat it defers to the ty in the pattern.
  • For everything else it returns u8.

stable_mir has a discriminant_ty on TyKind as well as RigidTy, it returns an Option<Ty> and is simply calling RigidTy's AdtDef.

rustc_middle also has AdtDef/CoroutineArgs``::discriminants returning an iterator over all variants, and AdtDef::discrimimant_def_for_variant returning a Option<DefId> of the most recent variant with an explicit definition and a u32 offset from that.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.