mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-20 15:27:45 +03:00
Check in some more work
This commit is contained in:
parent
6adb88beee
commit
ac752adc7c
@ -3,7 +3,8 @@ use crate::pattern::DestructType;
|
||||
use roc_collections::all::HumanIndex;
|
||||
use roc_error_macros::internal_error;
|
||||
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::symbol::ModuleId;
|
||||
@ -338,25 +339,29 @@ fn to_nonredundant_rows(subs: &Subs, rows: SketchedRows) -> NonRedundantSummary
|
||||
.map(|pattern| pattern.reify(subs))
|
||||
.collect();
|
||||
|
||||
let is_useful = {
|
||||
is_inhabited_row(&next_row)
|
||||
&& (
|
||||
// Anything inhabited with a guard is necessary
|
||||
matches!(guard, Guard::HasGuard)
|
||||
// Make sure that the row doesn't match something we already covered
|
||||
|| is_useful(checked_rows.clone(), next_row.clone())
|
||||
)
|
||||
let is_redundant = if !is_inhabited_row(&next_row) {
|
||||
Some(RedundantReason::Uninhabited)
|
||||
} else if !(matches!(guard, Guard::HasGuard)
|
||||
|| is_useful(checked_rows.clone(), next_row.clone()))
|
||||
{
|
||||
Some(RedundantReason::PreviouslyCovered)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if is_useful {
|
||||
checked_rows.push(next_row);
|
||||
} else {
|
||||
redundancies.push(redundant_mark);
|
||||
errors.push(Error::Redundant {
|
||||
overall_region,
|
||||
branch_region: region,
|
||||
index: HumanIndex::zero_based(checked_rows.len()),
|
||||
});
|
||||
match is_redundant {
|
||||
None => {
|
||||
checked_rows.push(next_row);
|
||||
}
|
||||
Some(reason) => {
|
||||
redundancies.push(redundant_mark);
|
||||
errors.push(Error::Redundant {
|
||||
overall_region,
|
||||
branch_region: region,
|
||||
index: HumanIndex::zero_based(checked_rows.len()),
|
||||
reason,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,9 +92,16 @@ pub enum Error {
|
||||
overall_region: Region,
|
||||
branch_region: Region,
|
||||
index: HumanIndex,
|
||||
reason: RedundantReason,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum RedundantReason {
|
||||
PreviouslyCovered,
|
||||
Uninhabited,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Context {
|
||||
BadArg,
|
||||
|
@ -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
|
||||
"#
|
||||
),
|
||||
"",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1064,12 +1064,8 @@ fn result_never() {
|
||||
res : Result I64 []
|
||||
res = Ok 4
|
||||
|
||||
# we should provide this in the stdlib
|
||||
never : [] -> a
|
||||
|
||||
when res is
|
||||
Ok v -> v
|
||||
Err empty -> never empty
|
||||
#"
|
||||
),
|
||||
4,
|
||||
@ -1990,3 +1986,21 @@ fn fit_recursive_union_in_struct_into_recursive_pointer() {
|
||||
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
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
@ -3889,6 +3889,7 @@ fn exhaustive_problem<'a>(
|
||||
overall_region,
|
||||
branch_region,
|
||||
index,
|
||||
reason: _,
|
||||
} => {
|
||||
let doc = alloc.stack([
|
||||
alloc.concat([
|
||||
|
Loading…
Reference in New Issue
Block a user