Skip to content

Commit c28d195

Browse files
committed
Address review comments
Clean up code and add comments. Use InlineConstant to wrap range patterns.
1 parent 98b4c1e commit c28d195

File tree

7 files changed

+56
-62
lines changed

7 files changed

+56
-62
lines changed

compiler/rustc_middle/src/thir.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -749,8 +749,19 @@ pub enum PatKind<'tcx> {
749749
value: mir::Const<'tcx>,
750750
},
751751

752+
/// Inline constant found while lowering a pattern.
752753
InlineConstant {
753-
value: mir::UnevaluatedConst<'tcx>,
754+
/// [LocalDefId] of the constant, we need this so that we have a
755+
/// reference that can be used by unsafety checking to visit nested
756+
/// unevaluated constants.
757+
def: LocalDefId,
758+
/// If the inline constant is used in a range pattern, this subpattern
759+
/// represents the range (if both ends are inline constants, there will
760+
/// be multiple InlineConstant wrappers).
761+
///
762+
/// Otherwise, the actual pattern that the constant lowered to. As with
763+
/// other constants, inline constants are matched structurally where
764+
/// possible.
754765
subpattern: Box<Pat<'tcx>>,
755766
},
756767

@@ -910,7 +921,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
910921
write!(f, "{subpattern}")
911922
}
912923
PatKind::Constant { value } => write!(f, "{value}"),
913-
PatKind::InlineConstant { value: _, ref subpattern } => {
924+
PatKind::InlineConstant { def: _, ref subpattern } => {
914925
write!(f, "{} (from inline const)", subpattern)
915926
}
916927
PatKind::Range(box PatRange { lo, hi, end }) => {

compiler/rustc_middle/src/thir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
233233
}
234234
}
235235
Constant { value: _ } => {}
236-
InlineConstant { value: _, subpattern } => visitor.visit_pat(subpattern),
236+
InlineConstant { def: _, subpattern } => visitor.visit_pat(subpattern),
237237
Range(_) => {}
238238
Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
239239
for subpattern in prefix.iter() {

compiler/rustc_mir_build/src/build/matches/simplify.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
204204
Err(match_pair)
205205
}
206206

