use crate::{common::SpanId, private::Sealed, span::Span};
use std::{fmt::Debug, marker::PhantomData};
mod ident_pat;
mod lit_pat;
mod or_pat;
mod path_pat;
mod place_pat;
mod range_pat;
mod ref_pat;
mod rest_pat;
mod slice_pat;
mod struct_pat;
mod tuple_pat;
mod unstable_pat;
mod wildcard_pat;
pub use ident_pat::*;
pub use lit_pat::*;
pub use or_pat::*;
pub use path_pat::*;
pub use place_pat::*;
pub use range_pat::*;
pub use ref_pat::*;
pub use rest_pat::*;
pub use slice_pat::*;
pub use struct_pat::*;
pub use tuple_pat::*;
pub use unstable_pat::*;
pub use wildcard_pat::*;
pub trait PatData<'ast>: Debug + Sealed {
fn span(&self) -> &Span<'ast>;
}
#[repr(C)]
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
pub enum PatKind<'ast> {
Ident(&'ast IdentPat<'ast>),
Wildcard(&'ast WildcardPat<'ast>),
Rest(&'ast RestPat<'ast>),
Ref(&'ast RefPat<'ast>),
Struct(&'ast StructPat<'ast>),
Tuple(&'ast TuplePat<'ast>),
Slice(&'ast SlicePat<'ast>),
Or(&'ast OrPat<'ast>),
Place(&'ast PlacePat<'ast>),
Lit(&'ast LitPat<'ast>),
Path(&'ast PathPat<'ast>),
Range(&'ast RangePat<'ast>),
Unstable(&'ast UnstablePat<'ast>),
}
impl<'ast> PatKind<'ast> {
impl_pat_data_fn!(span() -> &Span<'ast>);
}
macro_rules! impl_pat_data_fn {
($method:ident () -> $return_ty:ty) => {
impl_pat_data_fn!(
$method() -> $return_ty,
Ident, Wildcard, Rest, Ref, Struct, Tuple, Slice, Or, Place, Lit, Range, Path, Unstable
);
};
($method:ident () -> $return_ty:ty $(, $item:ident)+) => {
pub fn $method(&self) -> $return_ty {
match self {
$(PatKind::$item(data, ..) => data.$method(),)*
}
}
};
}
use impl_pat_data_fn;
#[repr(C)]
#[derive(Debug)]
#[cfg_attr(feature = "driver-api", visibility::make(pub))]
struct CommonPatData<'ast> {
_lifetime: PhantomData<&'ast ()>,
span: SpanId,
}
#[cfg(feature = "driver-api")]
impl<'ast> CommonPatData<'ast> {
pub fn new(span: SpanId) -> Self {
Self {
_lifetime: PhantomData,
span,
}
}
}
macro_rules! impl_pat_data {
($self_ty:ty, $enum_name:ident) => {
impl<'ast> super::PatData<'ast> for $self_ty {
fn span(&self) -> &crate::span::Span<'ast> {
$crate::context::with_cx(self, |cx| cx.span(self.data.span))
}
}
impl<'ast> From<&'ast $self_ty> for $crate::ast::pat::PatKind<'ast> {
fn from(from: &'ast $self_ty) -> Self {
$crate::ast::pat::PatKind::$enum_name(from)
}
}
impl<'ast> $crate::private::Sealed for $self_ty {}
};
}
use impl_pat_data;