[Issue 14242] destruction of static arrays with elaborate destructor elements does not propagate attributes
https://issues.dlang.org/show_bug.cgi?id=14242 Mike Franklinchanged: What|Removed |Added Status|NEW |RESOLVED CC||slavo5...@yahoo.com Resolution|--- |WORKSFORME --- Comment #1 from Mike Franklin --- This appears to have been fixed in 2.068.2. I cannot reproduce it in the latest compiler (2.079.0) either. Resolving as WORKSFORME. --
[Issue 17961] std.uni does not compile with -unittest -dip1000
https://issues.dlang.org/show_bug.cgi?id=17961 --- Comment #11 from Carsten Blüggel--- (In reply to hsteoh from comment #10) > Link: https://github.com/dlang/phobos/pull/6041 Due to lack of acceptance I closed PR https://github.com/dlang/phobos/pull/6041. Maybe https://github.com/dlang/phobos/pull/6212 will come to the rescue. --
[Issue 18557] Types with 0 size should not be usable as aa key types
https://issues.dlang.org/show_bug.cgi?id=18557 Ketmar Darkchanged: What|Removed |Added CC||ket...@ketmar.no-ip.org --- Comment #3 from Ketmar Dark --- this patch breaks Variant: it is legal to use `This[This]` as a placeholder type in Variant, and with the patch applied that code doesn't compiles anymore ('cause `This` is defined as `struct This;`). adding real definition to `This` doesn't help too, 'cause then dmd errored with "recursive template expansion". --
[Issue 18564] core.demangle exception Range violation
https://issues.dlang.org/show_bug.cgi?id=18564 --- Comment #1 from Rainer Schuetze--- Did you try latest dmd master? There have been a couple of recent fixes that look similar, e.g. https://issues.dlang.org/show_bug.cgi?id=18300 and https://issues.dlang.org/show_bug.cgi?id=18208. --
[Issue 18542] DMD could generate better assembly for common range check idioms
https://issues.dlang.org/show_bug.cgi?id=18542 Ketmar Darkchanged: What|Removed |Added CC||ket...@ketmar.no-ip.org --
[Issue 18567] New: immutability hole related to context pointers accessed through const pure methods
https://issues.dlang.org/show_bug.cgi?id=18567 Issue ID: 18567 Summary: immutability hole related to context pointers accessed through const pure methods Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: critical Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: timon.g...@gmx.ch DMD 2.079.0 void main(){ int i = 0; struct S{ const(int)* fun()const pure{ return } } immutable S s; static const(int)* foo(immutable(S) s)pure{ return s.fun(); } immutable(int) *pi=foo(s); import std.stdio; writeln(*pi); // 0 i+=1; writeln(*pi); // 1 } I.e. the data *pi is typed as immutable(int), yet changes. --
[Issue 18566] New: const on method of nested data type is not applied to variables in context
https://issues.dlang.org/show_bug.cgi?id=18566 Issue ID: 18566 Summary: const on method of nested data type is not applied to variables in context Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: timon.g...@gmx.ch void main(){ int i = 0; struct S{ int *fun()const pure{ return // compiles, but shouldn't } } } The type of i within "fun" should be "const(int)". --
[Issue 18563] context pointer inside structs constness problems
https://issues.dlang.org/show_bug.cgi?id=18563 Ketmar Darkchanged: What|Removed |Added CC||ket...@ketmar.no-ip.org --
[Issue 18541] comparison `==` of two typeid() should always be rewritten as a "is"
https://issues.dlang.org/show_bug.cgi?id=18541 --- Comment #9 from Ketmar Dark--- compiler transforms `==` for objects to virtual call, and dmd cannot devirtualize calls (yet? ;-). so yeah, no inlining. it is quite possible to rewrite the call into `e1 is e1 || .object.opEquals(e1, e2)`, tho. --- a/src/ddmd/opover.d +++ b/src/ddmd/opover.d @@ -30,6 +30,7 @@ import ddmd.globals; import ddmd.id; import ddmd.identifier; import ddmd.mtype; +import ddmd.sideeffect; import ddmd.statement; import ddmd.tokens; import ddmd.visitor; @@ -1162,7 +1163,7 @@ extern (C++) Expression op_overload(Expression e, Scope* sc) if (!(cd1.cpp || cd2.cpp)) { /* Rewrite as: - * .object.opEquals(e1, e2) + * e1 is e2 || .object.opEquals(e1, e2) */ Expression e1x = e.e1; Expression e2x = e.e2; @@ -1176,12 +1177,38 @@ extern (C++) Expression op_overload(Expression e, Scope* sc) if (cd2.isInterfaceDeclaration()) e2x = new CastExp(e.loc, e.e2, t2.isMutable() ? to : to.constOf()); +/* create temporaries, to avoid invalid rewriting of this: + *if (arr[i++] is obj || .object.opEquals(arr[i++], obj) + * rewrite to: + *tmp1 = e1x, tmp2 = e2x, then use temps + */ +// load e1x to temporary +auto tmp1 = copyToTemp(STCnodtor, "__opEqualsTmp1", e1x); +auto e1xtmp = new CommaExp(e.loc, new DeclarationExp(e.loc, tmp1), new VarExp(e.loc, tmp1)); + +// load e2x to temporary +auto tmp2 = copyToTemp(STCnodtor, "__opEqualsTmp2", e2x); +auto e2xtmp = new CommaExp(e.loc, new DeclarationExp(e.loc, tmp2), new VarExp(e.loc, tmp2)); + +// e1 is e2 +auto expis = new IdentityExp(TOKidentity, e.loc, e1xtmp, e2xtmp); + +// and use fresh varexps with temps (previous ones can be changed by semanticing) +e1x = new VarExp(e.loc, tmp1); +e2x = new VarExp(e.loc, tmp2); + +// .object.opEquals(e1, e2) result = new IdentifierExp(e.loc, Id.empty); result = new DotIdExp(e.loc, result, Id.object); result = new DotIdExp(e.loc, result, Id.eq); result = new CallExp(e.loc, result, e1x, e2x); + +// expis || result +result = new LogicalExp(e.loc, TOKoror, expis, result); + if (e.op == TOKnotequal) result = new NotExp(e.loc, result); + result = result.semantic(sc); return; } --
[Issue 18562] expression is not evaluated when accessing manifest constant
https://issues.dlang.org/show_bug.cgi?id=18562 Ketmar Darkchanged: What|Removed |Added CC||ket...@ketmar.no-ip.org --
[Issue 18560] find on infinite ranges is broken
https://issues.dlang.org/show_bug.cgi?id=18560 Ketmar Darkchanged: What|Removed |Added CC||ket...@ketmar.no-ip.org --
[Issue 18565] New: std.regex Captures opAssign returns void since v2.079.0
https://issues.dlang.org/show_bug.cgi?id=18565 Issue ID: 18565 Summary: std.regex Captures opAssign returns void since v2.079.0 Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: regression Priority: P1 Component: phobos Assignee: nob...@puremagic.com Reporter: d.b...@webfreak.org Before commit 59520969ef73eaf0691972ee00b389e5bbc4c8fb this code used to work: --- import std.regex; void main() { string str; Captures!string match; if (cast(bool)(match = str.matchFirst("a")) || cast(bool)(match = str.matchFirst("b"))) {} } --- and it performed the expected operations. However now the compilation fails with: --- a.d(7): Error: cannot cast expression match.opAssign(matchFirst(str, "a")) of type void to bool a.d(8): Error: cannot cast expression match.opAssign(matchFirst(str, "b")) of type void to bool --- --
[Issue 17448] Move semantics cause memory corruption and cryptic bugs
https://issues.dlang.org/show_bug.cgi?id=17448 --- Comment #30 from Andrei Alexandrescu--- Indeed it seems we are not supporting registration by address with ease for D value types. There are good reasons for that; by allowing value types to be moved around we avoid a swath of complications and difficulties that C++ encounters with their definition of rvalue references and move constructors. That C++ feature complicates all code considerably and still has a variety of safety, correctness, and efficiency issues (I am not exaggerating; all three problems are present) that make the bread and butter of advanced C++ instructors worldwide, including myself. I think we got the better deal there. The disadvantage is that indeed an object can be born and die at different addresses. So self-registering objects by address, or objects holding internal pointers, do not work with automatic allocation. Such is the nature of automatic allocation in D. (It should be noted that C++ has its own, distinct issues with self-registering objects, to which I dedicate several slides in http://erdani.com/index.php/training/mc1xd.) Allow me to make a few suggestions for workarounds: * Avoid automatic/stack allocation and also return by value. A struct may hold internal pointers and a constant address as long as the memory it's in is not automatic/stack. If you use raw memory in conjunction with functions such as emplace and destroy, you have good control. As a perk, you avoid the creation, copying, and destruction of spurious objects - which comes along with calls to register/unregister, which I assume has a significant cost. * Use a "cookie", not an address, in the registration. A classic registration pattern returns a cookie/handle, usually an integer, which the object stores. Then, the object passes that cookie back to the unregister function. In other words, if the address of an object isn't invariant, let's define something that is. * Use dynamic allocation in conjunction with reference counting. I know this has been mentioned and dismissed as too expensive, but I'm mentioning it for completeness. Also, it's one of those cases in which engineering can go a long way: use a high-performance allocator (for which we have a solid framework in the standard library), duplicate objects lazily, etc. If after exploring these and other solutions you come to the conclusion they are not satisfactory, I encourage you to create a DIP. Two possible lines of attack are: (1) Allow specifying that an object can't be moved (2) Allow a type to intercept its move by means of a nothrow hook Drawing from extensive experience with Phobos and its very generic code, I can tell you I foresee difficulties with (1). Anything that makes types "more special than others" is bound to cause a smorgasbord of special handling in the library. I think (2) would be a better angle because it encapsulates the handling with the type. Thanks! --
[Issue 18541] comparison `==` of two typeid() should always be rewritten as a "is"
https://issues.dlang.org/show_bug.cgi?id=18541 Ketmar Darkchanged: What|Removed |Added CC||ket...@ketmar.no-ip.org --
[Issue 18564] core.demangle exception Range violation
https://issues.dlang.org/show_bug.cgi?id=18564 johanenge...@weka.io changed: What|Removed |Added Keywords||mangling --
[Issue 18564] core.demangle exception Range violation
https://issues.dlang.org/show_bug.cgi?id=18564 johanenge...@weka.io changed: What|Removed |Added Keywords||industry CC||r.sagita...@gmx.de --
[Issue 18564] New: core.demangle exception Range violation
https://issues.dlang.org/show_bug.cgi?id=18564 Issue ID: 18564 Summary: core.demangle exception Range violation Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: druntime Assignee: nob...@puremagic.com Reporter: johanenge...@weka.io Testcase: ``` import core.demangle; import std.stdio; void main() { enum str = "UVVUYUUY"; writeln(demangleType(str)); } ``` Instead of outputting the string, we get: `core.exception.RangeError@core/demangle.d(230): Range violation` (found by fuzz testing, but I get a range violation on the same line with a real world type mangle too) --
[Issue 18561] postblit should allow writing const/immutable members just like constructors
https://issues.dlang.org/show_bug.cgi?id=18561 --- Comment #5 from Steven Schveighoffer--- (In reply to anonymous4 from comment #3) > a.__ctor(1); This is another bug. One should only be able to call const __ctor on a struct once, before using it. --
[Issue 18561] postblit should allow writing const/immutable members just like constructors
https://issues.dlang.org/show_bug.cgi?id=18561 --- Comment #4 from ajiesk...@gmail.com --- (In reply to anonymous4 from comment #3) > This passes: > --- > struct A > { > int a; > this(int b) const { a=b; } > } > int main() > { > const A a; > assert(a.a==0,"0"); > a.__ctor(1); > assert(a.a==1,"1"); > return 0; > } > --- I believe it should not. Yes, constructor should be able to do that, but only when used as a constructor. But it is a separate issue from this one. --
[Issue 9983] inout type can not be used as a parameter for structure template
https://issues.dlang.org/show_bug.cgi?id=9983 Martin Nowakchanged: What|Removed |Added CC||c...@dawg.eu Severity|normal |enhancement --
[Issue 18134] BitArray >>= broken when length % (8 * size_t.sizeof) == 0
https://issues.dlang.org/show_bug.cgi?id=18134 github-bugzi...@puremagic.com changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --
[Issue 18134] BitArray >>= broken when length % (8 * size_t.sizeof) == 0
https://issues.dlang.org/show_bug.cgi?id=18134 --- Comment #3 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/b211347454b70fdb5a539f3fd8bc82fcec846e70 Fix issue 18134 - BitArray right shift broken if length is multiple of 8*size_t.sizeof https://github.com/dlang/phobos/commit/6264e40d8abbb411d4391b3cf8c4d2d4c69423e1 Merge pull request #6110 from byebye/issue_18134 Fix issue 18134 - BitArray right shift broken if length is multiple of 8*size_t.sizeof merged-on-behalf-of: Jack Stouffer--
[Issue 17448] Move semantics cause memory corruption and cryptic bugs
https://issues.dlang.org/show_bug.cgi?id=17448 Jonathan M Davischanged: What|Removed |Added CC||issues.dl...@jmdavisprog.co ||m --- Comment #29 from Jonathan M Davis --- (In reply to Tomer Filiba (weka) from comment #27) > I don't suppose this would help. It seems the & operator is just not allowed > in safe code: > > void main() @safe { > int x; > auto tmp = // Error: cannot take address of local x in @safe > function > } That code becomes @safe with -dip1000, because then it's inferred as scope, and the compiler verifies that it doesn't escape, whereas without DIP 1000 and its improvements to scope, the compiler doesn't have any way to ensure that the resulting pointer is used in an @safe manner. So, DIP 1000 should have a fairly large impact on how @safe certain operations are. (In reply to Tomer Filiba (weka) from comment #28) > My point is, @safe is so constrained that it's practically unusable, so I > don't consider it a viable solution for this problem. That would be highly dependent on what your code is doing and how willing you are to vet code and mark functions @trusted where appropriate or use @trusted lambdas to mark sections of code as @trusted (which isn't the most ideal solution for marking a section of code as @trusted, but it's the best we have right now). If you're constantly doing stuff like taking the address of a local variable, then yes, @safe is going to be a miserable mess (though DIP 1000 may fix that). But a lot of code can be @safe with no problem. It really depends on the type of stuff your code is doing. --
[Issue 17448] Move semantics cause memory corruption and cryptic bugs
https://issues.dlang.org/show_bug.cgi?id=17448 --- Comment #28 from Tomer Filiba (weka)--- My point is, @safe is so constrained that it's practically unusable, so I don't consider it a viable solution for this problem. --
[Issue 17448] Move semantics cause memory corruption and cryptic bugs
https://issues.dlang.org/show_bug.cgi?id=17448 --- Comment #27 from Tomer Filiba (weka)--- (In reply to Andrei Alexandrescu from comment #25) > > So... more special cases? > > That's a straight use of scope per DIP 1000, in fact the very design intent: > scope in a function signature specifies the function won't escape the > parameter. I don't suppose this would help. It seems the & operator is just not allowed in safe code: void main() @safe { int x; auto tmp = // Error: cannot take address of local x in @safe function } --
[Issue 1985] import expression should return ubyte[] not string
https://issues.dlang.org/show_bug.cgi?id=1985 anonymous4changed: What|Removed |Added Keywords||spec --
[Issue 1985] import expression should return ubyte[] not string
https://issues.dlang.org/show_bug.cgi?id=1985 --- Comment #11 from anonymous4--- I think it's better to replace import expression with intrinsic, say, importText (like std.file.readText). This will also reduce grammar complexity and remove second and rarely used meaning from the import keyword. Due to how rarely import expression is used it confuses newcomers that are used only to it's usage as module import statement. --
[Issue 17448] Move semantics cause memory corruption and cryptic bugs
https://issues.dlang.org/show_bug.cgi?id=17448 --- Comment #26 from Eyal--- What solution is there for this use-case then? We need objects to register themselves (i.e: set out-of-scope pointers to point at them) and RAII-wise have them de-register themselves. While they are registered, we need a guarantee that they won't be moved. Doesn't sound like D has any solution for us here? 1) We can't use classes, because: 1.A) they are hard to use without GC 1.B) cannot reasonably nest classes so they re-use the same allocation as the container class 1.C) cannot easily allocate them on the stack 2) We can't use structs, because there's no way to make sure structs aren't moved when they're registered. In my experience, this use-case of registered objects is extremely common. Immovable structs, even if those require some effort, sound like they should be well worth virtually any effort they'd require. In practice, we use structs for this, and we don't really have a choice so we'll keep using structs. But D is fighting us here, instead of helping us. --
[Issue 18561] postblit should allow writing const/immutable members just like constructors
https://issues.dlang.org/show_bug.cgi?id=18561 --- Comment #3 from anonymous4--- This passes: --- struct A { int a; this(int b) const { a=b; } } int main() { const A a; assert(a.a==0,"0"); a.__ctor(1); assert(a.a==1,"1"); return 0; } --- --
[Issue 17448] Move semantics cause memory corruption and cryptic bugs
https://issues.dlang.org/show_bug.cgi?id=17448 --- Comment #25 from Andrei Alexandrescu--- (In reply to Tomer Filiba (weka) from comment #24) > > We should address this situation by having writeln take scope inputs. It > > does > > not escape any pointers. > > So... more special cases? That's a straight use of scope per DIP 1000, in fact the very design intent: scope in a function signature specifies the function won't escape the parameter. > > I think immovability is a red herring. The problem is a pointer is escaped > > and it shouldn't be. Even if the struct were immovable, you could construct > > other cases in which gets messed up. > > Of course I could *make* it fail, but that would require me doing memcpy or > what not. It escapes the type system. I'm trying to make it work or fail > inside the type system. > > The whole point is that `struct S` cannot tell how people will use it. The > author thought people would just do > > void func() { > auto s = S(100); > // ... > // when s goes out of scope it will cancel the callback > } > > The author tried to prevent people from shooting themselves in the foot by > making the struct immovable. But then someone added a wrapper function that > returns a `struct S`. This second author knew the struct is immovable and > trusted the type system so his changes would either not compile, or compile > but never move the object. The code works in the happy flow, but when > things go south, all of the sudden you get cryptic bugs that take many days > -- and a lot of luck -- to track down. > > In this specific example, the struct registers a timer to be called in XX > seconds and kill the operation. Other examples could be a struct that adds > itself to a link-list and removes itself when it's destroyed. > > It doesn't make sense that C++ gives me this guarantee, but D fools me into > thinking my code is okay when in fact it isn't. It's not an implementation > detail or an optimization -- it's a semantic guarantee. What I'm saying is the problem is different: the address of this should not escape a non-scope method (including the constructor), we're in a world of trouble regardless whether we introduce a new feature regarding movability. --
[Issue 18563] New: context pointer inside structs constness problems
https://issues.dlang.org/show_bug.cgi?id=18563 Issue ID: 18563 Summary: context pointer inside structs constness problems Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: shac...@weka.io The following program does not compile: void main() { struct S { uint value; ~this() { } } const S a = S(12); S b = a; } test.d(10): Error: cannot implicitly convert expression a of type const(S) to S The reason is that the context pointer stored in a is const, and thus implies that the context it points to is also const. This cannot be copied to the non-const context pointer in b. This context pointer is not, however, actually treated as const. The following code compiles and passes: unittest { int i = 0; struct S { int n; void fun() const { i++; } } const S s; assert(i == 0); s.fun(); assert(i == 1); } Full discussion thread at https://forum.dlang.org/thread/p7lp2b$1jod$1...@digitalmars.com I would argue that the correct solution is to allow the assignment. --
[Issue 17448] Move semantics cause memory corruption and cryptic bugs
https://issues.dlang.org/show_bug.cgi?id=17448 --- Comment #24 from Tomer Filiba (weka)--- > We should address this situation by having writeln take scope inputs. It does > not escape any pointers. So... more special cases? > I think immovability is a red herring. The problem is a pointer is escaped > and it shouldn't be. Even if the struct were immovable, you could construct > other cases in which gets messed up. Of course I could *make* it fail, but that would require me doing memcpy or what not. It escapes the type system. I'm trying to make it work or fail inside the type system. The whole point is that `struct S` cannot tell how people will use it. The author thought people would just do void func() { auto s = S(100); // ... // when s goes out of scope it will cancel the callback } The author tried to prevent people from shooting themselves in the foot by making the struct immovable. But then someone added a wrapper function that returns a `struct S`. This second author knew the struct is immovable and trusted the type system so his changes would either not compile, or compile but never move the object. The code works in the happy flow, but when things go south, all of the sudden you get cryptic bugs that take many days -- and a lot of luck -- to track down. In this specific example, the struct registers a timer to be called in XX seconds and kill the operation. Other examples could be a struct that adds itself to a link-list and removes itself when it's destroyed. It doesn't make sense that C++ gives me this guarantee, but D fools me into thinking my code is okay when in fact it isn't. It's not an implementation detail or an optimization -- it's a semantic guarantee. --
[Issue 18562] expression is not evaluated when accessing manifest constant
https://issues.dlang.org/show_bug.cgi?id=18562 FeepingCreaturechanged: What|Removed |Added Keywords||wrong-code --
[Issue 17448] Move semantics cause memory corruption and cryptic bugs
https://issues.dlang.org/show_bug.cgi?id=17448 --- Comment #23 from Andrei Alexandrescu--- (In reply to Tomer Filiba (weka) from comment #21) > Walter, the @safe-ty aspects of the issue are one thing. In real code, @safe > is hardly workable, i.e. > > void main() { > int x; > writeln();// Error: cannot take address of local `x` in `@safe` > function `main` > } We should address this situation by having writeln take scope inputs. It does not escape any pointers. > It's either you go whole nine yards and implement a full-blown > borrow-checker like rust, or impose very strict (and sometimes arbitrary) > limitations that practically make it unusable. We believe there's a third way, but the burden of proof is indeed on us. > But @safe-aside, the *more important* aspect here that the compiler must > provide a guarantee of *never moving* structs that are marked `@disable > this(this)` or `pragma(immovable)` or with any other syntax. It's a semantic > contract with the compiler, not an optimization. > > So for example, a desired outcome might be for this not to compile: > > pragma(immovable) struct S { > int x; > } > S func() { > return S(100); > } > void main() { > S s = func(); > } > > Should the compile be unable to rewrite this as pass-by-reference. > > I hope it makes the problem clear, again, @safe is really not the issue > here. It's the guarantees provided by move semantics. I think immovability is a red herring. The problem is a pointer is escaped and it shouldn't be. Even if the struct were immovable, you could construct other cases in which gets messed up. (Thinking of supporting the notion of immovable objects - it would have huge ripples. Already supporting structs with @disable this(); and/or @disable this(this); in the standard library is a recurring (and still ongoing) nightmare. Dealing with immovability on top of that would make a lot of code a lot heavier.) --
[Issue 18561] postblit should allow writing const/immutable members just like constructors
https://issues.dlang.org/show_bug.cgi?id=18561 Steven Schveighofferchanged: What|Removed |Added Hardware|x86 |All OS|Windows |All --
[Issue 18561] postblit should allow writing const/immutable members just like constructors
https://issues.dlang.org/show_bug.cgi?id=18561 Steven Schveighofferchanged: What|Removed |Added Status|RESOLVED|REOPENED CC||schvei...@yahoo.com Resolution|DUPLICATE |--- Summary|postblit behaves|postblit should allow |inconsistently with |writing const/immutable |constants |members just like ||constructors --- Comment #2 from Steven Schveighoffer --- I think the OP has a point here. A more direct example: struct S { const char[] t; this(this) { t = t.dup; // this should be allowed // t[0] = 'w'; // this should not } } S s; // Should be OK, calls postblit, s2 is new data. auto s2 = s; // error cannot overwrite const (does not call postblit). This happens already s = s2; essentially, when READING `this`, all normal rules apply. When WRITING members of `this`, everything should be considered tail-X, where X is const, immutable, etc. If we have any immutable or const data as members, the compiler should have already forbade it if you couldn't overwrite it before the postblit. It's the same as constructors, but for constructors, `this` didn't exist yet. If we get to a postblit on a type that has const or immutable data, we have the same guarantee. This does not address postblits being called on const data types (with `this` being mutable during the postblit). That is a different bug. --
[Issue 18561] postblit behaves inconsistently with constants
https://issues.dlang.org/show_bug.cgi?id=18561 ag0ae...@gmail.com changed: What|Removed |Added Status|NEW |RESOLVED CC||ag0ae...@gmail.com Resolution|--- |DUPLICATE --- Comment #1 from ag0ae...@gmail.com --- (In reply to Ajieskola from comment #0) > Postblits behave inconsistently with constants. As shown in the second > example, it cannot modify members which are declared as const. But if that > is wrong, the first one should compile neither, as all the members should be > treated as const when the whole variable is const. The first example shouldn't compile. `title = title.dup;` doesn't do any actual harm, because you're not altering the original. But consider `title[0] = 'W';`. Now you're changing the original `title` to "Wondon bridge", and you're doing it through a `const` reference. That should not be possible. Even worse, the original title could be `immutable`: import std.stdio; struct placeAtWorldMap { char[] title; this(this) { title[0] = 'W'; /* ! */ } } void main() { immutable char[] title = "London bridge".dup; const place = const placeAtWorldMap(title); const samePlace = place; title.writeln; // Wondon bridge } Issue 18357 already covers that problem. Closing as DUPLICATE. Feel free to revert if you think it's not an exact duplicate. *** This issue has been marked as a duplicate of issue 18357 *** --
[Issue 18357] can break immutable with postblit
https://issues.dlang.org/show_bug.cgi?id=18357 ag0ae...@gmail.com changed: What|Removed |Added CC||ajiesk...@gmail.com --- Comment #1 from ag0ae...@gmail.com --- *** Issue 18561 has been marked as a duplicate of this issue. *** --
[Issue 18560] find on infinite ranges is broken
https://issues.dlang.org/show_bug.cgi?id=18560 ag0ae...@gmail.com changed: What|Removed |Added Keywords||wrong-code CC||ag0ae...@gmail.com --- Comment #3 from ag0ae...@gmail.com --- That makes it a codegen bug. foo isn't pure so it must be executed for the side effects. The compiler cannot skip the execution just because the result isn't really used. --
[Issue 18562] New: expression is not evaluated when accessing manifest constant
https://issues.dlang.org/show_bug.cgi?id=18562 Issue ID: 18562 Summary: expression is not evaluated when accessing manifest constant Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: default_357-l...@yahoo.de Consider: struct Struct { enum Enum = 5; } Struct foo() { while (true) { } return Struct(); } void main() { auto value = foo().Enum; assert(false); } The assert trips, despite the fact that foo() should loop indefinitely, because the compiler optimizes away the call to foo entirely. This is highly unintuitive and also responsible for bug #18560 . Is this really intended? --
[Issue 18561] New: postblit behaves inconsistently with constants
https://issues.dlang.org/show_bug.cgi?id=18561 Issue ID: 18561 Summary: postblit behaves inconsistently with constants Product: D Version: D2 Hardware: x86 OS: Windows Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: ajiesk...@gmail.com This compiles: import std.array; import std.stdio; import std.algorithm; struct placeAtWorldMap { char[] title; int[2] coordsMicroDeg; this(this) { title = title.dup; } } void main() { char[] title = "London bridge".dup; const place = placeAtWorldMap(title, [51_508_038, -87_693]); const samePlace = place; "falling down ".copy(title); place.title.writeln; // falling down samePlace.title.writeln; // London bridge readln; } This does not: import std.array; import std.stdio; import std.algorithm; struct placeAtWorldMap { const char[] title; int[2] coordsMicroDeg; this(char[] name, int[2] coords) { // you can assign const members here this.title = name; this.coordsMicroDeg = coords; } this(this) { // remove to compile title = title.dup;// cannot modify ´const´ expression ´this.title´ } } void main() { char[] title = "London bridge".dup; const place = placeAtWorldMap(title, [51_508_038, -87_693]); const newPlace = placeAtWorldMap("Big Ben".dup, [51_500_749, -124_611]); const samePlace = place; "falling down ".copy(title); place.title.writeln; // falling down samePlace.title.writeln; // London bridge (but falling down without the postblit causing the error) newPlace.title.writeln; // Big Ben } Postblits behave inconsistently with constants. As shown in the second example, it cannot modify members which are declared as const. But if that is wrong, the first one should compile neither, as all the members should be treated as const when the whole variable is const. Postblits should behave either like member functions -no mutation of const whatsover- or like constructors -allow mutating the variable once-. I tend to think it should be the latter of the two, since postblits are initializing an object, just like constructiors. --
[Issue 18560] find on infinite ranges is broken
https://issues.dlang.org/show_bug.cgi?id=18560 --- Comment #2 from FeepingCreature--- No, this is the actual problem! struct Struct { enum Enum = 5; } bool fooEvaluated; Struct foo() { fooEvaluated = true; return Struct(); } assert(foo().Enum == 5); assert(fooEvaluated == true); Should this last assert pass? Right now it doesn't, because foo() is never evaluated because Enum is enum. This means that in any and all, the find() never runs. --
[Issue 18560] find on infinite ranges is broken
https://issues.dlang.org/show_bug.cgi?id=18560 --- Comment #1 from FeepingCreature--- The actual problem seems to be that expression.empty actually presumes that expression terminates. So when .all checks for find.empty, it fails to account for the case that find does not terminate, in which situation the behavior is logically undefined. --
[Issue 18551] Improve hint for "does not override any function
https://issues.dlang.org/show_bug.cgi?id=18551 --- Comment #2 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/89243bdc93ef220f85e53d18a0c8521fc43afead Fix Issue 18551 - Improve hint for does not override any function https://github.com/dlang/dmd/commit/bc85c44e819a9ceaf14c33970a07e1105aaf5a93 Merge pull request #7984 from RazvanN7/Issue_18551 Fix Issue 18551 - Improve hint for does not override any function merged-on-behalf-of: Mike Franklin--
[Issue 18560] New: find on infinite ranges is broken
https://issues.dlang.org/show_bug.cgi?id=18560 Issue ID: 18560 Summary: find on infinite ranges is broken Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: default_357-l...@yahoo.de Consider: assert(true.repeat.all != false); We may expect this to hang indefinitely. We will certainly not expect it to fail immediately! What happens is this. true.repeat is an infinite range. all searches for a place at which its condition becomes false. For this, it employs find. Find uses "empty" to signal success, ie. it returns an empty range if the element was not found. However, in this case find *cannot* return an empty range because the Repeat range type can never be empty. It compiles anyways. This then leads to .empty concluding, correctly, that find may never return an empty range, and immediately, without evaluating its input range, returning false. Either all must not be implemented on top of find, or find must be adjusted to signal failure in some other way, possibly using a VariantN. --
[Issue 18560] find on infinite ranges is broken
https://issues.dlang.org/show_bug.cgi?id=18560 FeepingCreaturechanged: What|Removed |Added Severity|enhancement |normal --