rustc_middle/ty/
pattern.rs1use std::fmt;
2
3use rustc_data_structures::intern::Interned;
4use rustc_macros::StableHash;
5use rustc_type_ir::ir_print::IrPrint;
6use rustc_type_ir::{self as ir, FlagComputation, Flags};
7
8use super::TyCtxt;
9use crate::ty;
10use crate::ty::consts::ConstExt;
11
12pub type PatternKind<'tcx> = ir::PatternKind<TyCtxt<'tcx>>;
13
14#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for Pattern<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for Pattern<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for Pattern<'tcx> {
#[inline]
fn clone(&self) -> Self {
let _:
::core::clone::AssertParamIsClone<Interned<'tcx,
PatternKind<'tcx>>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::StructuralPartialEq for Pattern<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for Pattern<'tcx> {
#[inline]
fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for Pattern<'tcx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _:
::core::cmp::AssertParamIsEq<Interned<'tcx,
PatternKind<'tcx>>>;
}
}Eq, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for Pattern<'tcx> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, const _: () =
{
impl<'tcx> ::rustc_data_structures::stable_hash::StableHash for
Pattern<'tcx> {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
Pattern(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
15#[rustc_pass_by_value]
16pub struct Pattern<'tcx>(pub Interned<'tcx, PatternKind<'tcx>>);
17
18impl<'tcx> Flags for Pattern<'tcx> {
19 fn flags(&self) -> rustc_type_ir::TypeFlags {
20 match &**self {
21 ty::PatternKind::Range { start, end } => {
22 FlagComputation::for_const_kind(&start.kind()).flags
23 | FlagComputation::for_const_kind(&end.kind()).flags
24 }
25 ty::PatternKind::Or(pats) => {
26 let mut flags = pats[0].flags();
27 for pat in pats[1..].iter() {
28 flags |= pat.flags();
29 }
30 flags
31 }
32 ty::PatternKind::NotNull => rustc_type_ir::TypeFlags::empty(),
33 }
34 }
35
36 fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
37 match &**self {
38 ty::PatternKind::Range { start, end } => {
39 start.outer_exclusive_binder().max(end.outer_exclusive_binder())
40 }
41 ty::PatternKind::Or(pats) => {
42 let mut idx = pats[0].outer_exclusive_binder();
43 for pat in pats[1..].iter() {
44 idx = idx.max(pat.outer_exclusive_binder());
45 }
46 idx
47 }
48 ty::PatternKind::NotNull => rustc_type_ir::INNERMOST,
49 }
50 }
51}
52
53impl<'tcx> std::ops::Deref for Pattern<'tcx> {
54 type Target = PatternKind<'tcx>;
55
56 fn deref(&self) -> &Self::Target {
57 &*self.0
58 }
59}
60
61impl<'tcx> fmt::Debug for Pattern<'tcx> {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 f.write_fmt(format_args!("{0:?}", **self))write!(f, "{:?}", **self)
64 }
65}
66
67impl<'tcx> IrPrint<PatternKind<'tcx>> for TyCtxt<'tcx> {
68 fn print(t: &PatternKind<'tcx>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 match *t {
70 PatternKind::Range { start, end } => {
71 f.write_fmt(format_args!("{0}", start))write!(f, "{start}")?;
72
73 if let Some(c) = end.try_to_value() {
74 let end = c.to_leaf();
75 let size = end.size();
76 let max = match c.ty.kind() {
77 ty::Int(_) => {
78 Some(ty::ScalarInt::truncate_from_int(size.signed_int_max(), size))
79 }
80 ty::Uint(_) => {
81 Some(ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size))
82 }
83 ty::Char => Some(ty::ScalarInt::truncate_from_uint(char::MAX, size)),
84 _ => None,
85 };
86 if let Some((max, _)) = max
87 && end == max
88 {
89 return f.write_fmt(format_args!(".."))write!(f, "..");
90 }
91 }
92
93 f.write_fmt(format_args!("..={0}", end))write!(f, "..={end}")
94 }
95 PatternKind::NotNull => f.write_fmt(format_args!("!null"))write!(f, "!null"),
96 PatternKind::Or(patterns) => {
97 f.write_fmt(format_args!("("))write!(f, "(")?;
98 let mut first = true;
99 for pat in patterns {
100 if first {
101 first = false
102 } else {
103 f.write_fmt(format_args!(" | "))write!(f, " | ")?;
104 }
105 f.write_fmt(format_args!("{0:?}", pat))write!(f, "{pat:?}")?;
106 }
107 f.write_fmt(format_args!(")"))write!(f, ")")
108 }
109 }
110 }
111
112 fn print_debug(t: &PatternKind<'tcx>, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
113 Self::print(t, fmt)
114 }
115}
116
117impl<'tcx> rustc_type_ir::inherent::IntoKind for Pattern<'tcx> {
118 type Kind = PatternKind<'tcx>;
119 fn kind(self) -> Self::Kind {
120 *self
121 }
122}