Skip to content

Commit 28debe0

Browse files
committed
Implement #[cold] on match arms
1 parent 43ca9d1 commit 28debe0

File tree

6 files changed

+39
-3
lines changed

6 files changed

+39
-3
lines changed

compiler/rustc_middle/src/thir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ pub struct Arm<'tcx> {
568568
pub lint_level: LintLevel,
569569
pub scope: region::Scope,
570570
pub span: Span,
571+
pub is_cold: bool,
571572
}
572573

573574
#[derive(Copy, Clone, Debug, HashStable)]

compiler/rustc_mir_build/src/builder/matches/mod.rs

+30-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::middle::region;
1414
use rustc_middle::mir::{self, *};
1515
use rustc_middle::thir::{self, *};
1616
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
17-
use rustc_span::{BytePos, Pos, Span, Symbol};
17+
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
1818
use tracing::{debug, instrument};
1919

2020
use crate::builder::ForGuard::{self, OutsideGuard, RefWithinGuard};
@@ -458,7 +458,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
458458
opt_scrutinee_place,
459459
);
460460

461-
let arm_block = this.bind_pattern(
461+
let mut arm_block = this.bind_pattern(
462462
outer_source_info,
463463
branch,
464464
&built_match_tree.fake_borrow_temps,
@@ -467,6 +467,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
467467
EmitStorageLive::Yes,
468468
);
469469

470+
if arm.is_cold
471+
&& let Some(cold_path_def) = this.tcx.get_diagnostic_item(sym::cold_path)
472+
{
473+
let cold_path_ty = this.tcx.type_of(cold_path_def).instantiate_identity();
474+
let cold_path = Operand::Constant(Box::new(ConstOperand {
475+
span: arm.span,
476+
user_ty: None,
477+
const_: Const::from_value(ConstValue::ZeroSized, cold_path_ty),
478+
}));
479+
let new_arm_block = this.cfg.start_new_block();
480+
let cold_path_result =
481+
this.local_decls.push(LocalDecl::new(this.tcx.types.unit, arm.span));
482+
this.cfg.terminate(
483+
arm_block,
484+
this.source_info(arm.span),
485+
TerminatorKind::Call {
486+
func: cold_path,
487+
args: Box::new([]),
488+
destination: Place::from(cold_path_result),
489+
target: Some(new_arm_block),
490+
unwind: UnwindAction::Unreachable,
491+
call_source: CallSource::Misc,
492+
fn_span: arm.span,
493+
},
494+
);
495+
arm_block = new_arm_block;
496+
}
497+
470498
this.fixed_temps_scope = old_dedup_scope;
471499

472500
if let Some(source_scope) = scope {

compiler/rustc_mir_build/src/thir/cx/expr.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1005,13 +1005,15 @@ impl<'tcx> ThirBuildCx<'tcx> {
10051005
}
10061006

10071007
fn convert_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) -> ArmId {
1008+
let attrs = self.tcx.hir().attrs(arm.hir_id);
10081009
let arm = Arm {
10091010
pattern: self.pattern_from_hir(&arm.pat),
10101011
guard: arm.guard.as_ref().map(|g| self.mirror_expr(g)),
10111012
body: self.mirror_expr(arm.body),
10121013
lint_level: LintLevel::Explicit(arm.hir_id),
10131014
scope: region::Scope { local_id: arm.hir_id.local_id, data: region::ScopeData::Node },
10141015
span: arm.span,
1016+
is_cold: attrs.iter().any(|a| a.name_or_empty() == sym::cold),
10151017
};
10161018
self.thir.arms.push(arm)
10171019
}

compiler/rustc_mir_build/src/thir/print.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
623623
print_indented!(self, "Arm {", depth_lvl);
624624

625625
let arm = &self.thir.arms[arm_id];
626-
let Arm { pattern, guard, body, lint_level, scope, span } = arm;
626+
let Arm { pattern, guard, body, lint_level, scope, span, is_cold } = arm;
627627

628628
print_indented!(self, "pattern: ", depth_lvl + 1);
629629
self.print_pat(pattern, depth_lvl + 2);
@@ -640,6 +640,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
640640
print_indented!(self, format!("lint_level: {:?}", lint_level), depth_lvl + 1);
641641
print_indented!(self, format!("scope: {:?}", scope), depth_lvl + 1);
642642
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
643+
print_indented!(self, format!("is_cold: {:?}", is_cold), depth_lvl + 1);
643644
print_indented!(self, "}", depth_lvl);
644645
}
645646

library/core/src/intrinsics/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,7 @@ pub const unsafe fn assume(b: bool) {
14751475
/// This intrinsic does not have a stable counterpart.
14761476
#[unstable(feature = "core_intrinsics", issue = "none")]
14771477
#[rustc_intrinsic]
1478+
#[rustc_diagnostic_item = "cold_path"]
14781479
#[rustc_nounwind]
14791480
#[miri::intrinsic_fallback_is_spec]
14801481
#[cold]

tests/ui/thir-print/thir-tree-match.stdout

+3
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ body:
143143
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).14))
144144
scope: Node(14)
145145
span: $DIR/thir-tree-match.rs:17:9: 17:40 (#0)
146+
is_cold: false
146147
}
147148
Arm {
148149
pattern:
@@ -195,6 +196,7 @@ body:
195196
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).20))
196197
scope: Node(20)
197198
span: $DIR/thir-tree-match.rs:18:9: 18:32 (#0)
199+
is_cold: false
198200
}
199201
Arm {
200202
pattern:
@@ -239,6 +241,7 @@ body:
239241
lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).26))
240242
scope: Node(26)
241243
span: $DIR/thir-tree-match.rs:19:9: 19:28 (#0)
244+
is_cold: false
242245
}
243246
]
244247
}

0 commit comments

Comments
 (0)