Skip to main content

rustc_middle/ty/
pattern.rs

1use 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}