Enable optional record field underivable error

This commit is contained in:
Ayaz Hafiz 2022-08-09 08:48:21 -07:00
parent 55fe1df995
commit e77e53f37b
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
2 changed files with 17 additions and 14 deletions

View file

@ -4,7 +4,9 @@ use roc_collections::{VecMap, VecSet};
use roc_error_macros::{internal_error, todo_abilities}; use roc_error_macros::{internal_error, todo_abilities};
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_region::all::{Loc, Region}; use roc_region::all::{Loc, Region};
use roc_solve_problem::{NotDerivableContext, TypeError, UnderivableReason, Unfulfilled}; use roc_solve_problem::{
NotDerivableContext, NotDerivableDecode, TypeError, UnderivableReason, Unfulfilled,
};
use roc_types::num::NumericRange; use roc_types::num::NumericRange;
use roc_types::subs::{ use roc_types::subs::{
instantiate_rigids, Content, FlatType, GetSubsSlice, Rank, RecordFields, Subs, Variable, instantiate_rigids, Content, FlatType, GetSubsSlice, Rank, RecordFields, Subs, Variable,
@ -837,19 +839,18 @@ impl DerivableVisitor for DeriveDecoding {
var: Variable, var: Variable,
fields: RecordFields, fields: RecordFields,
) -> Result<Descend, NotDerivable> { ) -> Result<Descend, NotDerivable> {
let has_optional_field = subs for (field_name, _, field) in fields.iter_all() {
.get_subs_slice(fields.record_fields()) if matches!(subs[field], RecordField::Optional(..)) {
.iter() return Err(NotDerivable {
.any(|field| matches!(field, RecordField::Optional(..))); var,
context: NotDerivableContext::Decode(NotDerivableDecode::OptionalRecordField(
if has_optional_field { subs[field_name].clone(),
Err(NotDerivable { )),
var, });
context: NotDerivableContext::NoContext, }
})
} else {
Ok(Descend(true))
} }
Ok(Descend(true))
} }
#[inline(always)] #[inline(always)]

View file

@ -425,7 +425,9 @@ fn underivable_hint<'b>(
alloc.reflow("Roc cannot derive decoding for a record with an optional field, which in this case is "), alloc.reflow("Roc cannot derive decoding for a record with an optional field, which in this case is "),
alloc.record_field(field), alloc.record_field(field),
alloc.reflow(". Optional record fields are polymorphic over records that may or may not contain them at compile time, "), alloc.reflow(". Optional record fields are polymorphic over records that may or may not contain them at compile time, "),
alloc.reflow("but are not a concept that extends to runtime! That means Roc cannot derive a decoder for a record with an optional value "), alloc.reflow("but are not a concept that extends to runtime!"),
alloc.hardline(),
alloc.reflow("That means Roc cannot derive a decoder for a record with an optional value "),
alloc.reflow("by way of an optional record field. If you want to model the idea that a field may or may not be present at runtime, "), alloc.reflow("by way of an optional record field. If you want to model the idea that a field may or may not be present at runtime, "),
alloc.reflow("consider using a "), alloc.reflow("consider using a "),
alloc.symbol_unqualified(Symbol::RESULT_RESULT), alloc.symbol_unqualified(Symbol::RESULT_RESULT),