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,
|
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 MultiPattern<PatternConstructor, Type> = Vec<Pattern<PatternConstructor, Type>>;
|
||||||
|
|
||||||
pub type UntypedMultiPattern = MultiPattern<(), ()>;
|
pub type UntypedMultiPattern = MultiPattern<(), ()>;
|
||||||
|
|
|
@ -1210,7 +1210,7 @@ impl<'a> Environment<'a> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if t2.is_data() {
|
if t1.is_data() || t2.is_data() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -822,6 +822,16 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
typed_value.type_defining_location(),
|
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();
|
value_typ = ann_typ.clone();
|
||||||
|
|
||||||
// Ensure the pattern matches the type of the value
|
// 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