1use crate::{
42 arg_err_noloc,
43 combine::{Parser, parser},
44 common_traits::Verify,
45 context::{Context, collect_deduped_interface_verifiers},
46 dialect::{Dialect, DialectName},
47 identifier::Identifier,
48 impl_printable_for_display, input_err,
49 irfmt::parsers::spaced,
50 parsable::{IntoParseResult, Parsable, ParseResult, StateStream, StreamLocation},
51 printable::{self, Printable},
52 result::{Error, Result},
53 std_deps::sync::LazyLock,
54 storage_uniquer::TypeValueHash,
55 utils::{table::HMap, trait_cast::impls_trait_static},
56};
57
58use alloc::{
59 boxed::Box,
60 string::{String, ToString},
61 vec::Vec,
62};
63use core::{
64 cell::{Ref, RefCell, RefMut},
65 fmt::{Debug, Display},
66 hash::{Hash, Hasher},
67 marker::PhantomData,
68};
69use downcast_rs::{Downcast, impl_downcast};
70use pliron_derive::format;
71use thiserror::Error;
72
73pub trait Type: Printable + Verify + Downcast + Sync + Send + Debug {
102 fn hash_type(&self) -> TypeValueHash;
105 fn eq_type(&self, other: &dyn Type) -> bool;
107
108 fn get_self_handle(&self, ctx: &Context) -> TypeHandle {
112 let is = |other: &TypeObj| self.eq_type(&**other.0.borrow());
113 let idx = ctx
114 .type_store
115 .get(self.hash_type(), &is)
116 .expect("Unregistered type object in existence");
117 TypeHandle(idx)
118 }
119
120 fn instantiate(t: Self, ctx: &Context) -> TypedHandle<Self>
122 where
123 Self: Sized,
124 {
125 let hash = t.hash_type();
126 let idx = ctx.type_store.get_or_create_unique(
127 TypeObj(RefCell::new(Box::new(t))),
128 hash,
129 &TypeObj::eq,
130 );
131 TypedHandle(TypeHandle(idx), PhantomData::<Self>)
132 }
133
134 fn get_type_id(&self) -> TypeId;
138
139 fn get_type_id_static() -> TypeId
141 where
142 Self: Sized;
143
144 #[doc(hidden)]
145 fn verify_interfaces(&self, ctx: &Context) -> Result<()>;
147
148 fn register(ctx: &mut Context)
150 where
151 Self: Sized + Parsable<Arg = (), Parsed = TypedHandle<Self>>,
152 {
153 let ptr_parser: TypeParserFn = |parsable_state, &()| {
154 Self::parse(parsable_state, ())
155 .map(|(typtr, r)| -> (TypeHandle, _) { (typtr.to_handle(), r) })
156 };
157 let typeid = Self::get_type_id_static();
158 Dialect::register(ctx, &typeid.dialect.clone()).add_type(typeid, ptr_parser);
159 }
160}
161impl_downcast!(Type);
162
163pub(crate) type TypeParserFn =
166 for<'a> fn(&mut StateStream<'a>, &'a ()) -> ParseResult<'a, TypeHandle>;
167
168pub trait Typed {
170 fn get_type(&self, ctx: &Context) -> TypeHandle;
172}
173
174impl Typed for TypeHandle {
175 fn get_type(&self, _ctx: &Context) -> TypeHandle {
176 *self
177 }
178}
179
180impl Typed for dyn Type {
181 fn get_type(&self, ctx: &Context) -> TypeHandle {
182 self.get_self_handle(ctx)
183 }
184}
185
186impl<T: Typed + ?Sized> Typed for &T {
187 fn get_type(&self, ctx: &Context) -> TypeHandle {
188 (*self).get_type(ctx)
189 }
190}
191
192impl<T: Typed + ?Sized> Typed for &mut T {
193 fn get_type(&self, ctx: &Context) -> TypeHandle {
194 (**self).get_type(ctx)
195 }
196}
197
198impl<T: Typed + ?Sized> Typed for Box<T> {
199 fn get_type(&self, ctx: &Context) -> TypeHandle {
200 (**self).get_type(ctx)
201 }
202}
203
204#[derive(Clone, Hash, PartialEq, Eq)]
205pub struct TypeName(Identifier);
207
208impl TypeName {
209 pub fn try_new(name: &str) -> Result<TypeName> {
211 Identifier::try_from(name).map(TypeName)
212 }
213}
214
215impl From<Identifier> for TypeName {
216 fn from(name: Identifier) -> Self {
217 TypeName(name)
218 }
219}
220
221impl From<TypeName> for Identifier {
222 fn from(name: TypeName) -> Self {
223 name.0
224 }
225}
226
227impl TryFrom<&str> for TypeName {
228 type Error = Error;
229
230 fn try_from(value: &str) -> Result<Self> {
231 Identifier::try_from(value).map(TypeName)
232 }
233}
234
235impl TryFrom<String> for TypeName {
236 type Error = Error;
237
238 fn try_from(value: String) -> Result<Self> {
239 Identifier::try_from(value).map(TypeName)
240 }
241}
242
243impl AsRef<str> for TypeName {
244 fn as_ref(&self) -> &str {
245 self.0.as_ref()
246 }
247}
248
249impl AsRef<Identifier> for TypeName {
250 fn as_ref(&self) -> &Identifier {
251 &self.0
252 }
253}
254
255impl_printable_for_display!(TypeName);
256
257impl Display for TypeName {
258 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
259 write!(f, "{}", self.0)
260 }
261}
262
263impl Parsable for TypeName {
264 type Arg = ();
265 type Parsed = TypeName;
266
267 fn parse<'a>(
268 state_stream: &mut crate::parsable::StateStream<'a>,
269 _arg: Self::Arg,
270 ) -> ParseResult<'a, Self::Parsed>
271 where
272 Self: Sized,
273 {
274 Identifier::parser(())
275 .map(TypeName)
276 .parse_stream(state_stream)
277 .into()
278 }
279}
280
281#[derive(Clone, Hash, PartialEq, Eq)]
283pub struct TypeId {
284 pub dialect: DialectName,
285 pub name: TypeName,
286}
287
288impl Parsable for TypeId {
289 type Arg = ();
290 type Parsed = TypeId;
291
292 fn parse<'a>(
294 state_stream: &mut StateStream<'a>,
295 _arg: Self::Arg,
296 ) -> ParseResult<'a, Self::Parsed>
297 where
298 Self: Sized,
299 {
300 let mut parser = DialectName::parser(())
301 .skip(parser::char::char('.'))
302 .and(TypeName::parser(()))
303 .map(|(dialect, name)| TypeId { dialect, name });
304 parser.parse_stream(state_stream).into()
305 }
306}
307
308impl_printable_for_display!(TypeId);
309
310impl Display for TypeId {
311 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
312 write!(f, "{}.{}", self.dialect, self.name)
313 }
314}
315
316pub(crate) struct TypeObj(RefCell<Box<dyn Type>>);
318
319impl PartialEq for TypeObj {
320 fn eq(&self, other: &Self) -> bool {
321 self.0.borrow().eq_type(&**other.0.borrow())
322 }
323}
324
325impl Eq for TypeObj {}
326
327impl Hash for TypeObj {
328 fn hash<H: Hasher>(&self, state: &mut H) {
329 state.write(&u64::from(self.0.borrow().hash_type()).to_ne_bytes())
330 }
331}
332
333#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
335pub struct TypeHandle(usize);
336
337impl TypeHandle {
338 pub fn deref<'a>(&self, ctx: &'a Context) -> Ref<'a, dyn Type> {
340 Ref::map(
341 ctx.type_store.unique_store.get(self.0).unwrap().0.borrow(),
342 |t| &**t,
343 )
344 }
345
346 pub fn deref_mut<'a>(&self, ctx: &'a Context) -> RefMut<'a, dyn Type> {
350 RefMut::map(
351 ctx.type_store
352 .unique_store
353 .get(self.0)
354 .unwrap()
355 .0
356 .borrow_mut(),
357 |t| &mut **t,
358 )
359 }
360}
361
362impl Printable for TypeHandle {
363 fn fmt(
364 &self,
365 ctx: &Context,
366 state: &printable::State,
367 f: &mut core::fmt::Formatter<'_>,
368 ) -> core::fmt::Result {
369 write!(f, "{} ", self.deref(ctx).get_type_id())?;
370 Printable::fmt(&*self.deref(ctx), ctx, state, f)
371 }
372}
373
374impl Verify for TypeHandle {
375 fn verify(&self, ctx: &Context) -> Result<()> {
376 verify_type(&*self.deref(ctx), ctx)
377 }
378}
379
380impl Parsable for TypeHandle {
381 type Arg = ();
382 type Parsed = Self;
383
384 fn parse<'a>(
385 state_stream: &mut StateStream<'a>,
386 _arg: Self::Arg,
387 ) -> ParseResult<'a, Self::Parsed> {
388 let loc = state_stream.loc();
389 let type_id_parser = spaced(TypeId::parser(()));
390
391 let mut type_parser = type_id_parser.then(move |type_id: TypeId| {
392 let loc = loc.clone();
394 combine::parser(move |parsable_state: &mut StateStream<'a>| {
395 let state = &parsable_state.state;
396 let dialect = state
397 .ctx
398 .dialects
399 .get(&type_id.dialect)
400 .expect("Dialect name parsed but dialect isn't registered");
401 let Some(type_parser) = dialect.types.get(&type_id) else {
402 input_err!(loc.clone(), "Unregistered type {}", type_id.disp(state.ctx))?
403 };
404 type_parser(parsable_state, &())
405 })
406 });
407
408 type_parser.parse_stream(state_stream).into_result()
409 }
410}
411
412pub fn verify_type(ty: &dyn Type, ctx: &Context) -> Result<()> {
416 ty.verify_interfaces(ctx)?;
418
419 Verify::verify(ty, ctx)
421}
422
423impl Verify for TypeObj {
424 fn verify(&self, ctx: &Context) -> Result<()> {
425 verify_type(self.0.borrow().as_ref(), ctx)
426 }
427}
428
429#[derive(Debug)]
431pub struct TypedHandle<T: Type>(TypeHandle, PhantomData<T>);
432
433#[derive(Error, Debug)]
434#[error("TypedHandle mismatch: expected {expected} but provided {provided}")]
435pub struct TypedHandleErr {
436 pub expected: String,
437 pub provided: String,
438}
439
440impl<T: Type> TypedHandle<T> {
441 pub fn deref<'a>(&self, ctx: &'a Context) -> Ref<'a, T> {
443 Ref::map(self.0.deref(ctx), |t| {
444 t.downcast_ref::<T>()
445 .expect("Type mistmatch, inconsistent TypedHandle")
446 })
447 }
448
449 pub fn from_handle(handle: TypeHandle, ctx: &Context) -> Result<TypedHandle<T>> {
451 if handle.deref(ctx).is::<T>() {
452 Ok(TypedHandle(handle, PhantomData::<T>))
453 } else {
454 arg_err_noloc!(TypedHandleErr {
455 expected: T::get_type_id_static().disp(ctx).to_string(),
456 provided: handle.disp(ctx).to_string()
457 })
458 }
459 }
460
461 pub fn to_handle(&self) -> TypeHandle {
463 self.0
464 }
465}
466
467impl<T: Type> From<TypedHandle<T>> for TypeHandle {
468 fn from(value: TypedHandle<T>) -> Self {
469 value.to_handle()
470 }
471}
472
473impl<T: Type> Clone for TypedHandle<T> {
474 fn clone(&self) -> TypedHandle<T> {
475 *self
476 }
477}
478
479impl<T: Type> Copy for TypedHandle<T> {}
480
481impl<T: Type> PartialEq for TypedHandle<T> {
482 fn eq(&self, other: &Self) -> bool {
483 self.0 == other.0
484 }
485}
486
487impl<T: Type> Eq for TypedHandle<T> {}
488
489impl<T: Type> Hash for TypedHandle<T> {
490 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
491 self.0.hash(state);
492 }
493}
494
495impl<T: Type> Printable for TypedHandle<T> {
496 fn fmt(
497 &self,
498 ctx: &Context,
499 state: &printable::State,
500 f: &mut core::fmt::Formatter<'_>,
501 ) -> core::fmt::Result {
502 Printable::fmt(&self.0, ctx, state, f)
503 }
504}
505
506impl<T: Type + Parsable<Arg = (), Parsed = TypedHandle<T>>> Parsable for TypedHandle<T> {
507 type Arg = ();
508 type Parsed = Self;
509
510 fn parse<'a>(
511 state_stream: &mut StateStream<'a>,
512 arg: Self::Arg,
513 ) -> ParseResult<'a, Self::Parsed> {
514 let loc = state_stream.loc();
515 spaced(TypeId::parser(()))
516 .then(move |type_id| {
517 let loc = loc.clone();
518 combine::parser(move |parsable_state: &mut StateStream<'a>| {
519 if type_id != T::get_type_id_static() {
520 let ctx = &*parsable_state.state.ctx;
521 input_err!(
522 loc.clone(),
523 TypedHandleErr {
524 expected: T::get_type_id_static().disp(ctx).to_string(),
525 provided: type_id.disp(ctx).to_string()
526 }
527 )?
528 }
529 T::parser(arg).parse_stream(parsable_state).into()
530 })
531 })
532 .parse_stream(state_stream)
533 .into_result()
534 }
535}
536
537impl<T: Type> Verify for TypedHandle<T> {
538 fn verify(&self, ctx: &Context) -> Result<()> {
539 self.0.deref(ctx).verify(ctx)
540 }
541}
542
543#[diagnostic::on_unimplemented(
548 message = "`{Self}` not a type interface.",
549 label = "If `{Self}` is a trait, annotate it with #[type_interface] to be able to cast to it from a `&dyn Type`",
550 note = "If you want to cast to a concrete `Type`, use `downcast_ref` instead."
551)]
552pub trait TypeInterfaceMarker {}
553
554pub fn type_cast<T: ?Sized + TypeInterfaceMarker + 'static>(ty: &dyn Type) -> Option<&T> {
578 crate::utils::trait_cast::any_to_trait::<T>(ty.as_any())
579}
580
581pub fn type_impls<T: ?Sized + TypeInterfaceMarker + 'static>(ty: &dyn Type) -> bool {
603 type_cast::<T>(ty).is_some()
604}
605
606pub fn type_impls_static<T: Type, I: ?Sized + TypeInterfaceMarker + 'static>() -> bool {
618 impls_trait_static::<T, I>()
619}
620
621pub struct TypeInterfaceHandle<I: ?Sized + TypeInterfaceMarker + 'static>(
637 TypeHandle,
638 PhantomData<I>,
639);
640
641#[derive(Error, Debug)]
642#[error("TypeInterfaceHandle mismatch: {provided} does not implement interface {interface}")]
643pub struct TypeInterfaceHandleErr {
644 pub interface: String,
645 pub provided: String,
646}
647
648#[diagnostic::on_unimplemented(
671 message = "`{Self}` does not implement the type interface `{I}`.",
672 label = "Annotate `{Self}`'s implementation of this interface with #[type_interface_impl]",
673 note = "Use `TypeInterfaceHandle::from_handle` to check this at run time instead."
674)]
675pub trait TypeImplsInterface<I: ?Sized + TypeInterfaceMarker + 'static>: Type {}
676
677impl<I: ?Sized + TypeInterfaceMarker + 'static> TypeInterfaceHandle<I> {
678 pub fn deref<'a>(&self, ctx: &'a Context) -> Ref<'a, I> {
680 Ref::map(self.0.deref(ctx), |ty| {
681 type_cast::<I>(ty).expect("Interface mismatch, inconsistent TypeInterfaceHandle")
682 })
683 }
684
685 pub fn from_handle(handle: TypeHandle, ctx: &Context) -> Result<TypeInterfaceHandle<I>> {
687 if type_impls::<I>(&*handle.deref(ctx)) {
688 Ok(TypeInterfaceHandle(handle, PhantomData::<I>))
689 } else {
690 arg_err_noloc!(TypeInterfaceHandleErr {
691 interface: core::any::type_name::<I>().to_string(),
692 provided: handle.disp(ctx).to_string()
693 })
694 }
695 }
696
697 pub fn to_handle(&self) -> TypeHandle {
699 self.0
700 }
701}
702
703impl<T: TypeImplsInterface<I>, I: ?Sized + TypeInterfaceMarker + 'static> From<TypedHandle<T>>
704 for TypeInterfaceHandle<I>
705{
706 fn from(value: TypedHandle<T>) -> Self {
707 assert!(
708 type_impls_static::<T, I>(),
709 "{} does not implement interface {}. \
710 Use the `type_interface_impl` macro",
711 core::any::type_name::<T>(),
712 core::any::type_name::<I>()
713 );
714 TypeInterfaceHandle(value.to_handle(), PhantomData::<I>)
715 }
716}
717
718impl<I: ?Sized + TypeInterfaceMarker + 'static> From<TypeInterfaceHandle<I>> for TypeHandle {
719 fn from(value: TypeInterfaceHandle<I>) -> Self {
720 value.to_handle()
721 }
722}
723
724impl<I: ?Sized + TypeInterfaceMarker + 'static> Clone for TypeInterfaceHandle<I> {
725 fn clone(&self) -> TypeInterfaceHandle<I> {
726 *self
727 }
728}
729
730impl<I: ?Sized + TypeInterfaceMarker + 'static> Copy for TypeInterfaceHandle<I> {}
731
732impl<I: ?Sized + TypeInterfaceMarker + 'static> PartialEq for TypeInterfaceHandle<I> {
733 fn eq(&self, other: &Self) -> bool {
734 self.0 == other.0
735 }
736}
737
738impl<I: ?Sized + TypeInterfaceMarker + 'static> Eq for TypeInterfaceHandle<I> {}
739
740impl<I: ?Sized + TypeInterfaceMarker + 'static> Hash for TypeInterfaceHandle<I> {
741 fn hash<H: Hasher>(&self, state: &mut H) {
742 self.0.hash(state);
743 }
744}
745
746impl<I: ?Sized + TypeInterfaceMarker + 'static> Debug for TypeInterfaceHandle<I> {
747 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
748 Debug::fmt(&self.0, f)
749 }
750}
751
752impl<I: ?Sized + TypeInterfaceMarker + 'static> Printable for TypeInterfaceHandle<I> {
753 fn fmt(
754 &self,
755 ctx: &Context,
756 state: &printable::State,
757 f: &mut core::fmt::Formatter<'_>,
758 ) -> core::fmt::Result {
759 Printable::fmt(&self.0, ctx, state, f)
760 }
761}
762
763impl<I: ?Sized + TypeInterfaceMarker + 'static> Parsable for TypeInterfaceHandle<I> {
764 type Arg = ();
765 type Parsed = Self;
766
767 fn parse<'a>(
768 state_stream: &mut StateStream<'a>,
769 _arg: Self::Arg,
770 ) -> ParseResult<'a, Self::Parsed> {
771 let loc = state_stream.loc();
772 TypeHandle::parser(())
773 .then(move |handle| {
774 let loc = loc.clone();
775 combine::parser(move |parsable_state: &mut StateStream<'a>| {
776 let ctx = &*parsable_state.state.ctx;
777 if !type_impls::<I>(&*handle.deref(ctx)) {
778 input_err!(
779 loc.clone(),
780 TypeInterfaceHandleErr {
781 interface: core::any::type_name::<I>().to_string(),
782 provided: handle.disp(ctx).to_string()
783 }
784 )?
785 }
786 Ok(TypeInterfaceHandle(handle, PhantomData::<I>)).into_parse_result()
787 })
788 })
789 .parse_stream(state_stream)
790 .into_result()
791 }
792}
793
794impl<I: ?Sized + TypeInterfaceMarker + 'static> Verify for TypeInterfaceHandle<I> {
795 fn verify(&self, ctx: &Context) -> Result<()> {
796 self.0.verify(ctx)
797 }
798}
799
800pub type TypeInterfaceVerifier = fn(&dyn Type, &Context) -> Result<()>;
802pub type TypeInterfaceAllVerifiers = fn() -> Vec<TypeInterfaceVerifier>;
804
805#[doc(hidden)]
806type TypeInterfaceVerifierInfo = &'static [(core::any::TypeId, TypeInterfaceAllVerifiers)];
809
810#[doc(hidden)]
811#[cfg(not(target_family = "wasm"))]
812pub mod statics {
813 use super::*;
814
815 #[::pliron::linkme::distributed_slice]
816 pub static TYPE_INTERFACE_VERIFIERS: [TypeInterfaceVerifierInfo] = [..];
817
818 pub(super) fn get_type_interface_verifiers()
819 -> impl Iterator<Item = &'static TypeInterfaceVerifierInfo> {
820 TYPE_INTERFACE_VERIFIERS.iter()
821 }
822}
823#[doc(hidden)]
824#[cfg(not(target_family = "wasm"))]
825pub use statics::TYPE_INTERFACE_VERIFIERS;
826
827#[doc(hidden)]
828#[cfg(target_family = "wasm")]
829pub mod statics {
830 use super::*;
831 use crate::InventoryWrapper;
832
833 ::pliron::inventory::collect!(InventoryWrapper<TypeInterfaceVerifierInfo>);
834
835 pub(super) fn get_type_interface_verifiers()
836 -> impl Iterator<Item = &'static TypeInterfaceVerifierInfo> {
837 ::pliron::inventory::iter::<InventoryWrapper<TypeInterfaceVerifierInfo>>().map(|llw| llw.0)
838 }
839}
840
841#[doc(hidden)]
842pub static TYPE_INTERFACE_VERIFIERS_MAP: LazyLock<
845 HMap<core::any::TypeId, Vec<TypeInterfaceVerifier>>,
846> = LazyLock::new(|| collect_deduped_interface_verifiers(statics::get_type_interface_verifiers()));
847
848#[derive(Debug, Clone, PartialEq, Eq, Hash)]
851#[format("`(` vec($arguments, CharSpace(`,`)) `)` ` -> ` `(`vec($results, CharSpace(`,`)) `)`")]
852pub struct TypeSig {
853 pub arguments: Vec<TypeHandle>,
854 pub results: Vec<TypeHandle>,
855}