Skip to content

Expose discriminant values in stable_mir #93

Open
rust-lang/rust
#141639
@gmorenz

Description

@gmorenz

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.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions