diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 2669ccb8fc..4768d42514 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -421,6 +421,8 @@ RUN(NAME test_list_section LABELS cpython llvm c NOFAST) RUN(NAME test_list_count LABELS cpython llvm) RUN(NAME test_list_index LABELS cpython llvm) RUN(NAME test_list_reverse LABELS cpython llvm) +RUN(NAME test_list_pop LABELS cpython llvm NOFAST) # TODO: Remove NOFAST from here. +RUN(NAME test_list_pop2 LABELS cpython llvm NOFAST) # TODO: Remove NOFAST from here. RUN(NAME test_tuple_01 LABELS cpython llvm c) RUN(NAME test_tuple_02 LABELS cpython llvm c NOFAST) RUN(NAME test_tuple_03 LABELS cpython llvm c) diff --git a/integration_tests/test_list_pop.py b/integration_tests/test_list_pop.py new file mode 100644 index 0000000000..51c9f02f45 --- /dev/null +++ b/integration_tests/test_list_pop.py @@ -0,0 +1,68 @@ +from lpython import i32, f64 + +def test_list_pop(): + l1: list[i32] + l2: list[tuple[i32, f64]] + l3: list[list[str]] + i: i32 + j: i32 + total: i32 + x: tuple[i32, f64] + + l1 = [1, 2, 3] + assert l1.pop() == 3 + assert l1 == [1, 2] + + l1 = [] + total = 10 + for i in range(total): + l1.append(i) + if i % 2 == 1: + assert l1.pop() == i + for i in range(total // 2): + assert l1[i] == 2 * i + + l2 = [(1, 2.0)] + x = l2.pop() + assert x == (1, 2.0) + assert len(l2) == 0 + l2.append((2, 3.0)) + assert x == (1, 2.0) + + l3 = [] + for i in range(total): + l3.insert(0, ["a"]) + for j in range(len(l3)): + l3[j] += ["a"] + while len(l3) > 0: + total = len(l3) + assert len(l3.pop()) == total + 1 + assert len(l3) == 0 + + l1 = [0, 1, 2, 3, 4] + assert l1.pop(3) == 3 + assert l1.pop(0) == 0 + assert l1.pop(len(l1) - 1) == 4 + assert l1 == [1, 2] + + total = 10 + l1 = [] + for i in range(total): + l1.append(i) + j = 0 + for i in range(total): + assert l1.pop(j - i) == i + j += 1 + assert len(l1) == 0 + + total = 10 + l2 = [] + for i in range(total): + l2.append((i, f64(i * i))) + j = 0 + for i in range(total): + assert l2.pop(j - i) == (i, f64(i * i)) + j += 1 + assert len(l2) == 0 + +test_list_pop() \ No newline at end of file diff --git a/integration_tests/test_list_pop2.py b/integration_tests/test_list_pop2.py new file mode 100644 index 0000000000..cee56b3684 --- /dev/null +++ b/integration_tests/test_list_pop2.py @@ -0,0 +1,22 @@ +from lpython import i32, f64, InOut + +def pop_wrapper(l: InOut[list[tuple[i32, f64]]], idx: i32) -> tuple[i32, f64]: + return l.pop(idx) + +def test_list_pop(): + l1: list[tuple[i32, f64]] + x: tuple[i32, f64] + i: i32 + + l1 = [(1, 1.0), (2, 4.0), (3, 6.0)] + + x = pop_wrapper(l1, 0) + assert x == (1, 1.0) + + l1.append((4, 8.0)) + assert x == (1, 1.0) + + for i in range(len(l1)): + assert l1[i] == (i + 2, 2.0 * f64(i + 2)) + +test_list_pop() \ No newline at end of file diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl index ccbc950b70..1a056dd484 100644 --- a/src/libasr/ASR.asdl +++ b/src/libasr/ASR.asdl @@ -330,7 +330,6 @@ expr | ListItem(expr a, expr pos, ttype type, expr? value) | TupleItem(expr a, expr pos, ttype type, expr? value) | ListSection(expr a, array_index section, ttype type, expr? value) - | ListPop(expr a, expr? index, ttype type, expr? value) | DictPop(expr a, expr key, ttype type, expr? value) | SetPop(expr a, ttype type, expr? value) | IntegerBitLen(expr a, ttype type, expr? value) diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 02ed511607..0b52b17765 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -2021,6 +2021,32 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor list_api->reverse(plist, asr_el_type, *module); } + void generate_ListPop_0(ASR::expr_t* m_arg) { + ASR::ttype_t* asr_el_type = ASRUtils::get_contained_type(ASRUtils::expr_type(m_arg)); + int64_t ptr_loads_copy = ptr_loads; + ptr_loads = 0; + this->visit_expr(*m_arg); + llvm::Value* plist = tmp; + + ptr_loads = !LLVM::is_llvm_struct(asr_el_type); + ptr_loads = ptr_loads_copy; + tmp = list_api->pop_last(plist, asr_el_type, *module); + } + + void generate_ListPop_1(ASR::expr_t* m_arg, ASR::expr_t* m_ele) { + ASR::ttype_t* asr_el_type = ASRUtils::get_contained_type(ASRUtils::expr_type(m_arg)); + int64_t ptr_loads_copy = ptr_loads; + ptr_loads = 0; + this->visit_expr(*m_arg); + llvm::Value* plist = tmp; + + ptr_loads = 2; + this->visit_expr_wrapper(m_ele, true); + ptr_loads = ptr_loads_copy; + llvm::Value *pos = tmp; + tmp = list_api->pop_position(plist, pos, asr_el_type, module.get(), name2memidx); + } + void visit_IntrinsicFunction(const ASR::IntrinsicFunction_t& x) { switch (static_cast(x.m_intrinsic_id)) { case ASRUtils::IntrinsicFunctions::ListIndex: { @@ -2038,6 +2064,21 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break ; } + case ASRUtils::IntrinsicFunctions::ListReverse: { + generate_ListReverse(x.m_args[0]); + break; + } + case ASRUtils::IntrinsicFunctions::ListPop: { + switch(x.m_overload_id) { + case 0: + generate_ListPop_0(x.m_args[0]); + break; + case 1: + generate_ListPop_1(x.m_args[0], x.m_args[1]); + break; + } + break; + } case ASRUtils::IntrinsicFunctions::Exp: { switch (x.m_overload_id) { case 0: { @@ -2080,10 +2121,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break ; } - case ASRUtils::IntrinsicFunctions::ListReverse: { - generate_ListReverse(x.m_args[0]); - break; - } default: { throw CodeGenError( ASRUtils::IntrinsicFunctionRegistry:: get_intrinsic_function_name(x.m_intrinsic_id) + diff --git a/src/libasr/codegen/llvm_utils.cpp b/src/libasr/codegen/llvm_utils.cpp index d66af1e236..ab5f4fb5eb 100644 --- a/src/libasr/codegen/llvm_utils.cpp +++ b/src/libasr/codegen/llvm_utils.cpp @@ -2915,6 +2915,111 @@ namespace LCompilers { builder->CreateStore(end_point, end_point_ptr); } + llvm::Value* LLVMList::pop_last(llvm::Value* list, ASR::ttype_t* list_type, llvm::Module& module) { + // If list is empty, output error + + llvm::Value* end_point_ptr = get_pointer_to_current_end_point(list); + llvm::Value* end_point = LLVM::CreateLoad(*builder, end_point_ptr); + + llvm::Value* cond = builder->CreateICmpEQ(llvm::ConstantInt::get( + context, llvm::APInt(32, 0)), end_point); + llvm_utils->create_if_else(cond, [&]() { + std::string message = "pop from empty list"; + llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr("IndexError: %s\n"); + llvm::Value *fmt_ptr2 = builder->CreateGlobalStringPtr(message); + print_error(context, module, *builder, {fmt_ptr, fmt_ptr2}); + int exit_code_int = 1; + llvm::Value *exit_code = llvm::ConstantInt::get(context, + llvm::APInt(32, exit_code_int)); + exit(context, module, *builder, exit_code); + }, [=]() { + }); + + // Get last element of list + llvm::Value* tmp = builder->CreateSub(end_point, llvm::ConstantInt::get( + context, llvm::APInt(32, 1))); + tmp = read_item(list, tmp, false, module, LLVM::is_llvm_struct(list_type)); + + // Decrement end point by one + end_point = builder->CreateSub(end_point, llvm::ConstantInt::get( + context, llvm::APInt(32, 1))); + builder->CreateStore(end_point, end_point_ptr); + return tmp; + } + + llvm::Value* LLVMList::pop_position(llvm::Value* list, llvm::Value* pos, + ASR::ttype_t* list_element_type, llvm::Module* module, + std::map>& name2memidx) { + + /* Equivalent in C++: + * while(end_point > pos) { + * tmp = pos + 1; + * list[pos] = list[tmp]; + * pos = tmp; + * } + */ + + llvm::Value* end_point_ptr = get_pointer_to_current_end_point(list); + llvm::Value* end_point = LLVM::CreateLoad(*builder, end_point_ptr); + + llvm::AllocaInst *pos_ptr = builder->CreateAlloca( + llvm::Type::getInt32Ty(context), nullptr); + LLVM::CreateStore(*builder, pos, pos_ptr); + llvm::Value* tmp = nullptr; + + // Get element to return + llvm::Value* item = read_item(list, LLVM::CreateLoad(*builder, pos_ptr), + true, *module, LLVM::is_llvm_struct(list_element_type)); + // TODO: Create a macro for the following code to allocate auxiliary variables + // on stack. + if( LLVM::is_llvm_struct(list_element_type) ) { + std::string list_element_type_code = ASRUtils::get_type_code(list_element_type); + llvm::BasicBlock &entry_block = builder->GetInsertBlock()->getParent()->getEntryBlock(); + llvm::IRBuilder<> builder0(context); + builder0.SetInsertPoint(&entry_block, entry_block.getFirstInsertionPt()); + LCOMPILERS_ASSERT(typecode2listtype.find(list_element_type_code) != typecode2listtype.end()); + llvm::AllocaInst *target = builder0.CreateAlloca( + std::get<2>(typecode2listtype[list_element_type_code]), nullptr, + "pop_position_item"); + llvm_utils->deepcopy(item, target, list_element_type, module, name2memidx); + item = target; + } + + llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head"); + llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body"); + llvm::BasicBlock *loopend = llvm::BasicBlock::Create(context, "loop.end"); + + // head + llvm_utils->start_new_block(loophead); + { + llvm::Value *cond = builder->CreateICmpSGT(end_point, + LLVM::CreateLoad(*builder, pos_ptr)); + builder->CreateCondBr(cond, loopbody, loopend); + } + + // body + llvm_utils->start_new_block(loopbody); + { + tmp = builder->CreateAdd( + LLVM::CreateLoad(*builder, pos_ptr), + llvm::ConstantInt::get(context, llvm::APInt(32, 1))); + write_item(list, LLVM::CreateLoad(*builder, pos_ptr), + read_item(list, tmp, false, *module, false), false, *module); + LLVM::CreateStore(*builder, tmp, pos_ptr); + } + builder->CreateBr(loophead); + + // end + llvm_utils->start_new_block(loopend); + + // Decrement end point by one + end_point = builder->CreateSub(end_point, llvm::ConstantInt::get( + context, llvm::APInt(32, 1))); + builder->CreateStore(end_point, end_point_ptr); + + return item; + } + void LLVMList::list_clear(llvm::Value* list) { llvm::Value* end_point_ptr = get_pointer_to_current_end_point(list); llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), diff --git a/src/libasr/codegen/llvm_utils.h b/src/libasr/codegen/llvm_utils.h index 87648ec06d..106e32ad7f 100644 --- a/src/libasr/codegen/llvm_utils.h +++ b/src/libasr/codegen/llvm_utils.h @@ -259,6 +259,12 @@ namespace LCompilers { void remove(llvm::Value* list, llvm::Value* item, ASR::ttype_t* item_type, llvm::Module& module); + llvm::Value* pop_position(llvm::Value* list, llvm::Value* pos, + ASR::ttype_t* list_type, llvm::Module* module, + std::map>& name2memidx); + + llvm::Value* pop_last(llvm::Value* list, ASR::ttype_t* list_type, llvm::Module& module); + void list_clear(llvm::Value* list); void reverse(llvm::Value* list, ASR::ttype_t* list_type, llvm::Module& module); diff --git a/src/libasr/pass/intrinsic_function_registry.h b/src/libasr/pass/intrinsic_function_registry.h index 61f6067886..6c36d32416 100644 --- a/src/libasr/pass/intrinsic_function_registry.h +++ b/src/libasr/pass/intrinsic_function_registry.h @@ -63,6 +63,7 @@ enum class IntrinsicFunctions : int64_t { ListIndex, Partition, ListReverse, + ListPop, Sum, // ... }; @@ -1057,6 +1058,65 @@ static inline ASR::asr_t* create_ListReverse(Allocator& al, const Location& loc, } // namespace ListReverse +namespace ListPop { + +static inline void verify_args(const ASR::IntrinsicFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args <= 2, "Call to list.pop must have at most one argument", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), + "Argument to list.pop must be of list type", + x.base.base.loc, diagnostics); + switch(x.m_overload_id) { + case 0: + break; + case 1: + ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[1])), + "Argument to list.pop must be an integer", + x.base.base.loc, diagnostics); + break; + } + ASRUtils::require_impl(ASRUtils::check_equal_type(x.m_type, + ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]))), + "Return type of list.pop must be of same type as list's element type", + x.base.base.loc, diagnostics); +} + +static inline ASR::expr_t *eval_list_pop(Allocator &/*al*/, + const Location &/*loc*/, Vec& /*args*/) { + // TODO: To be implemented for ListConstant expression + return nullptr; +} + +static inline ASR::asr_t* create_ListPop(Allocator& al, const Location& loc, + Vec& args, + const std::function err) { + if (args.size() > 2) { + err("Call to list.pop must have at most one argument", loc); + } + if (args.size() == 2 && + !ASR::is_a(*ASRUtils::expr_type(args[1]))) { + err("Argument to list.pop must be an integer", loc); + } + + ASR::expr_t* list_expr = args[0]; + ASR::ttype_t *type = ASRUtils::expr_type(list_expr); + ASR::ttype_t *list_type = ASR::down_cast(type)->m_type; + + Vec arg_values; + arg_values.reserve(al, args.size()); + for( size_t i = 0; i < args.size(); i++ ) { + arg_values.push_back(al, ASRUtils::expr_value(args[i])); + } + ASR::expr_t* compile_time_value = eval_list_pop(al, loc, arg_values); + ASR::ttype_t *to_type = list_type; + int64_t overload_id = (args.size() == 2); + return ASR::make_IntrinsicFunction_t(al, loc, + static_cast(ASRUtils::IntrinsicFunctions::ListPop), + args.p, args.size(), overload_id, to_type, compile_time_value); +} + +} // namespace ListPop + namespace Any { static inline void verify_array(ASR::expr_t* array, ASR::ttype_t* return_type, @@ -1976,6 +2036,8 @@ namespace IntrinsicFunctionRegistry { {&Partition::instantiate_Partition, &Partition::verify_args}}, {static_cast(ASRUtils::IntrinsicFunctions::ListIndex), {nullptr, &ListIndex::verify_args}}, + {static_cast(ASRUtils::IntrinsicFunctions::ListPop), + {nullptr, &ListPop::verify_args}}, {static_cast(ASRUtils::IntrinsicFunctions::ListReverse), {nullptr, &ListReverse::verify_args}}, }; @@ -2014,6 +2076,8 @@ namespace IntrinsicFunctionRegistry { "list.index"}, {static_cast(ASRUtils::IntrinsicFunctions::ListReverse), "list.reverse"}, + {static_cast(ASRUtils::IntrinsicFunctions::ListPop), + "list.pop"}, {static_cast(ASRUtils::IntrinsicFunctions::Any), "any"}, {static_cast(ASRUtils::IntrinsicFunctions::Sum), @@ -2042,6 +2106,7 @@ namespace IntrinsicFunctionRegistry { {"sum", {&Sum::create_Sum, &Sum::eval_Sum}}, {"list.index", {&ListIndex::create_ListIndex, &ListIndex::eval_list_index}}, {"list.reverse", {&ListReverse::create_ListReverse, &ListReverse::eval_list_reverse}}, + {"list.pop", {&ListPop::create_ListPop, &ListPop::eval_list_pop}} }; static inline bool is_intrinsic_function(const std::string& name) { @@ -2088,6 +2153,9 @@ namespace IntrinsicFunctionRegistry { } static inline verify_function get_verify_function(int64_t id) { + if( intrinsic_function_by_id_db.find(id) == intrinsic_function_by_id_db.end() ) { + return nullptr; + } return std::get<1>(intrinsic_function_by_id_db.at(id)); } @@ -2143,6 +2211,7 @@ inline std::string get_intrinsic_name(int x) { INTRINSIC_NAME_CASE(ListIndex) INTRINSIC_NAME_CASE(Partition) INTRINSIC_NAME_CASE(ListReverse) + INTRINSIC_NAME_CASE(ListPop) INTRINSIC_NAME_CASE(Sum) default : { throw LCompilersException("pickle: intrinsic_id not implemented"); diff --git a/src/lpython/semantics/python_attribute_eval.h b/src/lpython/semantics/python_attribute_eval.h index d714f02b7a..5ce7834bb1 100644 --- a/src/lpython/semantics/python_attribute_eval.h +++ b/src/lpython/semantics/python_attribute_eval.h @@ -27,9 +27,9 @@ struct AttributeHandler { {"list@count", &eval_list_count}, {"list@index", &eval_list_index}, {"list@reverse", &eval_list_reverse}, + {"list@pop", &eval_list_pop}, {"list@clear", &eval_list_clear}, {"list@insert", &eval_list_insert}, - {"list@pop", &eval_list_pop}, {"set@pop", &eval_set_pop}, {"set@add", &eval_set_add}, {"set@remove", &eval_set_remove}, @@ -202,6 +202,20 @@ struct AttributeHandler { { throw SemanticError(msg, loc); }); } + static ASR::asr_t* eval_list_pop(ASR::expr_t *s, Allocator &al, const Location &loc, + Vec &args, diag::Diagnostics &/*diag*/) { + Vec args_with_list; + args_with_list.reserve(al, args.size() + 1); + args_with_list.push_back(al, s); + for(size_t i = 0; i < args.size(); i++) { + args_with_list.push_back(al, args[i]); + } + ASRUtils::create_intrinsic_function create_function = + ASRUtils::IntrinsicFunctionRegistry::get_create_function("list.pop"); + return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) + { throw SemanticError(msg, loc); }); + } + static ASR::asr_t* eval_list_insert(ASR::expr_t *s, Allocator &al, const Location &loc, Vec &args, diag::Diagnostics &diag) { if (args.size() != 2) { @@ -233,39 +247,6 @@ struct AttributeHandler { return make_ListInsert_t(al, loc, s, args[0], args[1]); } - static ASR::asr_t* eval_list_pop(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &diag) { - if (args.size() > 1) { - throw SemanticError("pop() takes atmost one argument", - loc); - } - ASR::expr_t *idx = nullptr; - ASR::ttype_t *int_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)); - ASR::ttype_t *type = ASRUtils::expr_type(s); - ASR::ttype_t *list_type = ASR::down_cast(type)->m_type; - if (args.size() == 1) { - ASR::ttype_t *pos_type = ASRUtils::expr_type(args[0]); - if (!ASRUtils::check_equal_type(pos_type, int_type)) { - std::string fnd = ASRUtils::type_to_str_python(pos_type); - std::string org = ASRUtils::type_to_str_python(int_type); - diag.add(diag::Diagnostic( - "Type mismatch in 'pop', List index should be of integer type", - diag::Level::Error, diag::Stage::Semantic, { - diag::Label("type mismatch (found: '" + fnd + "', expected: '" + org + "')", - {args[0]->base.loc}) - }) - ); - throw SemanticAbort(); - } - idx = args[0]; - } else { - // default is last index - idx = (ASR::expr_t*)ASR::make_IntegerConstant_t(al, loc, -1, int_type); - } - - return make_ListPop_t(al, loc, s, idx, list_type, nullptr); - } - static ASR::asr_t* eval_list_clear(ASR::expr_t *s, Allocator &al, const Location &loc, Vec &args, diag::Diagnostics & diag) { if (args.size() != 0) { diff --git a/tests/reference/asr-list1-770ba33.json b/tests/reference/asr-list1-770ba33.json index df1b3be49b..022e066a13 100644 --- a/tests/reference/asr-list1-770ba33.json +++ b/tests/reference/asr-list1-770ba33.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-list1-770ba33.stdout", - "stdout_hash": "f3ba730673d73c97937004763dbe9ea89707a155d12839b3b1b661d1", + "stdout_hash": "864109d0aeeabd4d640e80b6fd0c8f9d392c32c2c8a4d8f6be7c8567", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-list1-770ba33.stderr b/tests/reference/asr-list1-770ba33.stderr new file mode 100644 index 0000000000..ea41c95566 --- /dev/null +++ b/tests/reference/asr-list1-770ba33.stderr @@ -0,0 +1,5 @@ +semantic error: For now pop() takes no arguments + --> tests/list1.py:25:9 + | +25 | d = a.pop(2) + | ^^^^^^^^ diff --git a/tests/reference/asr-list1-770ba33.stdout b/tests/reference/asr-list1-770ba33.stdout index 11c7027b75..aa2fc4964e 100644 --- a/tests/reference/asr-list1-770ba33.stdout +++ b/tests/reference/asr-list1-770ba33.stdout @@ -323,9 +323,10 @@ ) (= (Var 2 d) - (ListPop - (Var 2 a) - (IntegerConstant -1 (Integer 4)) + (IntrinsicFunction + ListPop + [(Var 2 a)] + 0 (Integer 4) () ) @@ -333,9 +334,11 @@ ) (= (Var 2 d) - (ListPop - (Var 2 a) - (IntegerConstant 2 (Integer 4)) + (IntrinsicFunction + ListPop + [(Var 2 a) + (IntegerConstant 2 (Integer 4))] + 1 (Integer 4) () ) diff --git a/tests/reference/asr-test_list3-5f4d2a8.json b/tests/reference/asr-test_list3-5f4d2a8.json index 1975f8b077..09d515e69a 100644 --- a/tests/reference/asr-test_list3-5f4d2a8.json +++ b/tests/reference/asr-test_list3-5f4d2a8.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_list3-5f4d2a8.stderr", - "stderr_hash": "b6924dd90c3e80d22ea270ba6aeaabe9a121e970c650632c44ad8f4e", + "stderr_hash": "3e8e102841bfe5ae8524aa793b39cdf33de7e7073744a01f0049b424", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_list3-5f4d2a8.stderr b/tests/reference/asr-test_list3-5f4d2a8.stderr index 09551bf733..45d1ab0536 100644 --- a/tests/reference/asr-test_list3-5f4d2a8.stderr +++ b/tests/reference/asr-test_list3-5f4d2a8.stderr @@ -1,5 +1,5 @@ -semantic error: Type mismatch in 'pop', List index should be of integer type - --> tests/errors/test_list3.py:5:15 +semantic error: Argument to list.pop must be an integer + --> tests/errors/test_list3.py:5:9 | 5 | x = a.pop(2.2) - | ^^^ type mismatch (found: 'f64', expected: 'i32') + | ^^^^^^^^^^