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:
rvcas
2023-02-02 18:23:19 -05:00
committed by Lucas
parent 910d5ad312
commit a9ed04ef22
6 changed files with 69 additions and 1 deletions

View File

@@ -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<(), ()>;

View File

@@ -1210,7 +1210,7 @@ impl<'a> Environment<'a> {
return Ok(());
}
if t2.is_data() {
if t1.is_data() || t2.is_data() {
return Ok(());
}

View File

@@ -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