@@ -1619,6 +1619,15 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
16191619 }
16201620 }
16211621
1622+ bool is_hashable (ASR::ttype_t * object_type) {
1623+ if (ASR::is_a<ASR::List_t>(*object_type)
1624+ || ASR::is_a<ASR::Dict_t>(*object_type)
1625+ || ASR::is_a<ASR::Set_t>(*object_type)) {
1626+ return false ;
1627+ }
1628+ return true ;
1629+ }
1630+
16221631 AST::expr_t * get_var_intent_and_annotation (AST::expr_t *annotation, ASR::intentType &intent) {
16231632 if (AST::is_a<AST::Subscript_t>(*annotation)) {
16241633 AST::Subscript_t *s = AST::down_cast<AST::Subscript_t>(annotation);
@@ -1730,6 +1739,17 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
17301739 if (AST::is_a<AST::Name_t>(*s->m_slice ) || AST::is_a<AST::Subscript_t>(*s->m_slice )) {
17311740 ASR::ttype_t *type = ast_expr_to_asr_type (loc, *s->m_slice ,
17321741 is_allocatable, is_const, raise_error, abi, is_argument);
1742+ if (!is_hashable (type)) {
1743+ diag.add (diag::Diagnostic (
1744+ " Unhashable type: '" + ASRUtils::type_to_str (type) + " '" ,
1745+ diag::Level::Error, diag::Stage::Semantic, {
1746+ diag::Label (" Mutable type '" + ASRUtils::type_to_str (type)
1747+ + " ' cannot be stored in a set." ,
1748+ {s->m_slice ->base .loc })
1749+ })
1750+ );
1751+ throw SemanticAbort ();
1752+ }
17331753 return ASRUtils::TYPE (ASR::make_Set_t (al, loc, type));
17341754 } else {
17351755 throw SemanticError (" Only Name in Subscript supported for now in `set`"
@@ -1765,6 +1785,17 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
17651785 }
17661786 ASR::ttype_t *key_type = ast_expr_to_asr_type (loc, *t->m_elts [0 ],
17671787 is_allocatable, is_const, raise_error, abi, is_argument);
1788+ if (!is_hashable (key_type)) {
1789+ diag.add (diag::Diagnostic (
1790+ " Unhashable type: '" + ASRUtils::type_to_str (key_type) + " '" ,
1791+ diag::Level::Error, diag::Stage::Semantic, {
1792+ diag::Label (" Mutable type '" + ASRUtils::type_to_str (key_type)
1793+ + " ' cannot become a key in dict. Hint: Use an immutable type for key." ,
1794+ {t->m_elts [0 ]->base .loc })
1795+ })
1796+ );
1797+ throw SemanticAbort ();
1798+ }
17681799 ASR::ttype_t *value_type = ast_expr_to_asr_type (loc, *t->m_elts [1 ],
17691800 is_allocatable, is_const, raise_error, abi, is_argument);
17701801 raise_error_when_dict_key_is_float_or_complex (key_type, loc);
@@ -3808,7 +3839,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
38083839 ai.m_step , type, nullptr );
38093840 return false ;
38103841 } else if (ASR::is_a<ASR::Dict_t>(*type)) {
3811- throw SemanticError (" unhashable type in dict: 'slice'" , loc);
3842+ throw SemanticError (" Unhashable type in dict: 'slice'" , loc);
38123843 }
38133844 } else if (AST::is_a<AST::Tuple_t>(*m_slice) &&
38143845 ASRUtils::is_array (type)) {
@@ -6134,6 +6165,17 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
61346165 ASR::expr_t *key = ASRUtils::EXPR (tmp);
61356166 if (key_type == nullptr ) {
61366167 key_type = ASRUtils::expr_type (key);
6168+ if (!is_hashable (key_type)) {
6169+ diag.add (diag::Diagnostic (
6170+ " Unhashable type: '" + ASRUtils::type_to_str (key_type) + " '" ,
6171+ diag::Level::Error, diag::Stage::Semantic, {
6172+ diag::Label (" Mutable type '" + ASRUtils::type_to_str (key_type)
6173+ + " ' cannot become a key in dict. Hint: Use an immutable type for key." ,
6174+ {key->base .loc })
6175+ })
6176+ );
6177+ throw SemanticAbort ();
6178+ }
61376179 } else {
61386180 if (!ASRUtils::check_equal_type (ASRUtils::expr_type (key), key_type)) {
61396181 throw SemanticError (" All dictionary keys must be of the same type" ,
@@ -6603,6 +6645,17 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
66036645 ASR::expr_t *value = ASRUtils::EXPR (tmp);
66046646 if (type == nullptr ) {
66056647 type = ASRUtils::expr_type (value);
6648+ if (!is_hashable (type)) {
6649+ diag.add (diag::Diagnostic (
6650+ " Unhashable type: '" + ASRUtils::type_to_str (type) + " '" ,
6651+ diag::Level::Error, diag::Stage::Semantic, {
6652+ diag::Label (" Mutable type '" + ASRUtils::type_to_str (type)
6653+ + " ' cannot be stored in a set." ,
6654+ {value->base .loc })
6655+ })
6656+ );
6657+ throw SemanticAbort ();
6658+ }
66066659 } else {
66076660 if (!ASRUtils::check_equal_type (ASRUtils::expr_type (value), type)) {
66086661 throw SemanticError (" All Set values must be of the same type for now" ,
0 commit comments