いかなる型であってもできない。これはタプル型そのものの値であっても例外ではない。
void main() { alias tuple(A...) = A; tuple!int tup; cast(tuple!int) tup; }
(dmd-2.098.1)$ dmd -c cast.d cast.d(5): Error: cannot cast `__tup_field_0` to tuple type `(int)`
これは2022/01/05時点では仕様には記載されていない。 ちゃんと追ってはいないものの、ざっくりcommit追った感じではずっと前からこの仕様であったらしい。
あと構造体へのキャストを行う場合、 cast(S) x
は S(x)
への書き換えが行われるので以下のコードは合法。
struct S { this(int _) {} } void main() { S s = cast() 42; }
(dmd-2.098.1)$ dmd -c cast2.d (dmd-2.098.1)$ # no compilation error
こちらはドキュメントにひっそりと書いている。
S(v)
追記
以下のようなパッチを当てれば同じタプル型についてはキャストできる。
index 1e5f8b37e..ee54a6a83 100644 --- a/src/dmd/expressionsem.d +++ b/src/dmd/expressionsem.d @@ -7512,6 +7512,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.e1.type.ty == Ttuple) { TupleExp te = exp.e1.isTupleExp(); + if (exp.to) + { + if (TypeTuple tt = exp.to.isTypeTuple()) + { + if (exp.e1.type.equals(tt)) + { + result = exp.e1; + return; + } + } + } if (te.exps.dim == 1) exp.e1 = (*te.exps)[0]; }
あてたDMDのgit revisionもいちおう。
$ git rev-parse HEAD b14861d42ce3da9cf789988621c46dba1102ee0c
(dmd-2.098.1)$ ./dmd/generated/linux/release/64/dmd -c cast.d (dmd-2.098.1)$ # no compileation error
違う型だとエラーになる。
alias tuple(T...) = T; alias mytuple = tuple!(int, int); void main() { mytuple tup; auto tt = cast(tuple!(int, string)) tup; }
(dmd-2.098.1)$ ./dmd/generated/linux/release/64/dmd -c invalid.d invalid.d(7): Error: cannot cast `tuple(__tup_field_0, __tup_field_1)` to tuple type `(int, string)`
追記2
パッチ入りました、2.100から使えるはず。