fix: object assignment from multitype and in try

This commit is contained in:
Mark 2025-10-26 01:53:57 +02:00
parent ffcd95c72d
commit 9e4eece87c
5 changed files with 56 additions and 46 deletions

View File

@ -1,22 +0,0 @@
name: Rust
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check
run: sh -c "cd mers && cargo check --verbose"
- name: Tests
run: sh -c "cd mers && cargo test --verbose"

View File

@ -1,6 +1,6 @@
[package]
name = "mers"
version = "0.9.23"
version = "0.9.26"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "dynamically typed but type-checked programming language"
@ -15,7 +15,7 @@ default = ["colored-output"]
colored-output = ["mers_lib/ecolor-term", "mers_lib/pretty-print", "dep:colored"]
[dependencies]
mers_lib = "0.9.23"
mers_lib = "0.9.26"
# mers_lib = { path = "../mers_lib" }
clap = { version = "4.3.19", features = ["derive"] }
colored = { version = "2.1.0", optional = true }

View File

@ -1,6 +1,6 @@
[package]
name = "mers_lib"
version = "0.9.23"
version = "0.9.26"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "library to use the mers language in other projects"

View File

@ -133,7 +133,7 @@ impl MersType for ObjectT {
if let Some(remove) = remove
.as_any()
.downcast_ref::<Self>()
.filter(|r| r.0.len() <= m)
.filter(|r| r.0.len() >= m)
{
let mut out = Type::empty();
for i1 in 0usize.. {
@ -163,7 +163,7 @@ impl MersType for ObjectT {
remove_tuple
.iter()
.find(|(v, _)| *v == self_tuple[j].0)
.is_none_or(|(_, r)| {
.is_some_and(|(_, r)| {
self_tuple[j].1.as_ref().is_included_in(r.as_ref())
})
}) {

View File

@ -24,18 +24,65 @@ impl MersStatement for Object {
let print_is_part_of = init_to.types.len() > 1;
let mut init_fields = HashMap::new();
for t in init_to.types.iter() {
if let Some(t) = t.as_any().downcast_ref::<ObjectT>() {
for (field, t) in t.iter() {
if let Some(ot) = t.as_any().downcast_ref::<ObjectT>() {
let mut fields = self.fields.iter().map(|(t, _)| *t).collect::<Vec<_>>();
fields.sort();
for (field, t) in ot.iter() {
if let Ok(i) = fields.binary_search(field) {
fields.remove(i);
}
init_fields
.entry(*field)
.or_insert_with(Type::empty)
.add_all(t);
}
if !fields.is_empty() {
return Err(CheckError::new().msg(vec![
("can't init an ".to_owned(), None),
("object".to_owned(), Some(EColor::InitTo)),
(" from type ".to_owned(), None),
(t.simplified_as_string(info), Some(EColor::InitFrom)),
if print_is_part_of {
(", which is part of ".to_owned(), None)
} else {
(format!(""), None)
},
if print_is_part_of {
(init_to.simplified_as_string(info), Some(EColor::InitFrom))
} else {
(format!(""), None)
},
(
format!(" - missing fields {}", {
let object_fields_rev =
info.global.object_fields_rev.lock().unwrap();
fields
.iter()
.map(|f| {
object_fields_rev
.get(*f)
.map(|f| f.as_str())
.unwrap_or("<unknown>")
})
.enumerate()
.map(|(i, f)| {
if i == 0 {
f.to_owned()
} else {
format!(", {f}")
}
})
.collect::<String>()
}),
None,
),
]));
}
} else {
return Err(CheckError::new().msg(vec![
("can't init an ".to_owned(), None),
("object".to_owned(), Some(EColor::InitTo)),
(" with type ".to_owned(), None),
(" from type ".to_owned(), None),
(t.simplified_as_string(info), Some(EColor::InitFrom)),
if print_is_part_of {
(", which is part of ".to_owned(), None)
@ -72,22 +119,7 @@ impl MersStatement for Object {
} else if init_to_is_empty_type {
Type::empty()
} else {
return Err(CheckError::new().msg(vec![
("can't init an ".to_owned(), None),
("object".to_owned(), Some(EColor::InitTo)),
(" with type ".to_owned(), None),
(
init_to.as_ref().unwrap().simplified_as_string(info),
Some(EColor::InitFrom),
),
(
format!(
" - field {} is missing",
info.display_info().get_object_field_name(*field)
),
None,
),
]));
unreachable!("type-checking earlier in check_custom() should prevent this")
})
} else {
None