working feature

This commit is contained in:
Sébastien Besnier 2020-11-04 09:49:19 +01:00
parent 3479f61820
commit 5273896981
3 changed files with 95 additions and 18 deletions

View file

@ -220,8 +220,16 @@ pub fn canonicalize_expr<'a>(
(answer, output) (answer, output)
} }
Err(CanonicalizeFieldProblem::InvalidOptionalValue) => ( Err(CanonicalizeRecordProblem::InvalidOptionalValue {
Expr::RuntimeError(roc_problem::can::RuntimeError::InvalidOptionalRecord), field_name,
field_region,
record_region,
}) => (
Expr::RuntimeError(roc_problem::can::RuntimeError::InvalidOptionalValue {
field_name,
field_region,
record_region,
}),
Output::default(), Output::default(),
), ),
} }
@ -254,8 +262,16 @@ pub fn canonicalize_expr<'a>(
}, },
output, output,
), ),
Err(CanonicalizeFieldProblem::InvalidOptionalValue) => ( Err(CanonicalizeRecordProblem::InvalidOptionalValue {
Expr::RuntimeError(roc_problem::can::RuntimeError::InvalidOptionalRecord), field_name,
field_region,
record_region,
}) => (
Expr::RuntimeError(roc_problem::can::RuntimeError::InvalidOptionalValue {
field_name,
field_region,
record_region,
}),
Output::default(), Output::default(),
), ),
} }
@ -979,13 +995,20 @@ where
} }
} }
enum CanonicalizeRecordProblem {
InvalidOptionalValue {
field_name: Lowercase,
field_region: Region,
record_region: Region,
},
}
fn canonicalize_fields<'a>( fn canonicalize_fields<'a>(
env: &mut Env<'a>, env: &mut Env<'a>,
var_store: &mut VarStore, var_store: &mut VarStore,
scope: &mut Scope, scope: &mut Scope,
region: Region, region: Region,
fields: &'a [Located<ast::AssignedField<'a, ast::Expr<'a>>>], fields: &'a [Located<ast::AssignedField<'a, ast::Expr<'a>>>],
) -> Result<(SendMap<Lowercase, Field>, Output), CanonicalizeFieldProblem> { ) -> Result<(SendMap<Lowercase, Field>, Output), CanonicalizeRecordProblem> {
let mut can_fields = SendMap::default(); let mut can_fields = SendMap::default();
let mut output = Output::default(); let mut output = Output::default();
@ -1011,9 +1034,20 @@ fn canonicalize_fields<'a>(
output.references = output.references.union(field_out.references); output.references = output.references.union(field_out.references);
} }
Err(invalid_optional_value @ CanonicalizeFieldProblem::InvalidOptionalValue) => { Err(CanonicalizeFieldProblem::InvalidOptionalValue {
env.problems.push(Problem::InvalidOptionalRecord); field_name,
return Err(invalid_optional_value); field_region,
}) => {
env.problems.push(Problem::InvalidOptionalValue {
field_name: field_name.clone(),
field_region,
record_region: region,
});
return Err(CanonicalizeRecordProblem::InvalidOptionalValue {
field_name,
field_region,
record_region: region,
});
} }
} }
} }
@ -1022,9 +1056,11 @@ fn canonicalize_fields<'a>(
} }
enum CanonicalizeFieldProblem { enum CanonicalizeFieldProblem {
InvalidOptionalValue, InvalidOptionalValue {
field_name: Lowercase,
field_region: Region,
},
} }
fn canonicalize_field<'a>( fn canonicalize_field<'a>(
env: &mut Env<'a>, env: &mut Env<'a>,
var_store: &mut VarStore, var_store: &mut VarStore,
@ -1049,7 +1085,10 @@ fn canonicalize_field<'a>(
)) ))
} }
OptionalValue(_, _, _) => Err(CanonicalizeFieldProblem::InvalidOptionalValue), OptionalValue(label, _, loc_expr) => Err(CanonicalizeFieldProblem::InvalidOptionalValue {
field_name: Lowercase::from(label.value),
field_region: loc_expr.region,
}),
// A label with no value, e.g. `{ name }` (this is sugar for { name: name }) // A label with no value, e.g. `{ name }` (this is sugar for { name: name })
LabelOnly(_) => { LabelOnly(_) => {

View file

@ -40,7 +40,11 @@ pub enum Problem {
field_region: Region, field_region: Region,
replaced_region: Region, replaced_region: Region,
}, },
InvalidOptionalRecord, InvalidOptionalValue {
field_name: Lowercase,
record_region: Region,
field_region: Region,
},
DuplicateTag { DuplicateTag {
tag_name: TagName, tag_name: TagName,
@ -103,7 +107,11 @@ pub enum RuntimeError {
original_region: Region, original_region: Region,
shadow: Located<Ident>, shadow: Located<Ident>,
}, },
InvalidOptionalRecord, InvalidOptionalValue {
field_name: Lowercase,
record_region: Region,
field_region: Region,
},
// Example: (5 = 1 + 2) is an unsupported pattern in an assignment; Int patterns aren't allowed in assignments! // Example: (5 = 1 + 2) is an unsupported pattern in an assignment; Int patterns aren't allowed in assignments!
UnsupportedPattern(Region), UnsupportedPattern(Region),
// Example: when 1 is 1.X -> 32 // Example: when 1 is 1.X -> 32

View file

@ -179,8 +179,23 @@ pub fn can_problem<'b>(
alloc.reflow(" definitions from this record."), alloc.reflow(" definitions from this record."),
]), ]),
]), ]),
Problem::InvalidOptionalRecord => alloc.stack(vec![ Problem::InvalidOptionalValue {
alloc.reflow("This record contains optional values, it shouldn't!") field_name,
field_region,
record_region,
} => alloc.stack(vec![
alloc.concat(vec![
alloc.reflow("This record uses an optional value for the "),
alloc.record_field(field_name.clone()),
alloc.reflow(" field in an incorrect context!"),
]),
alloc.region_all_the_things(
record_region,
field_region,
field_region,
Annotation::Error,
),
alloc.reflow("You can only use optinal values in record destructuring."),
]), ]),
Problem::DuplicateRecordFieldType { Problem::DuplicateRecordFieldType {
field_name, field_name,
@ -537,9 +552,24 @@ fn pretty_runtime_error<'b>(
tip, tip,
]) ])
} }
RuntimeError::InvalidOptionalRecord => { RuntimeError::InvalidOptionalValue {
alloc.reflow("There is an inappropriate optional field in a record") field_name,
} field_region,
record_region,
} => alloc.stack(vec![
alloc.concat(vec![
alloc.reflow("This record uses an optional value for the "),
alloc.record_field(field_name.clone()),
alloc.reflow(" field in an incorrect context!"),
]),
alloc.region_all_the_things(
record_region,
field_region,
field_region,
Annotation::Error,
),
alloc.reflow("You can only use optinal values in record destructuring."),
]),
RuntimeError::InvalidRecordUpdate { region } => alloc.stack(vec![ RuntimeError::InvalidRecordUpdate { region } => alloc.stack(vec![
alloc.concat(vec![ alloc.concat(vec![
alloc.reflow("This expression cannot be updated"), alloc.reflow("This expression cannot be updated"),