Remove the is_inline field from PatKind::ExpandedConstant

This commit is contained in:
Nadrieril 2025-03-29 13:55:05 +01:00
parent de57c0515d
commit 090d76497f
8 changed files with 32 additions and 51 deletions

View file

@ -812,23 +812,17 @@ pub enum PatKind<'tcx> {
},
/// Pattern obtained by converting a constant (inline or named) to its pattern
/// representation using `const_to_pat`.
/// representation using `const_to_pat`. This is used for unsafety checking.
ExpandedConstant {
/// [DefId] of the constant, we need this so that we have a
/// reference that can be used by unsafety checking to visit nested
/// unevaluated constants and for diagnostics. If the `DefId` doesn't
/// correspond to a local crate, it points at the `const` item.
/// [DefId] of the constant item.
def_id: DefId,
/// If `false`, then `def_id` points at a `const` item, otherwise it
/// corresponds to a local inline const.
is_inline: bool,
/// If the inline constant is used in a range pattern, this subpattern
/// represents the range (if both ends are inline constants, there will
/// be multiple InlineConstant wrappers).
/// The pattern that the constant lowered to.
///
/// Otherwise, the actual pattern that the constant lowered to. As with
/// other constants, inline constants are matched structurally where
/// possible.
/// HACK: we need to keep the `DefId` of inline constants around for unsafety checking;
/// therefore when a range pattern contains inline constants, we re-wrap the range pattern
/// with the `ExpandedConstant` nodes that correspond to the range endpoints. Hence
/// `subpattern` may actually be a range pattern, and `def_id` be the constant for one of
/// its endpoints.
subpattern: Box<Pat<'tcx>>,
},

View file

