Skip to content

Commit 542300f

Browse files
authored
Throw an error for class objects assignment (#2784)
1 parent c58d31c commit 542300f

File tree

5 files changed

+61
-18
lines changed

5 files changed

+61
-18
lines changed

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5255,24 +5255,26 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
52555255
if ( sym && ASR::is_a<ASR::Variable_t>(*sym) ) {
52565256
ASR::Variable_t* var = ASR::down_cast<ASR::Variable_t>(sym);
52575257
if ( ASR::is_a<ASR::StructType_t>(*(var->m_type)) &&
5258-
!ASR::down_cast<ASR::StructType_t>((var->m_type))->m_is_cstruct &&
5259-
ASR::is_a<ASR::StructConstructor_t>(*init_expr) ) {
5260-
AST::Call_t* call = AST::down_cast<AST::Call_t>(x.m_value);
5261-
if ( call->n_keywords>0 ) {
5262-
throw SemanticError("Kwargs not implemented yet", x.base.base.loc);
5263-
}
5264-
Vec<ASR::call_arg_t> args;
5265-
args.reserve(al, call->n_args + 1);
5266-
ASR::call_arg_t self_arg;
5267-
self_arg.loc = x.base.base.loc;
5268-
self_arg.m_value = ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, sym));
5269-
args.push_back(al, self_arg);
5270-
visit_expr_list(call->m_args, call->n_args, args);
5271-
ASR::symbol_t* der = ASR::down_cast<ASR::StructType_t>((var->m_type))->m_derived_type;
5272-
std::string call_name = "__init__";
5273-
ASR::symbol_t* call_sym = get_struct_member(der, call_name, x.base.base.loc);
5274-
tmp = make_call_helper(al, call_sym, current_scope, args, call_name, x.base.base.loc);
5258+
!ASR::down_cast<ASR::StructType_t>((var->m_type))->m_is_cstruct ) {
5259+
if ( !ASR::is_a<ASR::StructConstructor_t>(*init_expr) ) {
5260+
throw SemanticError("Only Class constructor is allowed in the object assignment for now", x.base.base.loc);
5261+
}
5262+
AST::Call_t* call = AST::down_cast<AST::Call_t>(x.m_value);
5263+
if ( call->n_keywords>0 ) {
5264+
throw SemanticError("Kwargs not implemented yet", x.base.base.loc);
52755265
}
5266+
Vec<ASR::call_arg_t> args;
5267+
args.reserve(al, call->n_args + 1);
5268+
ASR::call_arg_t self_arg;
5269+
self_arg.loc = x.base.base.loc;
5270+
self_arg.m_value = ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, sym));
5271+
args.push_back(al, self_arg);
5272+
visit_expr_list(call->m_args, call->n_args, args);
5273+
ASR::symbol_t* der = ASR::down_cast<ASR::StructType_t>((var->m_type))->m_derived_type;
5274+
std::string call_name = "__init__";
5275+
ASR::symbol_t* call_sym = get_struct_member(der, call_name, x.base.base.loc);
5276+
tmp = make_call_helper(al, call_sym, current_scope, args, call_name, x.base.base.loc);
5277+
}
52765278
}
52775279
}
52785280

@@ -5539,11 +5541,18 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
55395541
if (target->type == ASR::exprType::Var) {
55405542
ASR::Var_t *var = ASR::down_cast<ASR::Var_t>(target);
55415543
ASR::symbol_t *sym = var->m_v;
5544+
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(sym);
55425545
if (do_loop_variables.size() > 0 && std::find(do_loop_variables.begin(), do_loop_variables.end(), sym) != do_loop_variables.end()) {
5543-
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(sym);
55445546
std::string var_name = std::string(v->m_name);
55455547
throw SemanticError("Assignment to loop variable `" + std::string(to_lower(var_name)) +"` is not allowed", target->base.loc);
55465548
}
5549+
if ( ASR::is_a<ASR::StructType_t>(*(v->m_type)) &&
5550+
!ASR::down_cast<ASR::StructType_t>((v->m_type))->m_is_cstruct &&
5551+
!(tmp_value->type == ASR::exprType::StructConstructor) ) {
5552+
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(sym);
5553+
std::string var_name = std::string(v->m_name);
5554+
throw SemanticError("Only Class constructor is allowed in the object assignment for now", target->base.loc);
5555+
}
55475556
}
55485557
tmp_vec.push_back(ASR::make_Assignment_t(al, x.base.base.loc, target, tmp_value,
55495558
overloaded));

tests/errors/class_04.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from lpython import i32
2+
3+
class coord:
4+
def __init__(self:"coord", x:i32, y:i32):
5+
self.x: i32 = x
6+
self.y: i32 = y
7+
8+
p1: coord = coord(1, 2)
9+
p2: coord = p1
10+
p2.x = 2
11+
print(p1.x)
12+
print(p2.x)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "asr-class_04-b89178d",
3+
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
4+
"infile": "tests/errors/class_04.py",
5+
"infile_hash": "e1e1c48050cce1b2855e4f8409aa3d72df716f61b8aa045aa97ae914",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": null,
9+
"stdout_hash": null,
10+
"stderr": "asr-class_04-b89178d.stderr",
11+
"stderr_hash": "7f8e807f5582952b4ad93b1fb3d4d264842a0700aeda5be00611d098",
12+
"returncode": 2
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
semantic error: Only Class constructor is allowed in the object assignment for now
2+
--> tests/errors/class_04.py:9:1
3+
|
4+
9 | p2: coord = p1
5+
| ^^^^^^^^^^^^^^

tests/tests.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@ asr = true
361361
pass = "class_constructor"
362362
cumulative = true
363363

364+
[[test]]
365+
filename = "errors/class_04.py"
366+
asr = true
367+
364368
[[test]]
365369
filename = "../integration_tests/callback_01.py"
366370
asr = true

0 commit comments

Comments
 (0)