diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs index 77821ca89bc..90f7dd733ca 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs @@ -111,7 +111,7 @@ enum RegionKind { } mod mcdc { - use rustc_middle::mir::coverage::{ConditionInfo, DecisionInfo}; + use rustc_middle::mir::coverage::{ConditionId, ConditionInfo, DecisionInfo}; /// Must match the layout of `LLVMRustMCDCDecisionParameters`. #[repr(C)] @@ -167,12 +167,13 @@ pub(crate) fn branch(branch_params: BranchParameters) -> Self { impl From for BranchParameters { fn from(value: ConditionInfo) -> Self { + let to_llvm_cond_id = |cond_id: Option| { + cond_id.and_then(|id| LLVMConditionId::try_from(id.as_usize()).ok()).unwrap_or(-1) + }; + let ConditionInfo { condition_id, true_next_id, false_next_id } = value; Self { - condition_id: value.condition_id.as_u32() as LLVMConditionId, - condition_ids: [ - value.false_next_id.as_u32() as LLVMConditionId, - value.true_next_id.as_u32() as LLVMConditionId, - ], + condition_id: to_llvm_cond_id(Some(condition_id)), + condition_ids: [to_llvm_cond_id(false_next_id), to_llvm_cond_id(true_next_id)], } } } diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index bfe2a2c2cb3..9a0f5a65321 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -67,7 +67,7 @@ pub struct ConditionId {} } impl ConditionId { - pub const NONE: Self = Self::from_u32(0); + pub const START: Self = Self::from_usize(0); } /// Enum that can hold a constant zero value, the ID of an physical coverage @@ -291,18 +291,8 @@ pub struct BranchSpan { #[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct ConditionInfo { pub condition_id: ConditionId, - pub true_next_id: ConditionId, - pub false_next_id: ConditionId, -} - -impl Default for ConditionInfo { - fn default() -> Self { - Self { - condition_id: ConditionId::NONE, - true_next_id: ConditionId::NONE, - false_next_id: ConditionId::NONE, - } - } + pub true_next_id: Option, + pub false_next_id: Option, } #[derive(Clone, Debug)] diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs index 6019a93e787..5c45a7a33a2 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs @@ -106,22 +106,27 @@ fn record_conditions(&mut self, op: LogicalOp, span: Span) { }), }; - let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_default(); - let lhs_id = if parent_condition.condition_id == ConditionId::NONE { + let parent_condition = decision_ctx.decision_stack.pop_back().unwrap_or_else(|| { + assert_eq!( + decision.num_conditions, 0, + "decision stack must be empty only for empty decision" + ); decision.num_conditions += 1; - ConditionId::from(decision.num_conditions) - } else { - parent_condition.condition_id - }; + ConditionInfo { + condition_id: ConditionId::START, + true_next_id: None, + false_next_id: None, + } + }); + let lhs_id = parent_condition.condition_id; - decision.num_conditions += 1; let rhs_condition_id = ConditionId::from(decision.num_conditions); - + decision.num_conditions += 1; let (lhs, rhs) = match op { LogicalOp::And => { let lhs = ConditionInfo { condition_id: lhs_id, - true_next_id: rhs_condition_id, + true_next_id: Some(rhs_condition_id), false_next_id: parent_condition.false_next_id, }; let rhs = ConditionInfo { @@ -135,7 +140,7 @@ fn record_conditions(&mut self, op: LogicalOp, span: Span) { let lhs = ConditionInfo { condition_id: lhs_id, true_next_id: parent_condition.true_next_id, - false_next_id: rhs_condition_id, + false_next_id: Some(rhs_condition_id), }; let rhs = ConditionInfo { condition_id: rhs_condition_id, @@ -164,10 +169,10 @@ fn take_condition( let Some(decision) = decision_ctx.processing_decision.as_mut() else { bug!("Processing decision should have been created before any conditions are taken"); }; - if condition_info.true_next_id == ConditionId::NONE { + if condition_info.true_next_id.is_none() { decision.end_markers.push(true_marker); } - if condition_info.false_next_id == ConditionId::NONE { + if condition_info.false_next_id.is_none() { decision.end_markers.push(false_marker); }