use std::fmt::Debug;
use std::marker::PhantomData;
mod args;
pub use args::*;
mod param;
pub use param::*;
use crate::{
common::{GenericId, SpanId, SymbolId},
context::with_cx,
ffi::{FfiOption, FfiSlice},
span::Span,
};
#[repr(C)]
#[derive(Debug)]
pub struct Lifetime<'ast> {
#[allow(clippy::struct_field_names)]
_lifetime: PhantomData<&'ast ()>,
span: FfiOption<SpanId>,
kind: LifetimeKind,
}
#[repr(C)]
#[derive(Debug)]
#[allow(clippy::exhaustive_enums)]
#[cfg_attr(feature = "driver-api", visibility::make(pub))]
pub(crate) enum LifetimeKind {
Label(SymbolId, GenericId),
Static,
Infer,
}
impl<'ast> Lifetime<'ast> {
pub fn id(&self) -> Option<GenericId> {
match self.kind {
LifetimeKind::Label(_, id) => Some(id),
_ => None,
}
}
pub fn label(&self) -> Option<&str> {
match self.kind {
LifetimeKind::Label(sym, _) => Some(with_cx(self, |cx| cx.symbol_str(sym))),
_ => None,
}
}
pub fn has_label(&self) -> bool {
matches!(self.kind, LifetimeKind::Label(..))
}
pub fn is_static(&self) -> bool {
matches!(self.kind, LifetimeKind::Static)
}
pub fn is_infer(&self) -> bool {
matches!(self.kind, LifetimeKind::Infer)
}
pub fn span(&self) -> Option<&Span<'ast>> {
self.span.get().map(|span| with_cx(self, |cx| cx.span(*span)))
}
}
#[cfg(feature = "driver-api")]
impl<'ast> Lifetime<'ast> {
pub fn new(span: Option<SpanId>, kind: LifetimeKind) -> Self {
Self {
_lifetime: PhantomData,
span: span.into(),
kind,
}
}
}
#[repr(C)]
#[derive(Debug)]
#[cfg_attr(feature = "driver-api", derive(Clone))]
pub struct GenericArgs<'ast> {
args: FfiSlice<'ast, GenericArgKind<'ast>>,
}
impl<'ast> GenericArgs<'ast> {
pub fn args(&self) -> &'ast [GenericArgKind<'ast>] {
self.args.get()
}
pub fn is_empty(&self) -> bool {
self.args.is_empty()
}
}
#[cfg(feature = "driver-api")]
impl<'ast> GenericArgs<'ast> {
pub fn new(args: &'ast [GenericArgKind<'ast>]) -> Self {
Self { args: args.into() }
}
}
#[repr(C)]
#[non_exhaustive]
#[derive(Debug)]
#[cfg_attr(feature = "driver-api", derive(Clone))]
pub enum GenericArgKind<'ast> {
Lifetime(&'ast LifetimeArg<'ast>),
Ty(&'ast TyArg<'ast>),
Binding(&'ast BindingArg<'ast>),
Const(&'ast ConstArg<'ast>),
}
#[repr(C)]
#[derive(Debug)]
pub struct GenericParams<'ast> {
params: FfiSlice<'ast, GenericParamKind<'ast>>,
clauses: FfiSlice<'ast, WhereClauseKind<'ast>>,
}
impl<'ast> GenericParams<'ast> {
pub fn params(&self) -> &'ast [GenericParamKind<'ast>] {
self.params.get()
}
pub fn clauses(&self) -> &'ast [WhereClauseKind<'ast>] {
self.clauses.get()
}
}
#[cfg(feature = "driver-api")]
impl<'ast> GenericParams<'ast> {
pub fn new(params: &'ast [GenericParamKind<'ast>], clauses: &'ast [WhereClauseKind<'ast>]) -> Self {
Self {
params: params.into(),
clauses: clauses.into(),
}
}
}