mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
Merge pull request #3370 from rtfeldman/list-unreachable
List unreachable
This commit is contained in:
commit
7365da6f69
7 changed files with 41 additions and 10 deletions
|
@ -373,17 +373,11 @@ contains = \list, needle ->
|
||||||
## `fold`, `foldLeft`, or `foldl`.
|
## `fold`, `foldLeft`, or `foldl`.
|
||||||
walk : List elem, state, (state, elem -> state) -> state
|
walk : List elem, state, (state, elem -> state) -> state
|
||||||
walk = \list, state, func ->
|
walk = \list, state, func ->
|
||||||
walkHelp list state func 0 (len list)
|
walkHelp = \currentState, element -> Continue (func currentState element)
|
||||||
|
|
||||||
## internal helper
|
when List.iterate list state walkHelp is
|
||||||
walkHelp : List elem, state, (state, elem -> state), Nat, Nat -> state
|
Continue newState -> newState
|
||||||
walkHelp = \list, state, f, index, length ->
|
Break void -> List.unreachable void
|
||||||
if index < length then
|
|
||||||
nextState = f state (getUnsafe list index)
|
|
||||||
|
|
||||||
walkHelp list nextState f (index + 1) length
|
|
||||||
else
|
|
||||||
state
|
|
||||||
|
|
||||||
## Note that in other languages, `walkBackwards` is sometimes called `reduceRight`,
|
## Note that in other languages, `walkBackwards` is sometimes called `reduceRight`,
|
||||||
## `fold`, `foldRight`, or `foldr`.
|
## `fold`, `foldRight`, or `foldr`.
|
||||||
|
@ -841,3 +835,6 @@ iterHelp = \list, state, f, index, length ->
|
||||||
Break b
|
Break b
|
||||||
else
|
else
|
||||||
Continue state
|
Continue state
|
||||||
|
|
||||||
|
## useful for typechecking guaranteed-unreachable cases
|
||||||
|
unreachable : [] -> a
|
||||||
|
|
|
@ -107,6 +107,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||||
STR_TO_I16 => str_to_num,
|
STR_TO_I16 => str_to_num,
|
||||||
STR_TO_U8 => str_to_num,
|
STR_TO_U8 => str_to_num,
|
||||||
STR_TO_I8 => str_to_num,
|
STR_TO_I8 => str_to_num,
|
||||||
|
LIST_UNREACHABLE => roc_unreachable,
|
||||||
LIST_LEN => list_len,
|
LIST_LEN => list_len,
|
||||||
LIST_WITH_CAPACITY => list_with_capacity,
|
LIST_WITH_CAPACITY => list_with_capacity,
|
||||||
LIST_GET_UNSAFE => list_get_unsafe,
|
LIST_GET_UNSAFE => list_get_unsafe,
|
||||||
|
@ -2359,6 +2360,11 @@ fn list_prepend(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List.unreachable : [] -> a
|
||||||
|
fn roc_unreachable(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
|
lowlevel_1(symbol, LowLevel::Unreachable, var_store)
|
||||||
|
}
|
||||||
|
|
||||||
/// List.map : List before, (before -> after) -> List after
|
/// List.map : List before, (before -> after) -> List after
|
||||||
fn list_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn list_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
lowlevel_2(symbol, LowLevel::ListMap, var_store)
|
lowlevel_2(symbol, LowLevel::ListMap, var_store)
|
||||||
|
|
|
@ -6090,6 +6090,20 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
PtrCast | RefCountInc | RefCountDec => {
|
PtrCast | RefCountInc | RefCountDec => {
|
||||||
unreachable!("Not used in LLVM backend: {:?}", op);
|
unreachable!("Not used in LLVM backend: {:?}", op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unreachable => match RocReturn::from_layout(env, layout) {
|
||||||
|
RocReturn::Return => {
|
||||||
|
let basic_type = basic_type_from_layout(env, layout);
|
||||||
|
basic_type.const_zero()
|
||||||
|
}
|
||||||
|
RocReturn::ByPointer => {
|
||||||
|
let basic_type = basic_type_from_layout(env, layout);
|
||||||
|
let ptr = env.builder.build_alloca(basic_type, "unreachable_alloca");
|
||||||
|
env.builder.build_store(ptr, basic_type.const_zero());
|
||||||
|
|
||||||
|
ptr.into()
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1696,6 +1696,17 @@ impl<'a> LowLevelCall<'a> {
|
||||||
BoxExpr | UnboxExpr => {
|
BoxExpr | UnboxExpr => {
|
||||||
unreachable!("The {:?} operation is turned into mono Expr", self.lowlevel)
|
unreachable!("The {:?} operation is turned into mono Expr", self.lowlevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unreachable => match self.ret_storage {
|
||||||
|
StoredValue::VirtualMachineStack { value_type, .. }
|
||||||
|
| StoredValue::Local { value_type, .. } => match value_type {
|
||||||
|
ValueType::I32 => backend.code_builder.i32_const(0),
|
||||||
|
ValueType::I64 => backend.code_builder.i64_const(0),
|
||||||
|
ValueType::F32 => backend.code_builder.f32_const(0.0),
|
||||||
|
ValueType::F64 => backend.code_builder.f64_const(0.0),
|
||||||
|
},
|
||||||
|
StoredValue::StackMemory { .. } => { /* do nothing */ }
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,7 @@ pub enum LowLevel {
|
||||||
RefCountDec,
|
RefCountDec,
|
||||||
BoxExpr,
|
BoxExpr,
|
||||||
UnboxExpr,
|
UnboxExpr,
|
||||||
|
Unreachable,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! higher_order {
|
macro_rules! higher_order {
|
||||||
|
|
|
@ -1271,6 +1271,7 @@ define_builtins! {
|
||||||
61 LIST_REPLACE_UNSAFE: "replaceUnsafe"
|
61 LIST_REPLACE_UNSAFE: "replaceUnsafe"
|
||||||
62 LIST_WITH_CAPACITY: "withCapacity"
|
62 LIST_WITH_CAPACITY: "withCapacity"
|
||||||
63 LIST_ITERATE: "iterate"
|
63 LIST_ITERATE: "iterate"
|
||||||
|
64 LIST_UNREACHABLE: "unreachable"
|
||||||
}
|
}
|
||||||
6 RESULT: "Result" => {
|
6 RESULT: "Result" => {
|
||||||
0 RESULT_RESULT: "Result" // the Result.Result type alias
|
0 RESULT_RESULT: "Result" // the Result.Result type alias
|
||||||
|
|
|
@ -884,6 +884,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||||
// - arguments that we may want to update destructively must be Owned
|
// - arguments that we may want to update destructively must be Owned
|
||||||
// - other refcounted arguments are Borrowed
|
// - other refcounted arguments are Borrowed
|
||||||
match op {
|
match op {
|
||||||
|
Unreachable => arena.alloc_slice_copy(&[irrelevant]),
|
||||||
ListLen | StrIsEmpty | StrToScalars | StrCountGraphemes | StrCountUtf8Bytes => {
|
ListLen | StrIsEmpty | StrToScalars | StrCountGraphemes | StrCountUtf8Bytes => {
|
||||||
arena.alloc_slice_copy(&[borrowed])
|
arena.alloc_slice_copy(&[borrowed])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue