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::{
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(#[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> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_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_query_system::ich::StableHashingContext<'__ctx>>
            for Pattern<'tcx> {
            #[inline]
            fn hash_stable(&self,
                __hcx:
                    &mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
                __hasher:
                    &mut ::rustc_data_structures::stable_hasher::StableHasher) {
                match *self {
                    Pattern(ref __binding_0) => {
                        { __binding_0.hash_stable(__hcx, __hasher); }
                    }
                }
            }
        }
    };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            ty::PatternKind::Or(pats) => {
27                let mut flags = pats[0].flags();
28                for pat in pats[1..].iter() {
29                    flags |= pat.flags();
30                }
31                flags
32            }
33            ty::PatternKind::NotNull => rustc_type_ir::TypeFlags::empty(),
34        }
35    }
36
37    fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
38        match &**self {
39            ty::PatternKind::Range { start, end } => {
40                start.outer_exclusive_binder().max(end.outer_exclusive_binder())
41            }
42            ty::PatternKind::Or(pats) => {
43                let mut idx = pats[0].outer_exclusive_binder();
44                for pat in pats[1..].iter() {
45                    idx = idx.max(pat.outer_exclusive_binder());
46                }
47                idx
48            }
49            ty::PatternKind::NotNull => rustc_type_ir::INNERMOST,
50        }
51    }
52}
53
54impl<'tcx> std::ops::Deref for Pattern<'tcx> {
55    type Target = PatternKind<'tcx>;
56
57    fn deref(&self) -> &Self::Target {
58        &*self.0
59    }
60}
61
62impl<'tcx> fmt::Debug for Pattern<'tcx> {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        f.write_fmt(format_args!("{0:?}", **self))write!(f, "{:?}", **self)
65    }
66}
67
68impl<'tcx> IrPrint<PatternKind<'tcx>> for TyCtxt<'tcx> {
69    fn print(t: &PatternKind<'tcx>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        match *t {
71            PatternKind::Range { start, end } => {
72                f.write_fmt(format_args!("{0}", start))write!(f, "{start}")?;
73
74                if let Some(c) = end.try_to_value() {
75                    let end = c.to_leaf();
76                    let size = end.size();
77                    let max = match c.ty.kind() {
78                        ty::Int(_) => {
79                            Some(ty::ScalarInt::truncate_from_int(size.signed_int_max(), size))
80                        }
81                        ty::Uint(_) => {
82                            Some(ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size))
83                        }
84                        ty::Char => Some(ty::ScalarInt::truncate_from_uint(char::MAX, size)),
85                        _ => None,
86                    };
87                    if let Some((max, _)) = max
88                        && end == max
89                    {
90                        return f.write_fmt(format_args!(".."))write!(f, "..");
91                    }
92                }
93
94                f.write_fmt(format_args!("..={0}", end))write!(f, "..={end}")
95            }
96            PatternKind::NotNull => f.write_fmt(format_args!("!null"))write!(f, "!null"),
97            PatternKind::Or(patterns) => {
98                f.write_fmt(format_args!("("))write!(f, "(")?;
99                let mut first = true;
100                for pat in patterns {
101                    if first {
102                        first = false
103                    } else {
104                        f.write_fmt(format_args!(" | "))write!(f, " | ")?;
105                    }
106                    f.write_fmt(format_args!("{0:?}", pat))write!(f, "{pat:?}")?;
107                }
108                f.write_fmt(format_args!(")"))write!(f, ")")
109            }
110        }
111    }
112
113    fn print_debug(t: &PatternKind<'tcx>, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
114        Self::print(t, fmt)
115    }
116}
117
118impl<'tcx> rustc_type_ir::inherent::IntoKind for Pattern<'tcx> {
119    type Kind = PatternKind<'tcx>;
120    fn kind(self) -> Self::Kind {
121        *self
122    }
123}