Skip to main content

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