rustc_middle/ty/
pattern.rs

1use std::fmt;
2
3use rustc_data_structures::intern::Interned;
4use rustc_macros::HashStable;
5use rustc_type_ir::ir_print::IrPrint;
6use rustc_type_ir::{
7    FlagComputation, Flags, {self as ir},
8};
9
10use super::TyCtxt;
11use crate::ty;
12
13pub type PatternKind<'tcx> = ir::PatternKind<TyCtxt<'tcx>>;
14
15#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)]
16#[rustc_pass_by_value]
17pub struct Pattern<'tcx>(pub Interned<'tcx, PatternKind<'tcx>>);
18
19impl<'tcx> Flags for Pattern<'tcx> {
20    fn flags(&self) -> rustc_type_ir::TypeFlags {
21        match &**self {
22            ty::PatternKind::Range { start, end } => {
23                FlagComputation::for_const_kind(&start.kind()).flags
24                    | FlagComputation::for_const_kind(&end.kind()).flags
25            }
26        }
27    }
28
29    fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
30        match &**self {
31            ty::PatternKind::Range { start, end } => {
32                start.outer_exclusive_binder().max(end.outer_exclusive_binder())
33            }
34        }
35    }
36}
37
38impl<'tcx> std::ops::Deref for Pattern<'tcx> {
39    type Target = PatternKind<'tcx>;
40
41    fn deref(&self) -> &Self::Target {
42        &*self.0
43    }
44}
45
46impl<'tcx> fmt::Debug for Pattern<'tcx> {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        write!(f, "{:?}", **self)
49    }
50}
51
52impl<'tcx> IrPrint<PatternKind<'tcx>> for TyCtxt<'tcx> {
53    fn print(t: &PatternKind<'tcx>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        match *t {
55            PatternKind::Range { start, end } => {
56                write!(f, "{start}")?;
57
58                if let Some(c) = end.try_to_value() {
59                    let end = c.valtree.unwrap_leaf();
60                    let size = end.size();
61                    let max = match c.ty.kind() {
62                        ty::Int(_) => {
63                            Some(ty::ScalarInt::truncate_from_int(size.signed_int_max(), size))
64                        }
65                        ty::Uint(_) => {
66                            Some(ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size))
67                        }
68                        ty::Char => Some(ty::ScalarInt::truncate_from_uint(char::MAX, size)),
69                        _ => None,
70                    };
71                    if let Some((max, _)) = max
72                        && end == max
73                    {
74                        return write!(f, "..");
75                    }
76                }
77
78                write!(f, "..={end}")
79            }
80        }
81    }
82
83    fn print_debug(t: &PatternKind<'tcx>, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
84        Self::print(t, fmt)
85    }
86}
87
88impl<'tcx> rustc_type_ir::inherent::IntoKind for Pattern<'tcx> {
89    type Kind = PatternKind<'tcx>;
90    fn kind(self) -> Self::Kind {
91        *self
92    }
93}