mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 10:49:54 +00:00
fix: unintended behavior for collections
This commit is contained in:
parent
daf01f3cf2
commit
7d7849b493
9 changed files with 66 additions and 17 deletions
|
@ -2661,13 +2661,27 @@ impl PyCodeGenerator {
|
|||
self.emit_push_null();
|
||||
self.emit_load_name_instr(Identifier::public("Str"));
|
||||
}
|
||||
other if other.is_array() => {
|
||||
self.emit_push_null();
|
||||
self.emit_load_name_instr(Identifier::public("Array"));
|
||||
}
|
||||
_ => {
|
||||
wrapped = false;
|
||||
}
|
||||
other => match &other.qual_name()[..] {
|
||||
"Array" => {
|
||||
self.emit_push_null();
|
||||
self.emit_load_name_instr(Identifier::public("Array"));
|
||||
}
|
||||
"Dict" => {
|
||||
self.emit_push_null();
|
||||
self.emit_load_name_instr(Identifier::public("Dict"));
|
||||
}
|
||||
"Set" => {
|
||||
self.emit_push_null();
|
||||
self.emit_load_name_instr(Identifier::public("Set"));
|
||||
}
|
||||
"Tuple" => {
|
||||
self.emit_push_null();
|
||||
self.emit_load_name_instr(Identifier::public("tuple"));
|
||||
}
|
||||
_ => {
|
||||
wrapped = false;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
match expr {
|
||||
|
|
|
@ -2160,19 +2160,19 @@ impl Context {
|
|||
generic_array,
|
||||
vis.clone(),
|
||||
Const,
|
||||
Some(FUNC_LIST),
|
||||
Some(ARRAY),
|
||||
);
|
||||
self.register_builtin_type(arr_t, array_, vis.clone(), Const, Some(FUNC_LIST));
|
||||
self.register_builtin_type(arr_t, array_, vis.clone(), Const, Some(ARRAY));
|
||||
self.register_builtin_type(
|
||||
mono(GENERIC_SET),
|
||||
generic_set,
|
||||
vis.clone(),
|
||||
Const,
|
||||
Some(FUNC_SET),
|
||||
Some(SET),
|
||||
);
|
||||
self.register_builtin_type(set_t, set_, vis.clone(), Const, Some(FUNC_SET));
|
||||
self.register_builtin_type(g_dict_t, generic_dict, vis.clone(), Const, Some(FUNC_DICT));
|
||||
self.register_builtin_type(dict_t, dict_, vis.clone(), Const, Some(FUNC_DICT));
|
||||
self.register_builtin_type(set_t, set_, vis.clone(), Const, Some(SET));
|
||||
self.register_builtin_type(g_dict_t, generic_dict, vis.clone(), Const, Some(DICT));
|
||||
self.register_builtin_type(dict_t, dict_, vis.clone(), Const, Some(DICT));
|
||||
self.register_builtin_type(mono(BYTES), bytes, vis.clone(), Const, Some(BYTES));
|
||||
self.register_builtin_type(
|
||||
mono(GENERIC_TUPLE),
|
||||
|
|
10
crates/erg_compiler/lib/std.d/Set.d.er
Normal file
10
crates/erg_compiler/lib/std.d/Set.d.er
Normal file
|
@ -0,0 +1,10 @@
|
|||
.Set: ClassType
|
||||
.Set.
|
||||
copy: |T|(self: .Set(T)) -> .Set(T)
|
||||
differece: |T|(self: .Set(T), other: .Set(T)) -> .Set(T)
|
||||
intersection: |T|(self: .Set(T), other: .Set(T)) -> .Set(T)
|
||||
isdisjoint: |T|(self: .Set(T), other: .Set(T)) -> Bool
|
||||
issubset: |T|(self: .Set(T), other: .Set(T)) -> Bool
|
||||
issuperset: |T|(self: .Set(T), other: .Set(T)) -> Bool
|
||||
symmetric_difference: |T|(self: .Set(T), other: .Set(T)) -> .Set(T)
|
||||
union: |T|(self: .Set(T), other: .Set(T)) -> .Set(T)
|
2
crates/erg_compiler/lib/std/_erg_dict.py
Normal file
2
crates/erg_compiler/lib/std/_erg_dict.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
class Dict(dict):
|
||||
pass
|
2
crates/erg_compiler/lib/std/_erg_set.py
Normal file
2
crates/erg_compiler/lib/std/_erg_set.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
class Set(set):
|
||||
pass
|
|
@ -14,6 +14,8 @@ from _erg_bool import Bool
|
|||
from _erg_bytes import Bytes
|
||||
from _erg_str import Str, StrMut
|
||||
from _erg_array import Array
|
||||
from _erg_dict import Dict
|
||||
from _erg_set import Set
|
||||
from _erg_in_operator import in_operator
|
||||
from _erg_mutate_operator import mutate_operator
|
||||
|
||||
|
|
|
@ -80,15 +80,21 @@ You cannot cast to unrelated types or subtypes with ``as``.
|
|||
## Forced casting
|
||||
|
||||
You can use `typing.cast` to force casting. This can convert the target to any type.
|
||||
In Python, `typing.cast` does nothing at runtime, but in Erg the conversion will be performed by the constructor. This is to protect type safety.
|
||||
In Python, `typing.cast` does nothing at runtime, but in Erg the conversion will be performed by the constructor if object's type is built-in[<sup id="f1">1</sup>](#1).
|
||||
For non-built-in types, the safety is not guaranteed at all.
|
||||
|
||||
```python
|
||||
typing = pyimport "typing"
|
||||
|
||||
C = Class { .x = Int }
|
||||
|
||||
s = typing.cast Str, 1
|
||||
|
||||
assert s == "1"
|
||||
print! s + "a" # 1a
|
||||
|
||||
c = typing.cast C, 1
|
||||
print! c.x # AttributeError: 'int' object has no attribute 'x'
|
||||
```
|
||||
|
||||
## Downcasting
|
||||
|
@ -104,6 +110,10 @@ IntTryFromFloat.
|
|||
else: Error "conversion failed".
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<span id="1" style="font-size:x-small"><sup>1</sup> This conversion is a byproduct of the current implementation and will be removed in the future. [↩](#f1) </span>
|
||||
|
||||
<p align='center'>
|
||||
<a href='./16_subtyping.md'>Previous</a> | <a href='./18_mut.md'>Next</a>
|
||||
</p>
|
||||
|
|
|
@ -75,8 +75,8 @@ i: Int
|
|||
i as (Int or Str)
|
||||
i as (1..10)
|
||||
i as {I: Int | I >= 0}
|
||||
|
||||
```
|
||||
|
||||
<p align='center'>
|
||||
<a href='./15_quantified.md'>Previous</a> | <a href='./17_type_casting.md'>Next</a>
|
||||
</p>
|
||||
|
|
|
@ -83,16 +83,21 @@ s = n as Str # ERR
|
|||
|
||||
`typing.cast`を使って、型を強制的にキャストすることができます。
|
||||
これは対象をどんな型にでも変換出来ます。
|
||||
Pythonの`typing.cast`はランタイムに何も行わない関数ですが、Ergではコンストラクタによる変換が入ります。
|
||||
これは型安全性を保護するためです。
|
||||
Pythonの`typing.cast`はランタイムに何も行わない関数ですが、Ergでは組み込み型の場合コンストラクタによる変換が入ります[<sup id="f1">1</sup>](#1)。
|
||||
組み込み型でない場合、変換は入らず、安全性の保証は全くありません。
|
||||
|
||||
```python
|
||||
typing = pyimport "typing"
|
||||
|
||||
C = Class { .x = Int }
|
||||
|
||||
s = typing.cast Str, 1
|
||||
|
||||
assert s == "1"
|
||||
print! s + "a" # 1a
|
||||
|
||||
c = typing.cast C, 1
|
||||
print! c.x # AttributeError: 'int' object has no attribute 'x'
|
||||
```
|
||||
|
||||
## ダウンキャスト
|
||||
|
@ -108,6 +113,10 @@ IntTryFromFloat.
|
|||
else: Error "conversion failed"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
<span id="1" style="font-size:x-small"><sup>1</sup> この変換は現状の実装による副産物であり、将来的には除去される。[↩](#f1) </span>
|
||||
|
||||
<p align='center'>
|
||||
<a href='./16_subtyping.md'>Previous</a> | <a href='./18_mut.md'>Next</a>
|
||||
</p>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue