mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 03:42:17 +00:00
parent
e674c33b89
commit
fc1617bf17
3 changed files with 139 additions and 8 deletions
|
@ -351,7 +351,8 @@ fn canonicalize_alias<'a>(
|
|||
region: loc_lowercase.region,
|
||||
});
|
||||
}
|
||||
None => {
|
||||
None => match kind {
|
||||
AliasKind::Structural => {
|
||||
is_phantom = true;
|
||||
|
||||
env.problems.push(Problem::PhantomTypeArgument {
|
||||
|
@ -360,6 +361,18 @@ fn canonicalize_alias<'a>(
|
|||
variable_name: loc_lowercase.value.clone(),
|
||||
});
|
||||
}
|
||||
AliasKind::Opaque => {
|
||||
// Opaques can have phantom types.
|
||||
can_vars.push(Loc {
|
||||
value: AliasVar {
|
||||
name: loc_lowercase.value.clone(),
|
||||
var: var_store.fresh(),
|
||||
opt_bound_ability: None,
|
||||
},
|
||||
region: loc_lowercase.region,
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7050,4 +7050,55 @@ mod solve_expr {
|
|||
&["fun : {} -[[thunk(5) [A Str]*, thunk(5) { a : Str }]]-> Str",]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_phantom_type() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
F a b := b
|
||||
|
||||
foo : F Str Str -> F U8 Str
|
||||
|
||||
x : F Str Str
|
||||
|
||||
foo x
|
||||
"#
|
||||
),
|
||||
"F U8 Str",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_phantom_type_flow() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
F a b := b
|
||||
|
||||
foo : _ -> F U8 Str
|
||||
foo = \it -> it
|
||||
|
||||
foo
|
||||
"#
|
||||
),
|
||||
"F U8 Str -> F U8 Str",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_unbound_phantom_type_star() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
F a b := b
|
||||
|
||||
foo = \@F {} -> @F ""
|
||||
|
||||
foo
|
||||
"#
|
||||
),
|
||||
"F * {}* -> F * Str",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9369,4 +9369,71 @@ All branches in an `if` must have the same type!
|
|||
a -> Str
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
same_phantom_types_unify,
|
||||
indoc!(
|
||||
r#"
|
||||
F a b := b
|
||||
|
||||
foo : F Str Str -> {}
|
||||
|
||||
x : F Str Str
|
||||
|
||||
foo x
|
||||
"#
|
||||
),
|
||||
@r"" // okay
|
||||
);
|
||||
|
||||
test_report!(
|
||||
different_phantom_types,
|
||||
indoc!(
|
||||
r#"
|
||||
F a b := b
|
||||
|
||||
foo : F Str Str -> {}
|
||||
|
||||
x : F U8 Str
|
||||
|
||||
foo x
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─
|
||||
|
||||
The 1st argument to `foo` is not what I expect:
|
||||
|
||||
10│ foo x
|
||||
^
|
||||
|
||||
This `x` value is a:
|
||||
|
||||
F U8 Str
|
||||
|
||||
But `foo` needs the 1st argument to be:
|
||||
|
||||
F Str Str
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
#[ignore = "TODO This should be a type error"]
|
||||
phantom_type_bound_to_ability_not_implementing,
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [x] to "./platform"
|
||||
|
||||
Foo has foo : a -> a | a has Foo
|
||||
|
||||
F a b := b | a has Foo
|
||||
|
||||
Hash := {}
|
||||
|
||||
x : F Hash {}
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue