https://issues.dlang.org/show_bug.cgi?id=20437
Issue ID: 20437 Summary: Transitive immutable/shared does not apply to variables captured by delegates Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: rightfold+bugzilla+dl...@gmail.com The following compiles: int x; void delegate() d = delegate() { x = 1; }; immutable(void delegate()) bad1 = d; shared(void delegate()) bad2 = d; And the following, as a result, does too: void delegate() shared { bad1(); bad2(); } This allows you to transfer bad1 or bad2 to another thread, to call it, and modify x without synchronization. * * * Theoretically, a type like void delegate() immutable could be seen as the following: struct dgt_ { int* x; void opCall() immutable; } Whereas a type like immutable(void delegate()) could be seen as the following: struct dgt_ { int* x; void opCall(); }; alias dgt = immutable(dgt_); In the latter case, immutable should apply to x too (similar for shared) but it seemingly doesn’t for actual delegate types. * * * Verified with: - DMD64 D Compiler v2.085.1 - LDC 1.16.0 based on DMD v2.086.1 and LLVM 8.0.1 --