digitalmars.D.bugs - [Issue 9186] New: Manifest constant can violate const correctness restrictions when empty
- d-bugmail puremagic.com (70/70) Dec 19 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9186
- d-bugmail puremagic.com (12/16) Dec 19 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9186
- d-bugmail puremagic.com (7/19) Dec 19 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9186
- d-bugmail puremagic.com (18/18) Dec 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9186
- d-bugmail puremagic.com (11/12) Dec 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9186
- d-bugmail puremagic.com (13/25) Dec 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9186
http://d.puremagic.com/issues/show_bug.cgi?id=9186 Summary: Manifest constant can violate const correctness restrictions when empty Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: major Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: monarchdodra gmail.com --- Comment #0 from monarchdodra gmail.com 2012-12-19 06:49:46 PST --- The basic use case is having: foo(const(char)[]); and trying to pass a immutable(char)[] to it. Which is illegal. The problem here is that if you define a manifest constant that is empty, and try to pass it to foo, the code will compile: //---- void main() { void foo(const(char)[][]); alias Type = string[]; static assert(is(typeof(Type.init) == Type)); static if (is(typeof(foo(Type.init)))) //Enter here !!! { Type Rbla() property; Type Lbla; enum Type Ebla1 = [[]]; enum Type Ebla2 = ["hello"]; foo(Type.init); //OK! foo(Rbla); foo(Lbla); foo(Ebla1); //OK! foo(Ebla2); } } //---- Error: function dmd2.main.foo (const(char)[][]) is not callable using argument types (string[]) Error: cannot implicitly convert expression (Rbla()) of type string[] to const(char)[][] Error: function dmd2.main.foo (const(char)[][]) is not callable using argument types (string[]) Error: cannot implicitly convert expression (Lbla) of type string[] to const(char)[][] //---- This may not seem like a "huge" problem in and out of itself. The *REAL* problem lies in the static if: "static if (is(typeof(foo(Type.init))))" This code is explicitly written to find out if we can pass a variable of type Type to foo. This is especially true for array types, which are the ones vulnerable to this problem. I'm marking as "Major", because phobos is vulnerable to the bug. Found inside "put": //---- else static if (is(typeof(r.put((E[]).init)))) { r((&e)[0..1]); } //---- src\phobos\std\range.d(590): Error: cannot implicitly convert expression (& e[0u..1u]) of type string[] to const(char)[][] //---- Current workaround is to use an lvalueof type function. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 19 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9186 Andrej Mitrovic <andrej.mitrovich gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrej.mitrovich gmail.com --- Comment #1 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2012-12-19 07:12:53 PST --- (In reply to comment #0)The basic use case is having: foo(const(char)[]); and trying to pass a immutable(char)[] to it. Which is illegal.Since when is that illegal? immutable and mutable both implicitly convert to const. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 19 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9186 --- Comment #2 from monarchdodra gmail.com 2012-12-19 07:26:55 PST --- (In reply to comment #1)(In reply to comment #0)Typo. My apologies:The basic use case is having: foo(const(char)[]); and trying to pass a immutable(char)[] to it. Which is illegal.Since when is that illegal? immutable and mutable both implicitly convert to const.The basic use case is having: foo(const(char)[][]); and trying to pass a "immutable(char)[][]" to it. Which is illegal.-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 19 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9186 --- Comment #3 from Kenji Hara <k.hara.pg gmail.com> 2012-12-21 00:30:27 PST --- This is not a type system problem. All manifest constants, which declared by `enum` and T.init, make literal expressions in the places where they used. alias T = string[]; enum T strs = [[]]; foo(T.init); // same as foo(null); foo(strs); // same as foo([[]]); And, empty array literal and null literal can ignore their type qualifiers in constant-folding process, because they have no references to qualified values. (From the view of compiler development, it is mainly designed by Expression::implicitConvTo.) I can agree that the behavior is not intuitive, but I'm not sure what is the correct behavior... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9186 Max Samukha <samukha voliacable.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |samukha voliacable.com --- Comment #4 from Max Samukha <samukha voliacable.com> 2012-12-21 01:35:54 PST --- (In reply to comment #3)I'm not sure what is the correct behavior...Obviously, the correct behavior is to preserve the type information. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9186 --- Comment #5 from monarchdodra gmail.com 2012-12-21 01:52:11 PST --- (In reply to comment #3)This is not a type system problem. All manifest constants, which declared by `enum` and T.init, make literal expressions in the places where they used. alias T = string[]; enum T strs = [[]]; foo(T.init); // same as foo(null); foo(strs); // same as foo([[]]); And, empty array literal and null literal can ignore their type qualifiers in constant-folding process, because they have no references to qualified values.I see your point, but I argue there is a difference between a "type-less" literal and an "empty" literal. (T[]).init, while empty, does carry a type, and it should be preserved/propagated. Heck, proof that a non-empty literal can have "no type": "[[]]" is *not* empty. It is a type-less slice which carries a single empty typeless slice. Yet you can still write "int[][] a = [[]];" -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 21 2012