fix: only allow casting on top level Data
This commit is contained in:
parent
c20ff6b160
commit
ee280bc309
|
@ -1847,6 +1847,44 @@ fn allow_expect_into_type_from_data() {
|
||||||
assert!(check(parse(source_code)).is_ok())
|
assert!(check(parse(source_code)).is_ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn forbid_partial_down_casting() {
|
||||||
|
let source_code = r#"
|
||||||
|
type Foo {
|
||||||
|
x: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(n: List<Foo>) {
|
||||||
|
expect a: List<Data> = n
|
||||||
|
a
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
assert!(matches!(
|
||||||
|
dbg!(check(parse(source_code))),
|
||||||
|
Err((_, Error::CouldNotUnify { .. }))
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn forbid_partial_up_casting() {
|
||||||
|
let source_code = r#"
|
||||||
|
type Foo {
|
||||||
|
x: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(n: List<Data>) {
|
||||||
|
expect a: List<Foo> = n
|
||||||
|
a
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
assert!(matches!(
|
||||||
|
dbg!(check(parse(source_code))),
|
||||||
|
Err((_, Error::CouldNotUnify { .. }))
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn allow_expect_into_type_from_data_2() {
|
fn allow_expect_into_type_from_data_2() {
|
||||||
let source_code = r#"
|
let source_code = r#"
|
||||||
|
|
|
@ -1431,7 +1431,7 @@ impl<'a> Environment<'a> {
|
||||||
lhs,
|
lhs,
|
||||||
Type::with_alias(tipo.clone(), alias.clone()),
|
Type::with_alias(tipo.clone(), alias.clone()),
|
||||||
location,
|
location,
|
||||||
allow_cast,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1470,7 +1470,7 @@ impl<'a> Environment<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
Action::Unify(t) => self.unify(t, rhs, location, allow_cast),
|
Action::Unify(t) => self.unify(t, rhs, location, false),
|
||||||
|
|
||||||
Action::CouldNotUnify => Err(Error::CouldNotUnify {
|
Action::CouldNotUnify => Err(Error::CouldNotUnify {
|
||||||
location,
|
location,
|
||||||
|
@ -1484,7 +1484,7 @@ impl<'a> Environment<'a> {
|
||||||
|
|
||||||
if let Type::Var { .. } = rhs.deref() {
|
if let Type::Var { .. } = rhs.deref() {
|
||||||
return self
|
return self
|
||||||
.unify(rhs, lhs, location, allow_cast)
|
.unify(rhs, lhs, location, false)
|
||||||
.map_err(|e| e.flip_unify());
|
.map_err(|e| e.flip_unify());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1511,7 +1511,7 @@ impl<'a> Environment<'a> {
|
||||||
unify_enclosed_type(
|
unify_enclosed_type(
|
||||||
lhs.clone(),
|
lhs.clone(),
|
||||||
rhs.clone(),
|
rhs.clone(),
|
||||||
self.unify(a.clone(), b.clone(), location, allow_cast),
|
self.unify(a.clone(), b.clone(), location, false),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1531,7 +1531,7 @@ impl<'a> Environment<'a> {
|
||||||
unify_enclosed_type(
|
unify_enclosed_type(
|
||||||
lhs.clone(),
|
lhs.clone(),
|
||||||
rhs.clone(),
|
rhs.clone(),
|
||||||
self.unify(a.clone(), b.clone(), location, allow_cast),
|
self.unify(a.clone(), b.clone(), location, false),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1550,7 +1550,7 @@ impl<'a> Environment<'a> {
|
||||||
},
|
},
|
||||||
) if args1.len() == args2.len() => {
|
) if args1.len() == args2.len() => {
|
||||||
for (a, b) in args1.iter().zip(args2) {
|
for (a, b) in args1.iter().zip(args2) {
|
||||||
self.unify(a.clone(), b.clone(), location, allow_cast)
|
self.unify(a.clone(), b.clone(), location, false)
|
||||||
.map_err(|_| Error::CouldNotUnify {
|
.map_err(|_| Error::CouldNotUnify {
|
||||||
location,
|
location,
|
||||||
expected: lhs.clone(),
|
expected: lhs.clone(),
|
||||||
|
@ -1559,7 +1559,7 @@ impl<'a> Environment<'a> {
|
||||||
rigid_type_names: HashMap::new(),
|
rigid_type_names: HashMap::new(),
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
self.unify(retrn1.clone(), retrn2.clone(), location, allow_cast)
|
self.unify(retrn1.clone(), retrn2.clone(), location, false)
|
||||||
.map_err(|_| Error::CouldNotUnify {
|
.map_err(|_| Error::CouldNotUnify {
|
||||||
location,
|
location,
|
||||||
expected: lhs.clone(),
|
expected: lhs.clone(),
|
||||||
|
|
Loading…
Reference in New Issue