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 location::Located,
51 parsable::{Parsable, ParseResult, StateStream},
52 printable::{self, Printable},
53 result::{Error, Result},
54 std_deps::{hash::FxHashMap, sync::LazyLock},
55 storage_uniquer::TypeValueHash,
56 utils::trait_cast::impls_trait_static,
57};
58
59use alloc::{
60 boxed::Box,
61 string::{String, ToString},
62 vec::Vec,
63};
64use core::{
65 cell::{Ref, RefCell, RefMut},
66 fmt::{Debug, Display},
67 hash::{Hash, Hasher},
68 marker::PhantomData,
69 ops::Deref,
70};
71use downcast_rs::{Downcast, impl_downcast};
72use pliron_derive::format;
73use thiserror::Error;
74
75pub trait Type: Printable + Verify + Downcast + Sync + Send + Debug {
104 fn hash_type(&self) -> TypeValueHash;
107 fn eq_type(&self, other: &dyn Type) -> bool;
109
110 fn get_self_handle(&self, ctx: &Context) -> TypeHandle {
114 let is = |other: &TypeObj| self.eq_type(&**other.0.borrow());
115 let idx = ctx
116 .type_store
117 .get(self.hash_type(), &is)
118 .expect("Unregistered type object in existence");
119 TypeHandle(idx)
120 }
121
122 fn instantiate(t: Self, ctx: &Context) -> TypedHandle<Self>
124 where
125 Self: Sized,
126 {
127 let hash = t.hash_type();
128 let idx = ctx.type_store.get_or_create_unique(
129 TypeObj(RefCell::new(Box::new(t))),
130 hash,
131 &TypeObj::eq,
132 );
133 TypedHandle(TypeHandle(idx), PhantomData::<Self>)
134 }
135
136 fn get_type_id(&self) -> TypeId;
140
141 fn get_type_id_static() -> TypeId
143 where
144 Self: Sized;
145
146 #[doc(hidden)]
147 fn verify_interfaces(&self, ctx: &Context) -> Result<()>;
149
150 fn register(ctx: &mut Context)
152 where
153 Self: Sized + Parsable<Arg = (), Parsed = TypedHandle<Self>>,
154 {
155 let ptr_parser: TypeParserFn = |parsable_state, &()| {
156 Self::parse(parsable_state, ())
157 .map(|(typtr, r)| -> (TypeHandle, _) { (typtr.to_handle(), r) })
158 };
159 let typeid = Self::get_type_id_static();
160 Dialect::register(ctx, &typeid.dialect.clone()).add_type(typeid, ptr_parser);
161 }
162}
163impl_downcast!(Type);
164
165pub(crate) type TypeParserFn =
168 for<'a> fn(&mut StateStream<'a>, &'a ()) -> ParseResult<'a, TypeHandle>;
169
170pub trait Typed {
172 fn get_type(&self, ctx: &Context) -> TypeHandle;
174}
175
176impl Typed for TypeHandle {
177 fn get_type(&self, _ctx: &Context) -> TypeHandle {
178 *self
179 }
180}
181
182impl Typed for dyn Type {
183 fn get_type(&self, ctx: &Context) -> TypeHandle {
184 self.get_self_handle(ctx)
185 }
186}
187
188impl<T: Typed + ?Sized> Typed for &T {
189 fn get_type(&self, ctx: &Context) -> TypeHandle {
190 (*self).get_type(ctx)
191 }
192}
193
194impl<T: Typed + ?Sized> Typed for &mut T {
195 fn get_type(&self, ctx: &Context) -> TypeHandle {
196 (**self).get_type(ctx)
197 }
198}
199
200impl<T: Typed + ?Sized> Typed for Box<T> {
201 fn get_type(&self, ctx: &Context) -> TypeHandle {
202 (**self).get_type(ctx)
203 }
204}
205
206#[derive(Clone, Hash, PartialEq, Eq)]
207pub struct TypeName(Identifier);
209
210impl TypeName {
211 pub fn try_new(name: &str) -> Result<TypeName> {
213 Identifier::try_from(name).map(TypeName)
214 }
215}
216
217impl From<Identifier> for TypeName {
218 fn from(name: Identifier) -> Self {
219 TypeName(name)
220 }
221}
222
223impl From<TypeName> for Identifier {
224 fn from(name: TypeName) -> Self {
225 name.0
226 }
227}
228
229impl TryFrom<&str> for TypeName {
230 type Error = Error;
231
232 fn try_from(value: &str) -> Result<Self> {
233 Identifier::try_from(value).map(TypeName)
234 }
235}
236
237impl TryFrom<String> for TypeName {
238 type Error = Error;
239
240 fn try_from(value: String) -> Result<Self> {
241 Identifier::try_from(value).map(TypeName)
242 }
243}
244
245impl Deref for TypeName {
246 type Target = Identifier;
247
248 fn deref(&self) -> &Self::Target {
249 &self.0
250 }
251}
252
253impl_printable_for_display!(TypeName);
254
255impl Display for TypeName {
256 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
257 write!(f, "{}", self.0)
258 }
259}
260
261impl Parsable for TypeName {
262 type Arg = ();
263 type Parsed = TypeName;
264
265 fn parse<'a>(
266 state_stream: &mut crate::parsable::StateStream<'a>,
267 _arg: Self::Arg,
268 ) -> ParseResult<'a, Self::Parsed>
269 where
270 Self: Sized,
271 {
272 Identifier::parser(())
273 .map(TypeName)
274 .parse_stream(state_stream)
275 .into()
276 }
277}
278
279#[derive(Clone, Hash, PartialEq, Eq)]
281pub struct TypeId {
282 pub dialect: DialectName,
283 pub name: TypeName,
284}
285
286impl Parsable for TypeId {
287 type Arg = ();
288 type Parsed = TypeId;
289
290 fn parse<'a>(
292 state_stream: &mut StateStream<'a>,
293 _arg: Self::Arg,
294 ) -> ParseResult<'a, Self::Parsed>
295 where
296 Self: Sized,
297 {
298 let mut parser = DialectName::parser(())
299 .skip(parser::char::char('.'))
300 .and(TypeName::parser(()))
301 .map(|(dialect, name)| TypeId { dialect, name });
302 parser.parse_stream(state_stream).into()
303 }
304}
305
306impl_printable_for_display!(TypeId);
307
308impl Display for TypeId {
309 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
310 write!(f, "{}.{}", self.dialect, self.name)
311 }
312}
313
314pub(crate) struct TypeObj(RefCell<Box<dyn Type>>);
316
317impl PartialEq for TypeObj {
318 fn eq(&self, other: &Self) -> bool {
319 self.0.borrow().eq_type(&**other.0.borrow())
320 }
321}
322
323impl Eq for TypeObj {}
324
325impl Hash for TypeObj {
326 fn hash<H: Hasher>(&self, state: &mut H) {
327 state.write(&u64::from(self.0.borrow().hash_type()).to_ne_bytes())
328 }
329}
330
331#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
333pub struct TypeHandle(usize);
334
335impl TypeHandle {
336 pub fn deref<'a>(&self, ctx: &'a Context) -> Ref<'a, dyn Type> {
338 Ref::map(
339 ctx.type_store.unique_store.get(self.0).unwrap().0.borrow(),
340 |t| &**t,
341 )
342 }
343
344 pub fn deref_mut<'a>(&self, ctx: &'a Context) -> RefMut<'a, dyn Type> {
348 RefMut::map(
349 ctx.type_store
350 .unique_store
351 .get(self.0)
352 .unwrap()
353 .0
354 .borrow_mut(),
355 |t| &mut **t,
356 )
357 }
358}
359
360impl Printable for TypeHandle {
361 fn fmt(
362 &self,
363 ctx: &Context,
364 state: &printable::State,
365 f: &mut core::fmt::Formatter<'_>,
366 ) -> core::fmt::Result {
367 write!(f, "{} ", self.deref(ctx).get_type_id())?;
368 Printable::fmt(&*self.deref(ctx), ctx, state, f)
369 }
370}
371
372impl Verify for TypeHandle {
373 fn verify(&self, ctx: &Context) -> Result<()> {
374 verify_type(&*self.deref(ctx), ctx)
375 }
376}
377
378impl Parsable for TypeHandle {
379 type Arg = ();
380 type Parsed = Self;
381
382 fn parse<'a>(
383 state_stream: &mut StateStream<'a>,
384 _arg: Self::Arg,
385 ) -> ParseResult<'a, Self::Parsed> {
386 let loc = state_stream.loc();
387 let type_id_parser = spaced(TypeId::parser(()));
388
389 let mut type_parser = type_id_parser.then(move |type_id: TypeId| {
390 let loc = loc.clone();
392 combine::parser(move |parsable_state: &mut StateStream<'a>| {
393 let state = &parsable_state.state;
394 let dialect = state
395 .ctx
396 .dialects
397 .get(&type_id.dialect)
398 .expect("Dialect name parsed but dialect isn't registered");
399 let Some(type_parser) = dialect.types.get(&type_id) else {
400 input_err!(loc.clone(), "Unregistered type {}", type_id.disp(state.ctx))?
401 };
402 type_parser(parsable_state, &())
403 })
404 });
405
406 type_parser.parse_stream(state_stream).into_result()
407 }
408}
409
410pub fn verify_type(ty: &dyn Type, ctx: &Context) -> Result<()> {
414 ty.verify_interfaces(ctx)?;
416
417 Verify::verify(ty, ctx)
419}
420
421impl Verify for TypeObj {
422 fn verify(&self, ctx: &Context) -> Result<()> {
423 verify_type(self.0.borrow().as_ref(), ctx)
424 }
425}
426
427#[derive(Debug)]
429pub struct TypedHandle<T: Type>(TypeHandle, PhantomData<T>);
430
431#[derive(Error, Debug)]
432#[error("TypedHandle mismatch: Constructing {expected} but provided {provided}")]
433pub struct TypedHandleErr {
434 pub expected: String,
435 pub provided: String,
436}
437
438impl<T: Type> TypedHandle<T> {
439 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 input_err!(
521 loc.clone(),
522 "Expected type {}, but found {}",
523 T::get_type_id_static().disp(parsable_state.state.ctx),
524 type_id.disp(parsable_state.state.ctx)
525 )?
526 }
527 T::parser(arg).parse_stream(parsable_state).into()
528 })
529 })
530 .parse_stream(state_stream)
531 .into_result()
532 }
533}
534
535impl<T: Type> Verify for TypedHandle<T> {
536 fn verify(&self, ctx: &Context) -> Result<()> {
537 self.0.deref(ctx).verify(ctx)
538 }
539}
540
541#[diagnostic::on_unimplemented(
546 message = "`{Self}` not a type interface.",
547 label = "If `{Self}` is a trait, annotate it with #[type_interface] to be able to cast to it from a `&dyn Type`",
548 note = "If you want to cast to a concrete `Type`, use `downcast_ref` instead."
549)]
550pub trait TypeInterfaceMarker {}
551
552pub fn type_cast<T: ?Sized + TypeInterfaceMarker + 'static>(ty: &dyn Type) -> Option<&T> {
576 crate::utils::trait_cast::any_to_trait::<T>(ty.as_any())
577}
578
579pub fn type_impls<T: ?Sized + TypeInterfaceMarker + 'static>(ty: &dyn Type) -> bool {
601 type_cast::<T>(ty).is_some()
602}
603
604pub fn type_impls_static<T: Type, I: ?Sized + TypeInterfaceMarker + 'static>() -> bool {
616 impls_trait_static::<T, I>()
617}
618
619pub type TypeInterfaceVerifier = fn(&dyn Type, &Context) -> Result<()>;
621pub type TypeInterfaceAllVerifiers = fn() -> Vec<TypeInterfaceVerifier>;
623
624#[doc(hidden)]
625type TypeInterfaceVerifierInfo = (core::any::TypeId, TypeInterfaceAllVerifiers);
628
629#[doc(hidden)]
630#[cfg(not(target_family = "wasm"))]
631pub mod statics {
632 use super::*;
633
634 #[::pliron::linkme::distributed_slice]
635 pub static TYPE_INTERFACE_VERIFIERS: [TypeInterfaceVerifierInfo] = [..];
636
637 pub(super) fn get_type_interface_verifiers()
638 -> impl Iterator<Item = &'static TypeInterfaceVerifierInfo> {
639 TYPE_INTERFACE_VERIFIERS.iter()
640 }
641}
642#[doc(hidden)]
643#[cfg(not(target_family = "wasm"))]
644pub use statics::TYPE_INTERFACE_VERIFIERS;
645
646#[doc(hidden)]
647#[cfg(target_family = "wasm")]
648pub mod statics {
649 use super::*;
650 use crate::InventoryWrapper;
651
652 ::pliron::inventory::collect!(InventoryWrapper<TypeInterfaceVerifierInfo>);
653
654 pub(super) fn get_type_interface_verifiers()
655 -> impl Iterator<Item = &'static TypeInterfaceVerifierInfo> {
656 ::pliron::inventory::iter::<InventoryWrapper<TypeInterfaceVerifierInfo>>().map(|llw| llw.0)
657 }
658}
659
660#[doc(hidden)]
661pub static TYPE_INTERFACE_VERIFIERS_MAP: LazyLock<
664 FxHashMap<core::any::TypeId, Vec<TypeInterfaceVerifier>>,
665> = LazyLock::new(|| collect_deduped_interface_verifiers(statics::get_type_interface_verifiers()));
666
667#[derive(Debug, Clone, PartialEq, Eq, Hash)]
670#[format("`(` vec($arguments, CharSpace(`,`)) `)` ` -> ` `(`vec($results, CharSpace(`,`)) `)`")]
671pub struct TypeSig {
672 pub arguments: Vec<TypeHandle>,
673 pub results: Vec<TypeHandle>,
674}