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