feat: newer rules around casting Data
* you cannot cast FROM Data with a `let` * you cannot cast FROM Data by passing Data to none Data when calling a function * you MUST use `assert` to cast from data * you can cast INTO Data with a `let` * you can cast INTO Data by passing none Data to Data when calling a function * You cannot assert cast Data without an annotation
This commit is contained in:
parent
910d5ad312
commit
a9ed04ef22
|
@ -769,6 +769,16 @@ pub enum AssignmentKind {
|
|||
Assert,
|
||||
}
|
||||
|
||||
impl AssignmentKind {
|
||||
pub fn is_let(&self) -> bool {
|
||||
matches!(self, AssignmentKind::Let)
|
||||
}
|
||||
|
||||
pub fn is_assert(&self) -> bool {
|
||||
matches!(self, AssignmentKind::Assert)
|
||||
}
|
||||
}
|
||||
|
||||
pub type MultiPattern<PatternConstructor, Type> = Vec<Pattern<PatternConstructor, Type>>;
|
||||
|
||||
pub type UntypedMultiPattern = MultiPattern<(), ()>;
|
||||
|
|
|
@ -1210,7 +1210,7 @@ impl<'a> Environment<'a> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
if t2.is_data() {
|
||||
if t1.is_data() || t2.is_data() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
|
@ -822,6 +822,16 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
typed_value.type_defining_location(),
|
||||
)?;
|
||||
|
||||
if value_typ.is_data() && kind.is_let() && !ann_typ.is_data() {
|
||||
return Err(Error::CouldNotUnify {
|
||||
location,
|
||||
expected: ann_typ,
|
||||
given: value_typ,
|
||||
situation: Some(UnifyErrorSituation::UnsafeCast),
|
||||
rigid_type_names: HashMap::new(),
|
||||
});
|
||||
}
|
||||
|
||||
value_typ = ann_typ.clone();
|
||||
|
||||
// Ensure the pattern matches the type of the value
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# This file was generated by Aiken
|
||||
# You typically do not need to edit this file
|
||||
|
||||
requirements = []
|
||||
packages = []
|
|
@ -0,0 +1,3 @@
|
|||
name = 'aiken-lang/acceptance_test_050'
|
||||
version = '0.0.0'
|
||||
description = ''
|
|
@ -0,0 +1,40 @@
|
|||
use aiken/builtin
|
||||
|
||||
pub type Thing {
|
||||
wow: Int,
|
||||
}
|
||||
|
||||
test assert_1() {
|
||||
assert thing: Thing = builtin.constr_data(0, [builtin.i_data(1)])
|
||||
|
||||
thing.wow == 1
|
||||
}
|
||||
|
||||
fn cast_to_thing(x: Data) -> Thing {
|
||||
assert x: Thing = x
|
||||
|
||||
x
|
||||
}
|
||||
|
||||
test assert_2() {
|
||||
let thing = Thing { wow: 1 }
|
||||
|
||||
let still_thing = cast_to_thing(thing)
|
||||
|
||||
still_thing.wow == 1
|
||||
}
|
||||
// should not typecheck
|
||||
// test unlift_data_without_assert_1() {
|
||||
// let thing: Thing = builtin.constr_data(0, [builtin.i_data(1)])
|
||||
// thing.wow == 1
|
||||
// }
|
||||
|
||||
// should not typecheck
|
||||
// fn bad_cast(x: Thing) -> Int {
|
||||
// x.wow
|
||||
// }
|
||||
|
||||
// test unlift_data_without_assert_2() {
|
||||
// let thing = builtin.constr_data(0, [builtin.i_data(1)])
|
||||
// bad_cast(thing) == 1
|
||||
// }
|
Loading…
Reference in New Issue