Closed segeljakt closed 1 year ago
@frej Is there anything which is tedious in MLIR to generate?
The less details of the Rust implementation the MLIR-level needs to know the better it is.
If we have macros for sharing values, shouldn't we also have macros for accessing the boxed/rc:d value too? Or is that handled by some Rust magic?
Rust has automatic dereferencing for types which implement Deref
and/or DerefMut
.
Because
impl<T: ?Sized> Deref for Rc<T> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&self.inner().value
}
}
we can do
use std::rc::Rc;
use std::cell::RefCell;
struct Foo {
x: i32,
y: Rc<String>
}
fn main() {
let a = Rc::new(Foo { x: 0, y: Rc::new("".to_owned())});
let b = a.clone().x.clone();
let c = a.clone().y.clone();
}
I suggest we skip RefCell
mutability for the moment. It makes it slightly more annoying to generate, we would have to insert .borrow()
and .borrow_mut()
in places. I am not sure completely about how we should handle mutability yet. There are two cases to consider for structs:
var x = { a: 0, b: 5 };
x = { a: 5, b: 9 }; // OK
x.a = 9; // OK
In Rust both are allowed as long as x
is mut
. However if we wrap x
inside an Rc
then we cannot mutate its fields:
let mut x = Rc::new(Foo { a: 0, b: 5 });
x = Rc::new(Foo { a: 0, b: 5 }); // OK
x.a = 9; // not OK
Either we need to just wrap all fields in RefCell
or UnsafeCell
and enforce in the arc-script type system that this is not possible:
val x = { a: 0, b: 5 };
x.a = 9; // not OK
In Rust, it would look something like:
let mut x = Rc::new(Foo { a: RefCell::new(0), b: RefCell::new(5) });
x.a.borrow_mut() = RefCell::new(9);
Alternatively we could try using functional struct syntax but I am not sure about the performance.
let mut x = Rc::new(Foo { a: 0, b: 5 });
x = Rc::new(Foo { a: 9, ..x.as_ref().clone() }); // OK
In
arcorn
we have the following macros:enwrap!(variant, value)
- Enum constructionunwrap!(variant, value)
- Enum deconstructionis!(variant, value)
- Enum check#[rewrite] struct ...
- Generate conversion code for struct#[rewrite] enum ...
- Generate conversion code for enum#[rewrite] mod ...
- Generate arcon/arctime taskI think we could consider additionally to add macros for generating other kinds of boilerplate:
share_expr!(value)
- Wrapsvalue
insidestd::rc::Rc::new(std::rc::RefCell::new(value))
share_type!(type)
- Wrapstype
insidestd::rc::Rc::new<std::rc::RefCell::new<type>>
convert!(type)
- Expands to<type as arc_script::arcorn::Convert>::T
to get the Sendable/Operable of a type.@frej Is there anything which is tedious in MLIR to generate?