@ -145,7 +145,7 @@ impl<'a, 'tcx> ParseCtxt<'a, 'tcx> {
let arm = &self.thir[*arm];
let value = match arm.pattern.kind {
PatKind::Constant { value } => value,
PatKind::ExpandedConstant { ref subpattern, def_id: _, is_inline: false }
PatKind::ExpandedConstant { ref subpattern, def_id: _ }
if let PatKind::Constant { value } = subpattern.kind =>
{
value

View file

@ -1,5 +1,6 @@
use std::sync::Arc;
use rustc_hir::def::DefKind;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
@ -201,15 +202,13 @@ impl<'tcx> MatchPairTree<'tcx> {
None
}
PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
None
}
PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
PatKind::ExpandedConstant { subpattern: ref pattern, def_id } => {
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
// Apply a type ascription for the inline constant to the value at `match_pair.place`
if let Some(source) = place {
if let Some(source) = place
&& matches!(cx.tcx.def_kind(def_id), DefKind::InlineConst)
{
let span = pattern.span;
let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id());
let args = ty::InlineConstArgs::new(

View file

@ -403,9 +403,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
visit::walk_pat(self, pat);
self.inside_adt = old_inside_adt;
}
PatKind::ExpandedConstant { def_id, is_inline, .. } => {
PatKind::ExpandedConstant { def_id, .. } => {
if let Some(def) = def_id.as_local()
&& *is_inline
&& matches!(self.tcx.def_kind(def_id), DefKind::InlineConst)
{
self.visit_inner_body(def);
}

View file

@ -676,7 +676,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
unpeeled_pat = subpattern;
}
if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = unpeeled_pat.kind
if let PatKind::ExpandedConstant { def_id, .. } = unpeeled_pat.kind
&& let DefKind::Const = self.tcx.def_kind(def_id)
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(pat.span)
// We filter out paths with multiple path::segments.
@ -1296,7 +1296,8 @@ fn report_non_exhaustive_match<'p, 'tcx>(
for &arm in arms {
let arm = &thir.arms[arm];
if let PatKind::ExpandedConstant { def_id, is_inline: false, .. } = arm.pattern.kind
if let PatKind::ExpandedConstant { def_id, .. } = arm.pattern.kind
&& !matches!(cx.tcx.def_kind(def_id), DefKind::InlineConst)
&& let Ok(snippet) = cx.tcx.sess.source_map().span_to_snippet(arm.pattern.span)
// We filter out paths with multiple path::segments.
&& snippet.chars().all(|c| c.is_alphanumeric() || c == '_')

View file

@ -5,7 +5,6 @@ use rustc_apfloat::Float;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Diag;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_index::Idx;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::Obligation;
@ -185,11 +184,7 @@ impl<'tcx> ConstToPat<'tcx> {
// Wrap the pattern in a marker node to indicate that it is the result of lowering a
// constant. This is used for diagnostics, and for unsafety checking of inline const blocks.
let kind = PatKind::ExpandedConstant {
subpattern: inlined_const_as_pat,
def_id: uv.def,
is_inline: matches!(self.tcx.def_kind(uv.def), DefKind::InlineConst),
};
let kind = PatKind::ExpandedConstant { subpattern: inlined_const_as_pat, def_id: uv.def };
Box::new(Pat { kind, ty, span: self.span })
}

View file

@ -20,7 +20,7 @@ use rustc_middle::thir::{
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::LocalDefId;
use rustc_span::def_id::DefId;
use rustc_span::{ErrorGuaranteed, Span};
use tracing::{debug, instrument};
@ -124,7 +124,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
expr: Option<&'tcx hir::PatExpr<'tcx>>,
// Out-parameters collecting extra data to be reapplied by the caller
ascriptions: &mut Vec<Ascription<'tcx>>,
inline_consts: &mut Vec<LocalDefId>,
expanded_consts: &mut Vec<DefId>,
) -> Result<Option<PatRangeBoundary<'tcx>>, ErrorGuaranteed> {
let Some(expr) = expr else { return Ok(None) };
@ -139,10 +139,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
ascriptions.push(ascription);
kind = subpattern.kind;
}
PatKind::ExpandedConstant { is_inline, def_id, subpattern } => {
if is_inline {
inline_consts.extend(def_id.as_local());
}
PatKind::ExpandedConstant { def_id, subpattern } => {
expanded_consts.push(def_id);
kind = subpattern.kind;
}
_ => break,
@ -221,10 +219,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// Collect extra data while lowering the endpoints, to be reapplied later.
let mut ascriptions = vec![];
let mut inline_consts = vec![];
let mut expanded_consts = vec![];
let mut lower_endpoint =
|expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions, &mut inline_consts);
|expr| self.lower_pattern_range_endpoint(expr, &mut ascriptions, &mut expanded_consts);
let lo = lower_endpoint(lo_expr)?.unwrap_or(PatRangeBoundary::NegInfinity);
let hi = lower_endpoint(hi_expr)?.unwrap_or(PatRangeBoundary::PosInfinity);
@ -269,17 +267,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated
// constants somewhere. Have them on the range pattern.
for ascription in ascriptions {
kind = PatKind::AscribeUserType {
ascription,
subpattern: Box::new(Pat { span, ty, kind }),
};
let subpattern = Box::new(Pat { span, ty, kind });
kind = PatKind::AscribeUserType { ascription, subpattern };
}
for def in inline_consts {
kind = PatKind::ExpandedConstant {
def_id: def.to_def_id(),
is_inline: true,
subpattern: Box::new(Pat { span, ty, kind }),
};
for def_id in expanded_consts {
let subpattern = Box::new(Pat { span, ty, kind });
kind = PatKind::ExpandedConstant { def_id, subpattern };
}
Ok(kind)
}

View file

@ -740,10 +740,9 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);
}
PatKind::ExpandedConstant { def_id, is_inline, subpattern } => {
PatKind::ExpandedConstant { def_id, subpattern } => {
print_indented!(self, "ExpandedConstant {", depth_lvl + 1);
print_indented!(self, format!("def_id: {def_id:?}"), depth_lvl + 2);
print_indented!(self, format!("is_inline: {is_inline:?}"), depth_lvl + 2);
print_indented!(self, "subpattern:", depth_lvl + 2);
self.print_pat(subpattern, depth_lvl + 2);
print_indented!(self, "}", depth_lvl + 1);