207-
PatKind::InlineConstant { subpattern: ref pattern, value: _ } => {
207+
PatKind::InlineConstant { subpattern: ref pattern, def: _ } => {
208208
candidate.match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
209209

210210
Ok(())
@@ -236,20 +236,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
236236
// pattern/_match.rs for another pertinent example of this pattern).
237237
//
238238
// Also, for performance, it's important to only do the second
239-
// `try_eval_scalar_int` if necessary.
240-
let lo = lo
241-
.try_eval_scalar_int(self.tcx, self.param_env)
242-
.unwrap()
243-
.to_bits(sz)
244-
.unwrap()
245-
^ bias;
239+
// `try_to_bits` if necessary.
240+
let lo = lo.try_to_bits(sz).unwrap() ^ bias;
246241
if lo <= min {
247-
let hi = hi
248-
.try_eval_scalar_int(self.tcx, self.param_env)
249-
.unwrap()
250-
.to_bits(sz)
251-
.unwrap()
252-
^ bias;
242+
let hi = hi.try_to_bits(sz).unwrap() ^ bias;
253243
if hi > max || hi == max && end == RangeEnd::Included {
254244
// Irrefutable pattern match.
255245
return Ok(());

compiler/rustc_mir_build/src/build/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
6767
thir::BodyTy::Const(ty) => construct_const(tcx, def, thir, expr, ty),
6868
};
6969

70-
tcx.ensure().check_match(def);
7170
// this must run before MIR dump, because
7271
// "not all control paths return a value" is reported here.
7372
//

compiler/rustc_mir_build/src/check_unsafety.rs

+7-20
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::errors::*;
33
use rustc_middle::thir::visit::{self, Visitor};
44

55
use rustc_hir as hir;
6-
use rustc_middle::mir::{BorrowKind, Const};
6+
use rustc_middle::mir::BorrowKind;
77
use rustc_middle::thir::*;
88
use rustc_middle::ty::print::with_no_trimmed_paths;
99
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
@@ -124,7 +124,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
124124
/// Handle closures/generators/inline-consts, which is unsafecked with their parent body.
125125
fn visit_inner_body(&mut self, def: LocalDefId) {
126126
if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
127-
let _ = self.tcx.ensure_with_value().mir_built(def);
127+
// Runs all other queries that depend on THIR.
128+
self.tcx.ensure_with_value().mir_built(def);
128129
let inner_thir = &inner_thir.steal();
129130
let hir_context = self.tcx.hir().local_def_id_to_hir_id(def);
130131
let mut inner_visitor = UnsafetyVisitor { thir: inner_thir, hir_context, ..*self };
@@ -278,23 +279,8 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
278279
visit::walk_pat(self, pat);
279280
self.inside_adt = old_inside_adt;
280281
}
281-
PatKind::Range(range) => {
282-
if let Const::Unevaluated(c, _) = range.lo {
283-
if let hir::def::DefKind::InlineConst = self.tcx.def_kind(c.def) {
284-
let def_id = c.def.expect_local();
285-
self.visit_inner_body(def_id);
286-
}
287-
}
288-
if let Const::Unevaluated(c, _) = range.hi {
289-
if let hir::def::DefKind::InlineConst = self.tcx.def_kind(c.def) {
290-
let def_id = c.def.expect_local();
291-
self.visit_inner_body(def_id);
292-
}
293-
}
294-
}
295-
PatKind::InlineConstant { value, .. } => {
296-
let def_id = value.def.expect_local();
297-
self.visit_inner_body(def_id);
282+
PatKind::InlineConstant { def, .. } => {
283+
self.visit_inner_body(*def);
298284
}
299285
_ => {
300286
visit::walk_pat(self, pat);
@@ -804,7 +790,8 @@ pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
804790
}
805791

806792
let Ok((thir, expr)) = tcx.thir_body(def) else { return };
807-
let _ = tcx.ensure_with_value().mir_built(def);
793+
// Runs all other queries that depend on THIR.
794+
tcx.ensure_with_value().mir_built(def);
808795
let thir = &thir.steal();
809796
// If `thir` is empty, a type error occurred, skip this body.
810797
if thir.exprs.is_empty() {

compiler/rustc_mir_build/src/thir/pattern/mod.rs

+27-20
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc_middle::ty::{
2727
self, AdtDef, CanonicalUserTypeAnnotation, GenericArg, GenericArgsRef, Region, Ty, TyCtxt,
2828
TypeVisitableExt, UserType,
2929
};
30+
use rustc_span::def_id::LocalDefId;
3031
use rustc_span::{ErrorGuaranteed, Span, Symbol};
3132
use rustc_target::abi::{FieldIdx, Integer};
3233

@@ -88,19 +89,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
8889
fn lower_pattern_range_endpoint(
8990
&mut self,
9091
expr: Option<&'tcx hir::Expr<'tcx>>,
91-
) -> Result<(Option<mir::Const<'tcx>>, Option<Ascription<'tcx>>), ErrorGuaranteed> {
92+
) -> Result<
93+
(Option<mir::Const<'tcx>>, Option<Ascription<'tcx>>, Option<LocalDefId>),
94+
ErrorGuaranteed,
95+
> {
9296
match expr {
93-
None => Ok((None, None)),
97+
None => Ok((None, None, None)),
9498
Some(expr) => {
95-
let (kind, ascr) = match self.lower_lit(expr) {
96-
PatKind::InlineConstant { subpattern, value } => (
97-
PatKind::Constant { value: Const::Unevaluated(value, subpattern.ty) },
98-
None,
99-
),
99+
let (kind, ascr, inline_const) = match self.lower_lit(expr) {
100+
PatKind::InlineConstant { subpattern, def } => {
101+
(subpattern.kind, None, Some(def))
102+
}
100103
PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
101-
(kind, Some(ascription))
104+
(kind, Some(ascription), None)
102105
}
103-
kind => (kind, None),
106+
kind => (kind, None, None),
104107
};
105108
let value = if let PatKind::Constant { value } = kind {
106109
value
@@ -110,7 +113,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
110113
);
111114
return Err(self.tcx.sess.delay_span_bug(expr.span, msg));
112115
};
113-
Ok((Some(value), ascr))
116+
Ok((Some(value), ascr, inline_const))
114117
}
115118
}
116119
}
@@ -181,8 +184,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
181184
return Err(self.tcx.sess.delay_span_bug(span, msg));
182185
}
183186

184-
let (lo, lo_ascr) = self.lower_pattern_range_endpoint(lo_expr)?;
185-
let (hi, hi_ascr) = self.lower_pattern_range_endpoint(hi_expr)?;
187+
let (lo, lo_ascr, lo_inline) = self.lower_pattern_range_endpoint(lo_expr)?;
188+
let (hi, hi_ascr, hi_inline) = self.lower_pattern_range_endpoint(hi_expr)?;
186189

187190
let lo = lo.unwrap_or_else(|| {
188191
// Unwrap is ok because the type is known to be numeric.
@@ -241,6 +244,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
241244
};
242245
}
243246
}
247+
for inline_const in [lo_inline, hi_inline] {
248+
if let Some(def) = inline_const {
249+
kind =
250+
PatKind::InlineConstant { def, subpattern: Box::new(Pat { span, ty, kind }) };
251+
}
252+
}
244253
Ok(kind)
245254
}
246255

@@ -606,11 +615,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
606615
// const eval path below.
607616
// FIXME: investigate the performance impact of removing this.
608617
let lit_input = match expr.kind {
609-
hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
610-
hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
611-
hir::ExprKind::Lit(ref lit) => {
612-
Some(LitToConstInput { lit: &lit.node, ty, neg: true })
613-
}
618+
hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
619+
hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
620+
hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
614621
_ => None,
615622
},
616623
_ => None,
@@ -646,7 +653,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
646653
span,
647654
None,
648655
);
649-
PatKind::InlineConstant { subpattern, value: uneval }
656+
PatKind::InlineConstant { subpattern, def: def_id }
650657
} else {
651658
// If that fails, convert it to an opaque constant pattern.
652659
match tcx.const_eval_resolve(self.param_env, uneval, Some(span)) {
@@ -828,8 +835,8 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
828835
PatKind::Deref { subpattern: subpattern.fold_with(folder) }
829836
}
830837
PatKind::Constant { value } => PatKind::Constant { value },
831-
PatKind::InlineConstant { value, subpattern: ref pattern } => {
832-
PatKind::InlineConstant { value, subpattern: pattern.fold_with(folder) }
838+
PatKind::InlineConstant { def, subpattern: ref pattern } => {
839+
PatKind::InlineConstant { def, subpattern: pattern.fold_with(folder) }
833840
}
834841
PatKind::Range(ref range) => PatKind::Range(range.clone()),
835842
PatKind::Slice { ref prefix, ref slice, ref suffix } => PatKind::Slice {

compiler/rustc_mir_build/src/thir/print.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
692692
}
693693
PatKind::Deref { subpattern } => {
694694
print_indented!(self, "Deref { ", depth_lvl + 1);
695-
print_indented!(self, "subpattern: ", depth_lvl + 2);
695+
print_indented!(self, "subpattern:", depth_lvl + 2);
696696
self.print_pat(subpattern, depth_lvl + 2);
697697
print_indented!(self, "}", depth_lvl + 1);
698698
}
@@ -701,10 +701,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
701701
print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
702702
print_indented!(self, "}", depth_lvl + 1);
703703
}
704-
PatKind::InlineConstant { value, subpattern } => {
704+
PatKind::InlineConstant { def, subpattern } => {
705705
print_indented!(self, "InlineConstant {", depth_lvl + 1);
706-
print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
707-
print_indented!(self, "subpattern: ", depth_lvl + 2);
706+
print_indented!(self, format!("def: {:?}", def), depth_lvl + 2);
707+
print_indented!(self, "subpattern:", depth_lvl + 2);
708708
self.print_pat(subpattern, depth_lvl + 2);
709709
print_indented!(self, "}", depth_lvl + 1);
710710
}

0 commit comments

Comments
 (0)