make objects work better, especially destructuring

This commit is contained in:
Mark
2024-09-28 01:51:20 +02:00
parent 9c8e918440
commit c17ea580b2
41 changed files with 899 additions and 453 deletions

View File

@@ -1,11 +1,16 @@
use std::{any::Any, fmt::Display, sync::Arc};
use crate::info::DisplayInfo;
use super::{MersData, MersType, Type};
#[derive(Debug, Clone)]
pub struct Bool(pub bool);
impl MersData for Bool {
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_eq(&self, other: &dyn MersData) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() {
other.0 == self.0
@@ -43,6 +48,13 @@ pub fn bool_type() -> Type {
Type::newm(vec![Arc::new(TrueT), Arc::new(FalseT)])
}
impl MersType for TrueT {
fn display(
&self,
_info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some()
}
@@ -63,6 +75,13 @@ impl MersType for TrueT {
}
}
impl MersType for FalseT {
fn display(
&self,
_info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some()
}

View File

@@ -1,11 +1,16 @@
use std::{any::Any, fmt::Display, sync::Arc};
use crate::info::DisplayInfo;
use super::{MersData, MersType, Type};
#[derive(Debug, Clone, Copy)]
pub struct Byte(pub u8);
impl MersData for Byte {
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_eq(&self, other: &dyn MersData) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() {
other.0 == self.0
@@ -33,6 +38,13 @@ impl MersData for Byte {
#[derive(Debug, Clone)]
pub struct ByteT;
impl MersType for ByteT {
fn display(
&self,
_info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some()
}

View File

@@ -28,7 +28,10 @@ pub fn assign(from: &Data, target: &Data) {
.as_any()
.downcast_ref::<crate::data::object::Object>(),
) {
for ((_, from), (_, target)) in from.0.iter().zip(target.0.iter()) {
for (field, target) in target.iter() {
let from = from
.get(*field)
.expect("type-checks should guarantee that from has every field of target");
assign(from, target);
}
} else {

View File

@@ -1,11 +1,16 @@
use std::{any::Any, fmt::Display, sync::Arc};
use crate::info::DisplayInfo;
use super::{MersData, MersType, Type};
#[derive(Debug, Clone)]
pub struct Float(pub f64);
impl MersData for Float {
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_eq(&self, other: &dyn MersData) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() {
other.0 == self.0
@@ -33,6 +38,13 @@ impl MersData for Float {
#[derive(Debug, Clone)]
pub struct FloatT;
impl MersType for FloatT {
fn display(
&self,
_info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some()
}

View File

@@ -6,7 +6,7 @@ use std::{
use crate::{
errors::CheckError,
info::Local,
info::DisplayInfo,
program::run::{CheckInfo, Info},
};
@@ -87,13 +87,13 @@ impl Function {
(self.run)(arg, &mut self.info.duplicate())
}
pub fn get_as_type(&self) -> FunctionT {
let info = self.info_check.lock().unwrap().clone();
match &self.out {
Ok(out) => {
let out = Arc::clone(out);
let info = self.info_check.lock().unwrap().clone();
FunctionT(Ok(Arc::new(move |a| out(a, &mut info.clone()))))
FunctionT(Ok(Arc::new(move |a, i| out(a, &mut i.clone()))), info)
}
Err(types) => FunctionT(Err(Arc::clone(types))),
Err(types) => FunctionT(Err(Arc::clone(types)), info),
}
}
@@ -108,6 +108,9 @@ impl Function {
}
impl MersData for Function {
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{self}")
}
fn executable(&self) -> Option<crate::data::function::FunctionT> {
Some(self.get_as_type())
}
@@ -151,18 +154,50 @@ impl MersData for Function {
#[derive(Clone)]
pub struct FunctionT(
pub Result<Arc<dyn Fn(&Type) -> Result<Type, CheckError> + Send + Sync>, Arc<Vec<(Type, Type)>>>,
pub Result<
Arc<dyn Fn(&Type, &CheckInfo) -> Result<Type, CheckError> + Send + Sync>,
Arc<Vec<(Type, Type)>>,
>,
pub CheckInfo,
);
impl FunctionT {
/// get output type
pub fn o(&self, i: &Type) -> Result<Type, CheckError> {
match &self.0 {
Ok(f) => f(i),
Err(v) => v.iter().find(|(a, _)| i.is_included_in(a)).map(|(_, o)| o.clone()).ok_or_else(|| format!("This function, which was defined with an explicit type, cannot be called with an argument of type {i}.").into()),
Ok(f) => f(i, &self.1),
Err(v) => v
.iter()
.find(|(a, _)| i.is_included_in(a))
.map(|(_, o)| o.clone())
.ok_or_else(|| format!("This function, which was defined with an explicit type, cannot be called with an argument of type {}.", i.with_info(&self.1)).into()),
}
}
}
impl MersType for FunctionT {
fn display(
&self,
info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
match &self.0 {
Err(e) => {
write!(f, "(")?;
for (index, (i, o)) in e.iter().enumerate() {
if index > 0 {
write!(f, ", ")?;
}
write!(f, "{} -> {}", i.with_display(info), o.with_display(info))?;
}
write!(f, ")")
}
Ok(_) => match self.o(&Type::empty_tuple()) {
Ok(t) => write!(f, "(() -> {}, ...)", t.with_display(info)),
Err(_) => {
write!(f, "(... -> ...)",)
}
},
}
}
fn executable(&self) -> Option<crate::data::function::FunctionT> {
Some(self.clone())
}
@@ -249,25 +284,3 @@ impl Display for Function {
write!(f, "<function>")
}
}
impl Display for FunctionT {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.0 {
Err(e) => {
write!(f, "(")?;
for (index, (i, o)) in e.iter().enumerate() {
if index > 0 {
write!(f, ", ")?;
}
write!(f, "{i} -> {o}")?;
}
write!(f, ")")
}
Ok(_) => match self.o(&Type::empty_tuple()) {
Ok(t) => write!(f, "(() -> {t}, ...)"),
Err(_) => {
write!(f, "(... -> ...)",)
}
},
}
}
}

View File

@@ -1,11 +1,16 @@
use std::{any::Any, fmt::Display, sync::Arc};
use crate::info::DisplayInfo;
use super::{MersData, MersType, Type};
#[derive(Debug, Clone, Copy)]
pub struct Int(pub isize);
impl MersData for Int {
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_eq(&self, other: &dyn MersData) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() {
other.0 == self.0
@@ -33,6 +38,13 @@ impl MersData for Int {
#[derive(Debug, Clone)]
pub struct IntT;
impl MersType for IntT {
fn display(
&self,
_info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some()
}

View File

@@ -4,7 +4,7 @@ use std::{
sync::{atomic::AtomicUsize, Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
};
use crate::errors::CheckError;
use crate::{errors::CheckError, info::DisplayInfo};
pub mod bool;
pub mod byte;
@@ -18,7 +18,12 @@ pub mod tuple;
pub mod defs;
pub trait MersData: Any + Debug + Display + Send + Sync {
pub trait MersData: Any + Debug + Send + Sync {
fn display(
&self,
info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result;
/// must be the same as the `executable` impl on the MersType
#[allow(unused_variables)]
fn executable(&self) -> Option<crate::data::function::FunctionT> {
@@ -46,7 +51,66 @@ pub trait MersData: Any + Debug + Display + Send + Sync {
fn to_any(self) -> Box<dyn Any>;
}
pub trait MersType: Any + Debug + Display + Send + Sync {
pub trait MersDataWInfo {
fn with_display<'a>(&'a self, info: &DisplayInfo<'a>) -> MersDataWithInfo<'a, Self> {
MersDataWithInfo(self, *info)
}
fn with_info<'a>(
&'a self,
info: &'a crate::info::Info<impl crate::info::Local>,
) -> MersDataWithInfo<'a, Self> {
MersDataWithInfo(self, info.display_info())
}
}
pub trait MersTypeWInfo {
fn with_display<'a>(&'a self, info: &DisplayInfo<'a>) -> MersTypeWithInfo<'a, Self> {
MersTypeWithInfo(self, *info)
}
fn with_info<'a>(
&'a self,
info: &'a crate::info::Info<impl crate::info::Local>,
) -> MersTypeWithInfo<'a, Self> {
MersTypeWithInfo(self, info.display_info())
}
}
impl Type {
pub fn with_display<'a>(&'a self, info: &DisplayInfo<'a>) -> TypeWithInfo<'a> {
TypeWithInfo(self, *info)
}
pub fn with_info<'a>(
&'a self,
info: &'a crate::info::Info<impl crate::info::Local>,
) -> TypeWithInfo<'a> {
TypeWithInfo(self, info.display_info())
}
}
impl<T: MersData + ?Sized> MersDataWInfo for T {}
impl<T: MersType + ?Sized> MersTypeWInfo for T {}
pub struct MersDataWithInfo<'a, T: ?Sized>(&'a T, crate::info::DisplayInfo<'a>);
pub struct MersTypeWithInfo<'a, T: ?Sized>(&'a T, crate::info::DisplayInfo<'a>);
pub struct TypeWithInfo<'a>(&'a Type, crate::info::DisplayInfo<'a>);
impl<'a, T: ?Sized + MersData> Display for MersDataWithInfo<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.display(&self.1, f)
}
}
impl<'a, T: ?Sized + MersType> Display for MersTypeWithInfo<'a, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.display(&self.1, f)
}
}
impl<'a> Display for TypeWithInfo<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.display(&self.1, f)
}
}
pub trait MersType: Any + Debug + Send + Sync {
fn display(
&self,
info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result;
#[allow(unused_variables)]
fn executable(&self) -> Option<crate::data::function::FunctionT> {
None
@@ -93,13 +157,20 @@ pub trait MersType: Any + Debug + Display + Send + Sync {
}
fn simplified_as_string(&self, info: &crate::program::run::CheckInfo) -> String {
self.simplify_for_display(info)
.map(|s| s.to_string())
.unwrap_or_else(|| self.to_string())
.map(|s| s.with_info(info).to_string())
.unwrap_or_else(|| self.with_info(info).to_string())
}
}
#[derive(Clone, Debug)]
pub(crate) struct TypeWithOnlyName(pub(crate) String);
impl MersType for TypeWithOnlyName {
fn display(
&self,
_info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_same_type_as(&self, _other: &dyn MersType) -> bool {
false
}
@@ -447,20 +518,20 @@ impl Type {
out
}
pub fn simplified_as_string(&self, info: &crate::program::run::CheckInfo) -> String {
self.simplify_for_display(info).to_string()
self.simplify_for_display(info).with_info(info).to_string()
}
}
impl Display for Type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl Type {
fn display(&self, info: &DisplayInfo, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.types.is_empty() {
write!(f, "<unreachable>")
} else {
// if self.types.len() > 1 {
// write!(f, "{{")?;
// }
write!(f, "{}", self.types[0])?;
write!(f, "{}", self.types[0].with_display(info))?;
for t in self.types.iter().skip(1) {
write!(f, "/{t}")?;
write!(f, "/{}", t.with_display(info))?;
}
// if self.types.len() > 1 {
// write!(f, "}}")?;

View File

@@ -1,13 +1,61 @@
use std::{fmt::Display, sync::Arc};
use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
use super::{Data, MersData, MersType, Type};
use crate::info::DisplayInfo;
use super::{Data, MersData, MersDataWInfo, MersType, Type};
#[derive(Debug, PartialEq, Clone)]
pub struct Object(pub Vec<(String, Data)>);
pub struct Object(Vec<(usize, Data)>);
impl Object {
pub fn new(v: Vec<(usize, Data)>) -> Self {
Self(v)
}
pub fn get(&self, f: usize) -> Option<&Data> {
self.iter().find(|v| v.0 == f).map(|v| &v.1)
}
pub fn iter(&self) -> std::slice::Iter<(usize, Data)> {
self.0.iter()
}
}
#[derive(Debug, Clone)]
pub struct ObjectT(pub Vec<(String, Type)>);
pub struct ObjectT(Vec<(usize, Type)>);
impl ObjectT {
pub fn new(v: Vec<(usize, Type)>) -> Self {
Self(v)
}
pub fn get(&self, f: usize) -> Option<&Type> {
self.iter().find(|v| v.0 == f).map(|v| &v.1)
}
pub fn iter(&self) -> std::slice::Iter<(usize, Type)> {
self.0.iter()
}
fn len(&self) -> usize {
self.0.len()
}
}
impl MersData for Object {
fn display(&self, info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let mut comma_sep = false;
write!(f, "{{")?;
for (field, val) in self.iter() {
if comma_sep {
write!(f, ", ")?;
}
write!(
f,
"{}: {}",
info.get_object_field_name(*field),
val.get().with_display(info)
)?;
comma_sep = true;
}
write!(f, "}}")?;
Ok(())
}
fn is_eq(&self, other: &dyn MersData) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() {
self == other
@@ -20,8 +68,7 @@ impl MersData for Object {
}
fn as_type(&self) -> Type {
Type::new(ObjectT(
self.0
.iter()
self.iter()
.map(|(n, v)| (n.clone(), v.get().as_type()))
.collect(),
))
@@ -38,14 +85,35 @@ impl MersData for Object {
}
impl MersType for ObjectT {
fn display(
&self,
info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
let mut comma_sep = false;
write!(f, "{{")?;
for (field, t) in self.iter() {
if comma_sep {
write!(f, ", ")?;
}
write!(
f,
"{}: {}",
info.get_object_field_name(*field),
t.with_display(info)
)?;
comma_sep = true;
}
write!(f, "}}")?;
Ok(())
}
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some_and(|other| {
self.0.len() == other.0.len()
&& self
.0
.iter()
.zip(other.0.iter())
.all(|((s1, t1), (s2, t2))| s1 == s2 && t1.is_same_type_as(t2))
self.len() == other.len()
&& other.iter().all(|(field, target_type)| {
self.get(*field)
.is_some_and(|self_type| self_type.is_same_type_as(target_type))
})
})
}
fn is_included_in(&self, target: &dyn MersType) -> bool {
@@ -53,16 +121,15 @@ impl MersType for ObjectT {
.as_any()
.downcast_ref::<Self>()
.is_some_and(|target| {
self.0.len() >= target.0.len()
&& self
.0
.iter()
.zip(target.0.iter())
.all(|((s1, t1), (s2, t2))| s1 == s2 && t1.is_included_in(t2))
self.len() >= target.len()
&& target.iter().all(|(field, target_type)| {
self.get(*field)
.is_some_and(|self_type| self_type.is_included_in(target_type))
})
})
}
fn subtypes(&self, acc: &mut Type) {
self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.0.len()));
self.gen_subtypes_recursively(acc, &mut Vec::with_capacity(self.len()));
}
fn as_any(&self) -> &dyn std::any::Any {
self
@@ -83,44 +150,13 @@ impl MersType for ObjectT {
}
}
impl Display for Object {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut comma_sep = false;
write!(f, "{{")?;
for (name, val) in self.0.iter() {
if comma_sep {
write!(f, ", ")?;
}
write!(f, "{name}: {}", val.get())?;
comma_sep = true;
}
write!(f, "}}")?;
Ok(())
}
}
impl Display for ObjectT {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut comma_sep = false;
write!(f, "{{")?;
for (name, t) in self.0.iter() {
if comma_sep {
write!(f, ", ")?;
}
write!(f, "{name}: {t}")?;
comma_sep = true;
}
write!(f, "}}")?;
Ok(())
}
}
impl ObjectT {
pub fn gen_subtypes_recursively(
&self,
acc: &mut Type,
types: &mut Vec<(String, Arc<dyn MersType>)>,
types: &mut Vec<(usize, Arc<dyn MersType>)>,
) {
if types.len() >= self.0.len() {
if types.len() >= self.len() {
let nt = Self(
types
.iter()
@@ -137,3 +173,18 @@ impl ObjectT {
}
}
}
pub(crate) trait ObjectFieldsMap {
fn get_or_add_field(&self, field: &str) -> usize;
}
impl ObjectFieldsMap for Arc<Mutex<HashMap<String, usize>>> {
fn get_or_add_field(&self, field: &str) -> usize {
let mut s = self.lock().unwrap();
if let Some(f) = s.get(field) {
return *f;
}
let o = s.len();
s.insert(field.to_owned(), o);
o
}
}

View File

@@ -1,10 +1,9 @@
use std::{
any::Any,
fmt::Display,
sync::{Arc, RwLock},
};
use crate::errors::CheckError;
use crate::{errors::CheckError, info::DisplayInfo};
use super::{Data, MersData, MersType, Type};
@@ -12,6 +11,9 @@ use super::{Data, MersData, MersType, Type};
pub struct Reference(pub Arc<RwLock<Data>>);
impl MersData for Reference {
fn display(&self, info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.0.read().unwrap().get().display(info, f)
}
fn executable(&self) -> Option<crate::data::function::FunctionT> {
let inner = self.0.read().unwrap();
let inner = inner.get();
@@ -88,6 +90,17 @@ impl MersData for Reference {
#[derive(Debug, Clone)]
pub struct ReferenceT(pub Type);
impl MersType for ReferenceT {
fn display(
&self,
info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
if self.0.types.len() > 1 {
write!(f, "&{{{}}}", self.0.with_display(info))
} else {
write!(f, "&{}", self.0.with_display(info))
}
}
fn executable(&self) -> Option<crate::data::function::FunctionT> {
let mut funcs: Vec<crate::data::function::FunctionT> = vec![];
for func in self.0.types.iter() {
@@ -96,13 +109,16 @@ impl MersType for ReferenceT {
.downcast_ref::<crate::data::function::FunctionT>()?,
));
}
Some(super::function::FunctionT(Ok(Arc::new(move |a| {
let mut out = Type::empty();
for func in funcs.iter() {
out.add_all(&func.o(a)?);
}
Ok(out)
}))))
Some(super::function::FunctionT(
Ok(Arc::new(move |a, _| {
let mut out = Type::empty();
for func in funcs.iter() {
out.add_all(&func.o(a)?);
}
Ok(out)
})),
crate::info::Info::neverused(),
))
}
fn iterable(&self) -> Option<Type> {
let mut out = Type::empty();
@@ -156,18 +172,3 @@ impl MersType for ReferenceT {
Some(&self.0)
}
}
impl Display for Reference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "&{}", self.0.read().unwrap().get())
}
}
impl Display for ReferenceT {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.0.types.len() > 1 {
write!(f, "&{{{}}}", self.0)
} else {
write!(f, "&{}", self.0)
}
}
}

View File

@@ -1,11 +1,16 @@
use std::{any::Any, fmt::Display, sync::Arc};
use crate::info::DisplayInfo;
use super::{MersData, MersType, Type};
#[derive(Debug, Clone)]
pub struct String(pub std::string::String);
impl MersData for String {
fn display(&self, _info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_eq(&self, other: &dyn MersData) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() {
other.0 == self.0
@@ -33,6 +38,13 @@ impl MersData for String {
#[derive(Debug, Clone)]
pub struct StringT;
impl MersType for StringT {
fn display(
&self,
_info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{self}")
}
fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().downcast_ref::<Self>().is_some()
}

View File

@@ -1,6 +1,6 @@
use std::{any::Any, fmt::Display, sync::Arc};
use std::{any::Any, sync::Arc};
use crate::errors::CheckError;
use crate::{errors::CheckError, info::DisplayInfo};
use super::{Data, MersData, MersType, Type};
@@ -17,6 +17,17 @@ impl Tuple {
}
impl MersData for Tuple {
fn display(&self, info: &DisplayInfo<'_>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "(")?;
for (i, c) in self.0.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
c.get().display(info, f)?;
}
write!(f, ")")?;
Ok(())
}
fn is_eq(&self, other: &dyn MersData) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() {
other.0 == self.0
@@ -47,6 +58,21 @@ impl MersData for Tuple {
#[derive(Debug)]
pub struct TupleT(pub Vec<Type>);
impl MersType for TupleT {
fn display(
&self,
info: &crate::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "(")?;
for (i, c) in self.0.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", c.with_display(info))?;
}
write!(f, ")")?;
Ok(())
}
fn iterable(&self) -> Option<Type> {
let mut o = Type::empty();
for t in self.0.iter() {
@@ -100,33 +126,6 @@ impl MersType for TupleT {
}
}
impl Display for Tuple {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(")?;
for (i, c) in self.0.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", c.get())?;
}
write!(f, ")")?;
Ok(())
}
}
impl Display for TupleT {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "(")?;
for (i, c) in self.0.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", c)?;
}
write!(f, ")")?;
Ok(())
}
}
impl TupleT {
pub fn gen_subtypes_recursively(&self, acc: &mut Type, types: &mut Vec<Arc<dyn MersType>>) {
if types.len() >= self.0.len() {