From d778e82d65411f9b4cc2e43d65a080aa7f2c04f4 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 12 Sep 2020 22:05:08 -0400 Subject: [PATCH] Fix Str.isEmpty --- compiler/gen/src/llvm/build.rs | 14 +++++++++----- compiler/gen/src/llvm/build_str.rs | 14 ++++++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index f411a9ffc1..8d308d9177 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -4,7 +4,7 @@ use crate::llvm::build_list::{ list_join, list_keep_if, list_len, list_map, list_prepend, list_repeat, list_reverse, list_set, list_single, list_walk_right, }; -use crate::llvm::build_str::{str_concat, str_is_not_empty, str_len, CHAR_LAYOUT}; +use crate::llvm::build_str::{str_concat, str_len, CHAR_LAYOUT}; use crate::llvm::compare::{build_eq, build_neq}; use crate::llvm::convert::{ basic_type_from_layout, block_of_memory, collection, get_fn_type, get_ptr_type, ptr_int, @@ -24,8 +24,8 @@ use inkwell::passes::{PassManager, PassManagerBuilder}; use inkwell::types::{BasicTypeEnum, FunctionType, IntType, StructType}; use inkwell::values::BasicValueEnum::{self, *}; use inkwell::values::{BasicValue, FloatValue, FunctionValue, IntValue, PointerValue, StructValue}; -use inkwell::AddressSpace; use inkwell::OptimizationLevel; +use inkwell::{AddressSpace, IntPredicate}; use roc_collections::all::{ImMap, MutSet}; use roc_module::low_level::LowLevel; use roc_module::symbol::{Interns, Symbol}; @@ -1564,8 +1564,13 @@ fn run_low_level<'a, 'ctx, 'env>( let wrapper_ptr = ptr_from_symbol(scope, args[0]); let len = str_len(env, parent, wrapper_ptr.clone()); - - BasicValueEnum::IntValue(str_is_not_empty(env, len)) + let is_zero = env.builder.build_int_compare( + IntPredicate::EQ, + len, + env.ptr_int().const_zero(), + "str_len_is_zero", + ); + BasicValueEnum::IntValue(is_zero) } ListLen => { // List.len : List * -> Int @@ -1707,7 +1712,6 @@ fn run_low_level<'a, 'ctx, 'env>( } NumCompare => { use inkwell::FloatPredicate; - use inkwell::IntPredicate; debug_assert_eq!(args.len(), 2); diff --git a/compiler/gen/src/llvm/build_str.rs b/compiler/gen/src/llvm/build_str.rs index 1b8cc4cdc0..e40f70253d 100644 --- a/compiler/gen/src/llvm/build_str.rs +++ b/compiler/gen/src/llvm/build_str.rs @@ -224,15 +224,21 @@ pub fn str_len<'a, 'ctx, 'env>( ) -> IntValue<'ctx> { let builder = env.builder; - let if_small = |final_byte| BasicValueEnum::IntValue(str_len_from_final_byte(env, final_byte)); + let if_small = |final_byte| { + let len = str_len_from_final_byte(env, final_byte); + + BasicValueEnum::IntValue(len) + }; let if_big = |_| { - BasicValueEnum::IntValue(big_str_len( + let len = big_str_len( builder, builder .build_load(wrapper_ptr, "big_str") .into_struct_value(), - )) + ); + + BasicValueEnum::IntValue(len) }; if_small_str( @@ -438,7 +444,7 @@ fn big_str_len<'ctx>(builder: &Builder<'ctx>, wrapper_struct: StructValue<'ctx>) .into_int_value() } -pub fn str_is_not_empty<'ctx>(env: &Env<'_, 'ctx, '_>, len: IntValue<'ctx>) -> IntValue<'ctx> { +fn str_is_not_empty<'ctx>(env: &Env<'_, 'ctx, '_>, len: IntValue<'ctx>) -> IntValue<'ctx> { env.builder.build_int_compare( IntPredicate::UGT, len,