Bug 22569 – emplace silently escapes @safe

Status
NEW
Severity
normal
Priority
P3
Component
druntime
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2021-12-04T15:07:43Z
Last change time
2024-12-07T13:41:35Z
Assigned to
No Owner
Creator
Stanislav Blinov
Moved to GitHub: dmd#17432 →

Comments

Comment #0 by stanislav.blinov — 2021-12-04T15:07:43Z
void* global; @safe void main() { import core.lifetime : emplace; int local; emplace(&global, &local); // this compiles, even with dip1000 global = &local; // this does not, as well it shouldn't } --- A more generic example: struct Escapist { void* p; this()(return scope void* p) { this.p = p; } } Escapist escape; @safe void main() { int value; import core.lifetime : emplace; emplace(&escape, &value); // compiles escape.__ctor(&value); // does not compile } --- Problem is, `emplace` is supposed to initialize the uninitialized, and with current rules there doesn't seem to be a way to make it infer correctly when pointers are involved. You can make a version that takes a generator (i.e. a lazy or a scope delegate), but you do need a cast to call the target ctor, and that cast, having to be lowered from @safe to @trusted, loses lifetime information.
Comment #1 by stanislav.blinov — 2021-12-04T15:09:25Z
Correction: you'd need a cast not to call the target ctor, but to emulate one, because struct initialization in D is not uniform. One of the various code paths in the `emplace` implementation does this.
Comment #2 by robert.schadek — 2024-12-07T13:41:35Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17432 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB