mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Initial plumbing for thir::PatExtra
This commit is contained in:
@@ -643,10 +643,26 @@ pub struct FieldPat<'tcx> {
|
||||
pub pattern: Pat<'tcx>,
|
||||
}
|
||||
|
||||
/// Additional per-node data that is not present on most THIR pattern nodes.
|
||||
#[derive(Clone, Debug, Default, HashStable, TypeVisitable)]
|
||||
pub struct PatExtra<'tcx> {
|
||||
/// If present, this node represents a named constant that was lowered to
|
||||
/// a pattern using `const_to_pat`.
|
||||
///
|
||||
/// This is used by some diagnostics for non-exhaustive matches, to map
|
||||
/// the pattern node back to the `DefId` of its original constant.
|
||||
pub expanded_const: Option<DefId>,
|
||||
|
||||
/// User-written types that must be preserved into MIR so that they can be
|
||||
/// checked.
|
||||
pub ascriptions: Vec<Ascription<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, HashStable, TypeVisitable)]
|
||||
pub struct Pat<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
pub span: Span,
|
||||
pub extra: Option<Box<PatExtra<'tcx>>>,
|
||||
pub kind: PatKind<'tcx>,
|
||||
}
|
||||
|
||||
@@ -1119,7 +1135,7 @@ mod size_asserts {
|
||||
static_assert_size!(Block, 48);
|
||||
static_assert_size!(Expr<'_>, 64);
|
||||
static_assert_size!(ExprKind<'_>, 40);
|
||||
static_assert_size!(Pat<'_>, 64);
|
||||
static_assert_size!(Pat<'_>, 72);
|
||||
static_assert_size!(PatKind<'_>, 48);
|
||||
static_assert_size!(Stmt<'_>, 48);
|
||||
static_assert_size!(StmtKind<'_>, 48);
|
||||
|
||||
@@ -259,7 +259,7 @@ pub(crate) fn for_each_immediate_subpat<'a, 'tcx>(
|
||||
pat: &'a Pat<'tcx>,
|
||||
mut callback: impl FnMut(&'a Pat<'tcx>),
|
||||
) {
|
||||
let Pat { kind, ty: _, span: _ } = pat;
|
||||
let Pat { kind, ty: _, span: _, extra: _ } = pat;
|
||||
match kind {
|
||||
PatKind::Missing
|
||||
| PatKind::Wild
|
||||
|
||||
@@ -90,7 +90,7 @@ fn mk_err(&self, mut err: Diag<'_>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
|
||||
);
|
||||
}
|
||||
}
|
||||
Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()) })
|
||||
Box::new(Pat { span: self.span, ty, kind: PatKind::Error(err.emit()), extra: None })
|
||||
}
|
||||
|
||||
fn unevaluated_to_pat(
|
||||
@@ -192,6 +192,7 @@ fn unevaluated_to_pat(
|
||||
ty: thir_pat.ty,
|
||||
span: thir_pat.span,
|
||||
kind: PatKind::ExpandedConstant { def_id: uv.def, subpattern: thir_pat },
|
||||
extra: None,
|
||||
});
|
||||
thir_pat
|
||||
}
|
||||
@@ -355,7 +356,7 @@ fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
|
||||
}
|
||||
};
|
||||
|
||||
Box::new(Pat { span, ty, kind })
|
||||
Box::new(Pat { span, ty, kind, extra: None })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ pub(super) fn pat_from_hir<'tcx>(
|
||||
ascription: Ascription { annotation, variance: ty::Covariant },
|
||||
subpattern: thir_pat,
|
||||
},
|
||||
extra: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
||||
}
|
||||
PatAdjust::PinDeref => PatKind::Deref { subpattern: thir_pat },
|
||||
};
|
||||
Box::new(Pat { span, ty: adjust.source, kind })
|
||||
Box::new(Pat { span, ty: adjust.source, kind, extra: None })
|
||||
});
|
||||
|
||||
if let Some(s) = &mut self.rust_2024_migration
|
||||
@@ -307,7 +308,7 @@ fn lower_pattern_range(
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
let mut thir_pat = Box::new(Pat { ty, span, kind });
|
||||
let mut thir_pat = Box::new(Pat { ty, span, kind, extra: None });
|
||||
|
||||
// If we are handling a range with associated constants (e.g.
|
||||
// `Foo::<'a>::A..=Foo::B`), we need to put the ascriptions for the associated
|
||||
@@ -317,6 +318,7 @@ fn lower_pattern_range(
|
||||
ty,
|
||||
span,
|
||||
kind: PatKind::AscribeUserType { ascription, subpattern: thir_pat },
|
||||
extra: None,
|
||||
});
|
||||
}
|
||||
// `PatKind::ExpandedConstant` wrappers from range endpoints used to
|
||||
@@ -428,7 +430,7 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tc
|
||||
};
|
||||
// We might have modified the type or span, so use the modified
|
||||
// values in the THIR pattern node.
|
||||
return Box::new(Pat { ty: thir_pat_ty, span: thir_pat_span, kind });
|
||||
return Box::new(Pat { ty: thir_pat_ty, span: thir_pat_span, kind, extra: None });
|
||||
}
|
||||
|
||||
hir::PatKind::TupleStruct(ref qpath, pats, ddpos) => {
|
||||
@@ -468,7 +470,7 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tc
|
||||
|
||||
// For pattern kinds that haven't already returned, create a `thir::Pat`
|
||||
// with the HIR pattern node's type and span.
|
||||
Box::new(Pat { span, ty, kind })
|
||||
Box::new(Pat { span, ty, kind, extra: None })
|
||||
}
|
||||
|
||||
fn lower_tuple_subpats(
|
||||
@@ -520,7 +522,7 @@ fn slice_or_array_pattern(
|
||||
}
|
||||
_ => span_bug!(span, "bad slice pattern type {ty:?}"),
|
||||
};
|
||||
Box::new(Pat { ty, span, kind })
|
||||
Box::new(Pat { ty, span, kind, extra: None })
|
||||
}
|
||||
|
||||
fn lower_variant_or_leaf(
|
||||
@@ -562,7 +564,12 @@ fn lower_variant_or_leaf(
|
||||
ty::Adt(_, args) | ty::FnDef(_, args) => args,
|
||||
ty::Error(e) => {
|
||||
// Avoid ICE (#50585)
|
||||
return Box::new(Pat { ty, span, kind: PatKind::Error(*e) });
|
||||
return Box::new(Pat {
|
||||
ty,
|
||||
span,
|
||||
kind: PatKind::Error(*e),
|
||||
extra: None,
|
||||
});
|
||||
}
|
||||
_ => bug!("inappropriate type for def: {:?}", ty),
|
||||
};
|
||||
@@ -603,7 +610,7 @@ fn lower_variant_or_leaf(
|
||||
PatKind::Error(e)
|
||||
}
|
||||
};
|
||||
let mut thir_pat = Box::new(Pat { ty, span, kind });
|
||||
let mut thir_pat = Box::new(Pat { ty, span, kind, extra: None });
|
||||
|
||||
if let Some(user_ty) = self.user_args_applied_to_ty_of_hir_id(hir_id) {
|
||||
debug!(?thir_pat, ?user_ty, ?span, "lower_variant_or_leaf: applying ascription");
|
||||
@@ -619,6 +626,7 @@ fn lower_variant_or_leaf(
|
||||
subpattern: thir_pat,
|
||||
ascription: Ascription { annotation, variance: ty::Covariant },
|
||||
},
|
||||
extra: None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -685,7 +693,7 @@ fn lower_path(
|
||||
variance: ty::Contravariant,
|
||||
},
|
||||
};
|
||||
pattern = Box::new(Pat { span, kind, ty });
|
||||
pattern = Box::new(Pat { span, kind, ty, extra: None });
|
||||
}
|
||||
|
||||
pattern
|
||||
|
||||
@@ -73,6 +73,24 @@ fn into_buffer(self) -> String {
|
||||
self.fmt
|
||||
}
|
||||
|
||||
fn print_list<T>(
|
||||
&mut self,
|
||||
label: &str,
|
||||
list: &[T],
|
||||
depth_lvl: usize,
|
||||
print_fn: impl Fn(&mut Self, &T, usize),
|
||||
) {
|
||||
if list.is_empty() {
|
||||
print_indented!(self, format_args!("{label}: []"), depth_lvl);
|
||||
} else {
|
||||
print_indented!(self, format_args!("{label}: ["), depth_lvl);
|
||||
for item in list {
|
||||
print_fn(self, item, depth_lvl + 1)
|
||||
}
|
||||
print_indented!(self, "]", depth_lvl);
|
||||
}
|
||||
}
|
||||
|
||||
fn print_param(&mut self, param: &Param<'tcx>, depth_lvl: usize) {
|
||||
let Param { pat, ty, ty_span, self_kind, hir_id } = param;
|
||||
|
||||
@@ -663,15 +681,37 @@ fn print_arm(&mut self, arm_id: ArmId, depth_lvl: usize) {
|
||||
}
|
||||
|
||||
fn print_pat(&mut self, pat: &Pat<'tcx>, depth_lvl: usize) {
|
||||
let &Pat { ty, span, ref kind } = pat;
|
||||
let &Pat { ty, span, ref kind, ref extra } = pat;
|
||||
|
||||
print_indented!(self, "Pat: {", depth_lvl);
|
||||
print_indented!(self, format!("ty: {:?}", ty), depth_lvl + 1);
|
||||
print_indented!(self, format!("span: {:?}", span), depth_lvl + 1);
|
||||
self.print_pat_extra(extra.as_deref(), depth_lvl + 1);
|
||||
self.print_pat_kind(kind, depth_lvl + 1);
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
|
||||
fn print_pat_extra(&mut self, extra: Option<&PatExtra<'tcx>>, depth_lvl: usize) {
|
||||
let Some(extra) = extra else {
|
||||
// Skip printing in the common case of a pattern node with no extra data.
|
||||
return;
|
||||
};
|
||||
|
||||
let PatExtra { expanded_const, ascriptions } = extra;
|
||||
|
||||
print_indented!(self, "extra: PatExtra {", depth_lvl);
|
||||
print_indented!(self, format_args!("expanded_const: {expanded_const:?}"), depth_lvl + 1);
|
||||
self.print_list(
|
||||
"ascriptions",
|
||||
ascriptions,
|
||||
depth_lvl + 1,
|
||||
|this, ascription, depth_lvl| {
|
||||
print_indented!(this, format_args!("{ascription:?}"), depth_lvl);
|
||||
},
|
||||
);
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
|
||||
fn print_pat_kind(&mut self, pat_kind: &PatKind<'tcx>, depth_lvl: usize) {
|
||||
print_indented!(self, "kind: PatKind {", depth_lvl);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user