mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 15:03:46 +00:00
Record with optionally-typed fields cannot be derived for decoding
This commit is contained in:
parent
958f64c8fc
commit
d2b9cc056f
2 changed files with 64 additions and 7 deletions
|
@ -6,8 +6,10 @@ use roc_module::symbol::Symbol;
|
|||
use roc_region::all::{Loc, Region};
|
||||
use roc_solve_problem::{TypeError, UnderivableReason, Unfulfilled};
|
||||
use roc_types::num::NumericRange;
|
||||
use roc_types::subs::{instantiate_rigids, Content, FlatType, GetSubsSlice, Rank, Subs, Variable};
|
||||
use roc_types::types::{AliasKind, Category, MemberImpl, PatternCategory};
|
||||
use roc_types::subs::{
|
||||
instantiate_rigids, Content, FlatType, GetSubsSlice, Rank, RecordFields, Subs, Variable,
|
||||
};
|
||||
use roc_types::types::{AliasKind, Category, MemberImpl, PatternCategory, RecordField};
|
||||
use roc_unify::unify::{Env, MustImplementConstraints};
|
||||
use roc_unify::unify::{MustImplementAbility, Obligated};
|
||||
|
||||
|
@ -476,7 +478,11 @@ trait DerivableVisitor {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_record(var: Variable) -> Result<Descend, DerivableError> {
|
||||
fn visit_record(
|
||||
_subs: &Subs,
|
||||
var: Variable,
|
||||
_fields: RecordFields,
|
||||
) -> Result<Descend, DerivableError> {
|
||||
Err(DerivableError::NotDerivable(var))
|
||||
}
|
||||
|
||||
|
@ -574,7 +580,7 @@ trait DerivableVisitor {
|
|||
}
|
||||
}
|
||||
Record(fields, ext) => {
|
||||
let descend = Self::visit_record(var)?;
|
||||
let descend = Self::visit_record(subs, var, fields)?;
|
||||
if descend.0 {
|
||||
push_var_slice!(fields.variables());
|
||||
if !matches!(
|
||||
|
@ -682,7 +688,11 @@ impl DerivableVisitor for DeriveEncoding {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_record(_var: Variable) -> Result<Descend, DerivableError> {
|
||||
fn visit_record(
|
||||
_subs: &Subs,
|
||||
_var: Variable,
|
||||
_fields: RecordFields,
|
||||
) -> Result<Descend, DerivableError> {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
|
||||
|
@ -753,8 +763,21 @@ impl DerivableVisitor for DeriveDecoding {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn visit_record(_var: Variable) -> Result<Descend, DerivableError> {
|
||||
Ok(Descend(true))
|
||||
fn visit_record(
|
||||
subs: &Subs,
|
||||
var: Variable,
|
||||
fields: RecordFields,
|
||||
) -> Result<Descend, DerivableError> {
|
||||
let has_optional_field = subs
|
||||
.get_subs_slice(fields.record_fields())
|
||||
.iter()
|
||||
.any(|field| matches!(field, RecordField::Optional(..)));
|
||||
|
||||
if has_optional_field {
|
||||
Err(DerivableError::NotDerivable(var))
|
||||
} else {
|
||||
Ok(Descend(true))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -10507,4 +10507,38 @@ All branches in an `if` must have the same type!
|
|||
Note: `Decoding` cannot be generated for functions.
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
record_with_optional_field_types_cannot_derive_decoding,
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" imports [Decode.{Decoder, DecoderFormatting, decoder}] provides [main] to "./platform"
|
||||
|
||||
main =
|
||||
myDecoder : Decoder {x : Str, y ? Str} fmt | fmt has DecoderFormatting
|
||||
myDecoder = decoder
|
||||
|
||||
myDecoder
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─
|
||||
|
||||
This expression has a type that does not implement the abilities it's expected to:
|
||||
|
||||
5│ myDecoder = decoder
|
||||
^^^^^^^
|
||||
|
||||
Roc can't generate an implementation of the `Decode.Decoding` ability
|
||||
for
|
||||
|
||||
{ x : Str, y ? Str }
|
||||
|
||||
Note: I can't derive decoding for a record with an optional field,
|
||||
which in this case is `.y`. Optional record fields are polymorphic over
|
||||
records that may or may not contain them at compile time, but are not
|
||||
a concept that extends to runtime!
|
||||
Maybe you wanted to use a `Result`?
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue