Check in some more work

This commit is contained in:
Ayaz Hafiz 2022-09-16 16:09:21 -05:00
parent 6adb88beee
commit ac752adc7c
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
6 changed files with 78 additions and 22 deletions

View file

@ -3,7 +3,8 @@ use crate::pattern::DestructType;
use roc_collections::all::HumanIndex; use roc_collections::all::HumanIndex;
use roc_error_macros::internal_error; use roc_error_macros::internal_error;
use roc_exhaustive::{ use roc_exhaustive::{
is_useful, Ctor, CtorName, Error, Guard, Literal, Pattern, RenderAs, TagId, Union, is_useful, Ctor, CtorName, Error, Guard, Literal, Pattern, RedundantReason, RenderAs, TagId,
Union,
}; };
use roc_module::ident::{TagIdIntType, TagName}; use roc_module::ident::{TagIdIntType, TagName};
use roc_module::symbol::ModuleId; use roc_module::symbol::ModuleId;
@ -338,27 +339,31 @@ fn to_nonredundant_rows(subs: &Subs, rows: SketchedRows) -> NonRedundantSummary
.map(|pattern| pattern.reify(subs)) .map(|pattern| pattern.reify(subs))
.collect(); .collect();
let is_useful = { let is_redundant = if !is_inhabited_row(&next_row) {
is_inhabited_row(&next_row) Some(RedundantReason::Uninhabited)
&& ( } else if !(matches!(guard, Guard::HasGuard)
// Anything inhabited with a guard is necessary || is_useful(checked_rows.clone(), next_row.clone()))
matches!(guard, Guard::HasGuard) {
// Make sure that the row doesn't match something we already covered Some(RedundantReason::PreviouslyCovered)
|| is_useful(checked_rows.clone(), next_row.clone()) } else {
) None
}; };
if is_useful { match is_redundant {
None => {
checked_rows.push(next_row); checked_rows.push(next_row);
} else { }
Some(reason) => {
redundancies.push(redundant_mark); redundancies.push(redundant_mark);
errors.push(Error::Redundant { errors.push(Error::Redundant {
overall_region, overall_region,
branch_region: region, branch_region: region,
index: HumanIndex::zero_based(checked_rows.len()), index: HumanIndex::zero_based(checked_rows.len()),
reason,
}); });
} }
} }
}
NonRedundantSummary { NonRedundantSummary {
non_redundant_rows: checked_rows, non_redundant_rows: checked_rows,

View file

@ -92,9 +92,16 @@ pub enum Error {
overall_region: Region, overall_region: Region,
branch_region: Region, branch_region: Region,
index: HumanIndex, index: HumanIndex,
reason: RedundantReason,
}, },
} }
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum RedundantReason {
PreviouslyCovered,
Uninhabited,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Context { pub enum Context {
BadArg, BadArg,

View file

@ -7775,4 +7775,20 @@ mod solve_expr {
"{}", "{}",
); );
} }
#[test]
fn match_on_result_with_uninhabited_error_branch() {
infer_eq_without_problem(
indoc!(
r#"
x : Result Str []
x = Ok "abc"
when x is
Ok s -> s
"#
),
"",
);
}
} }

View file

@ -1064,12 +1064,8 @@ fn result_never() {
res : Result I64 [] res : Result I64 []
res = Ok 4 res = Ok 4
# we should provide this in the stdlib
never : [] -> a
when res is when res is
Ok v -> v Ok v -> v
Err empty -> never empty
#" #"
), ),
4, 4,
@ -1990,3 +1986,21 @@ fn fit_recursive_union_in_struct_into_recursive_pointer() {
RocStr RocStr
); );
} }
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn match_on_result_with_uninhabited_error_branch() {
assert_evals_to!(
indoc!(
r#"
x : Result Str []
x = Ok "abc"
when x is
Ok s -> s
"#
),
RocStr::from("abc"),
RocStr
);
}

View file

@ -1936,3 +1936,16 @@ fn num_width_gt_u8_layout_as_float() {
"# "#
) )
} }
#[mono_test]
fn match_on_result_with_uninhabited_error_branch() {
indoc!(
r#"
x : Result Str []
x = Ok "abc"
when x is
Ok s -> s
"#
)
}

View file

@ -3889,6 +3889,7 @@ fn exhaustive_problem<'a>(
overall_region, overall_region,
branch_region, branch_region,
index, index,
reason: _,
} => { } => {
let doc = alloc.stack([ let doc = alloc.stack([
alloc.concat([ alloc.concat([