www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11206] New: static array can be implicitly built from items, when nested in aggregate

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206

           Summary: static array can be implicitly built from items, when
                    nested in aggregate
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: accepts-invalid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: monarchdodra gmail.com


--- Comment #0 from monarchdodra gmail.com 2013-10-09 07:22:40 PDT ---
Just to be clear, I'm not talking about "initial construction", where, eg, this
is correct:

//----
alias ARR = int[1];
struct S{int i;this(int){}}

struct AGG(T)
{
    T t;
}

void main()
{
    S s1 = S(1); //Explicit, OK
    S s2 = 1; //Implicit, OK
    ARR arr1 = [1]; //Explicit, OK
    ARR arr2 = 1; //Implicit, OK
}
//----

This is OK: The table makes an implicit construction, thanks to an explicit
type declaration.

However, if the table is nested inside an aggregate, then this should not
happen: Aggregate construction requires an exact type match (possibly via alias
this), *However*, individual elements *may not* be implicitly constructed from
pass in arguments:

//----
void main()
{
    AGG!S ts2 = AGG!S(S(2)); //Explicit. Good.
    AGG!S ts1 = AGG!S(1); //NO! ILLEGAL REQUEST FOR IMPLICIT CONSTRUCTION!

    AGG!ARR tarr1 = AGG!ARR([1]); //Explicit is good
    AGG!ARR tarr1 = AGG!ARR(1); //This works...? [HERE]
}
//----

[HERE]: This is a violation of the type system. With aggregate initialization,
each argument is supposed to match the type of the aggregated element, or be
*implicitly*castable* to said element. In the case of "element => static array
element", we have neither.

static arrays are the *only* type that allow this. I think making an exception
for static arrays is surprising and wrong. It should be rejected.

Related:
http://d.puremagic.com/issues/show_bug.cgi?id=10973

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 09 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206


Maxim Fomin <maxim maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |maxim maxim-fomin.ru
         Resolution|                            |INVALID


--- Comment #1 from Maxim Fomin <maxim maxim-fomin.ru> 2013-10-09 08:45:45 PDT
---
So, what?

Basically you are complainig about:

import std.stdio;

struct AGG
{
    int[1] t;
    double d;
}

void main()
{
    AGG tarr2 = AGG(1); 
    writeln(tarr2);
}

which prints AGG([1], nan).

AGG(1) is a struct literal which is valid in D. Integer literal is a valid
initializer for static array. Statement "AGG!S ts1 = AGG!S(1);" is rejected
because (unfortunately) 1 is not convertible to struct.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206


monarchdodra gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |


--- Comment #2 from monarchdodra gmail.com 2013-10-09 09:02:30 PDT ---
(In reply to comment #1)
 So, what?
 
 Basically you are complainig about:
 
 import std.stdio;
 
 struct AGG
 {
     int[1] t;
     double d;
 }
 
 void main()
 {
     AGG tarr2 = AGG(1); 
     writeln(tarr2);
 }
 
 which prints AGG([1], nan).
...Unsure what you are trying to show? the "AGG(1)".
 AGG(1) is a struct literal which is valid in D.
I'm arguing that AGG should not be constructible taking a 1.
 Integer literal is a valid
 initializer for static array. Statement "AGG!S ts1 = AGG!S(1);" is rejected
 because (unfortunately) 1 is not convertible to struct.
Yes, integer is a valid initializer for a static array, and it is also a valid initializer for a struct that holds an int. However, 1 is not convertible to a struct, not is it convertible to a static array. AGG(1) should not compile, because 1 is not convertible to typeof(AGG.tupleof[0]); What's happening is an implicit *construction* of a static array, in a context where implicit construction is not allowed. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #3 from Maxim Fomin <maxim maxim-fomin.ru> 2013-10-09 09:38:00 PDT
---
(In reply to comment #2)
 (In reply to comment #1)
 So, what?
 
 Basically you are complainig about:
 
 import std.stdio;
 
 struct AGG
 {
     int[1] t;
     double d;
 }
 
 void main()
 {
     AGG tarr2 = AGG(1); 
     writeln(tarr2);
 }
 
 which prints AGG([1], nan).
...Unsure what you are trying to show? the "AGG(1)".
actually the AGG([1], nan) to show struct literal behavior.
 AGG(1) is a struct literal which is valid in D.
I'm arguing that AGG should not be constructible taking a 1.
That's clear, but if you want to break the language you need to consider writing to newsgroup. Silent language change based on some issue in bugzilla is evil.
 Integer literal is a valid
 initializer for static array. Statement "AGG!S ts1 = AGG!S(1);" is rejected
 because (unfortunately) 1 is not convertible to struct.
Yes, integer is a valid initializer for a static array, and it is also a valid initializer for a struct that holds an int.
Right.
 
 However, 1 is not convertible to a struct, 
Right. It is sad fact but in this context it is irrelevant because in the example there is no conversion from 1 to struct, there is struct literal with partial initializer which match initializer for first field.
 not is it convertible to a static array.
Wrong. int[1] ai = 1; ai = 1; is fine with the language so far. However in this case we speak about struct initializer so having integer literal to be initializer for static integer array is sufficient.
 AGG(1) should not compile, because 1 is not convertible to
 typeof(AGG.tupleof[0]);
Please refer to the spec or argue if spec is incomplete for a particular case. Making up rules is not good. Adressing your point - this is incorrect because typeof(AGG.tupleof[0]) has type int[1] and initializaing or assigning 1 to int[1] is legal in D. I deliberatly unwrapped all templates to show that you are effectivelly protesting against int[1] = 1;
 What's happening is an implicit *construction* of a static array, in a context
 where implicit construction is not allowed.
This is not the case. Here is struct literal with partial list of initializers which match respective type initializers which is fine as far D is concern. If you are complaining because this breaks some assumption of a brilliant phobos ideom, this should be mentioned explicitly so some solution without damaging language can be found (personally I object to break the language for the sake of writing cute template in phobos). Please don't reopen issue: CLOSED->REOPENED->CLOSED war is not good either. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #4 from monarchdodra gmail.com 2013-10-09 13:03:47 PDT ---
(In reply to comment #3)
 (In reply to comment #2)
 I'm arguing that AGG should not be constructible taking a 1.
That's clear, but if you want to break the language you need to consider writing to newsgroup. Silent language change based on some issue in bugzilla is evil.
Filing it in buzilla is the first step.
 Integer literal is a valid
 initializer for static array. Statement "AGG!S ts1 = AGG!S(1);" is rejected
 because (unfortunately) 1 is not convertible to struct.
Yes, integer is a valid initializer for a static array, and it is also a valid initializer for a struct that holds an int.
Right.
 
 However, 1 is not convertible to a struct, 
Right. It is sad fact but in this context it is irrelevant because in the example there is no conversion from 1 to struct, there is struct literal with partial initializer which match initializer for first field.
 not is it convertible to a static array.
Wrong. int[1] ai = 1; ai = 1; is fine with the language so far. However in this case we speak about struct initializer so having integer literal to be initializer for static integer array is sufficient.
That doesn't mean convertible. It just means constructible and assignable: struct S { this(int); void opAssign(int); } S s = 1; s = 1; Does that mean int is convertible to S? it doesn't. Also: is(int : int[1]); //FALSE Also: void foo(int[1]); void main() { foo(1); //HERE } Error: function foo (int[1]) is not callable using argument types (int)
 AGG(1) should not compile, because 1 is not convertible to
 typeof(AGG.tupleof[0]);
Please refer to the spec or argue if spec is incomplete for a particular case. Making up rules is not good. Adressing your point - this is incorrect because typeof(AGG.tupleof[0]) has type int[1] and initializaing or assigning 1 to int[1] is legal in D. I deliberatly unwrapped all templates to show that you are effectivelly protesting against int[1] = 1;
I will indeed lookup the exact spec. Please let me sleep on it. Do they make any mention about special behavior for static arrays?
 What's happening is an implicit *construction* of a static array, in a context
 where implicit construction is not allowed.
This is not the case. Here is struct literal with partial list of initializers which match respective type initializers which is fine as far D is concern.
Except the type "int" doesn't match nor is convertible to the type "int[1]" int[1] *can* be *initialized* from an int, yes. But so can a struct. Yet doing the same for a struct that is both constructible and assignable doesn't work (as I believe the spec says it shouldn't).
 If
 you are complaining because this breaks some assumption of a brilliant phobos
 ideom, this should be mentioned explicitly so some solution without damaging
 language can be found (personally I object to break the language for the sake
 of writing cute template in phobos).  
That's definitely not the reason. However, that piece of code "shows" that static arrays get a special treatment, that I do not believe they should get.
 Please don't reopen issue: CLOSED->REOPENED->CLOSED war is not good either.
Works for me if you agree to rebuke my points and prove me wrong :) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #5 from Maxim Fomin <maxim maxim-fomin.ru> 2013-10-09 13:33:42 PDT
---
Let's start from the basics.

import std.stdio;

struct AGG
{
    int[1] t;
    double d;
}

void main()
{
    AGG tarr2 = AGG(1); 
    writeln(tarr2);
}

Claim is follows: this is a D valid code.

Backing:
1) AGG(1) is a struct literal (struct spec page). Note, that struct literal
really means struct literal, not "default struct constructor" or "implicit
function call" or "call expression" or any other 'creative' understaning of
language rules.
2) Struct literal contains member initializers which should match in order and
type to struct member initializer (struct spec page + TDPL).
3) Integer literal is valid initializer for static array of ints (TDPL).

You can either refute the backing or make contra point that although the code
is valid, it shouldn't be because the code is bad/wrong/unsafe (but I don't see
how you can convince that reasoning is wrong or the code is unsafe).

Before you write again about assignment, call expressions or implicit type
conversion, please note, that whether integeral expression is convertible to
struct, whether integer expression is convertible to static array in call
expression, whether is(int: int[10]) is true, all of this is irrelevant to the
initialization case.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #6 from monarchdodra gmail.com 2013-10-09 14:11:33 PDT ---
(In reply to comment #5)
 Claim is follows: this is a D valid code.
OK.
 Backing:
 1) AGG(1) is a struct literal (struct spec page). Note, that struct literal
 really means struct literal, not "default struct constructor" or "implicit
 function call" or "call expression" or any other 'creative' understaning of
 language rules.
 2) Struct literal contains member initializers which should match in order and
 type to struct member initializer (struct spec page + TDPL).
 3) Integer literal is valid initializer for static array of ints (TDPL).
How do you define "is a valid initializer"? The struct page (http://dlang.org/struct.html ?) doesn't actually define it (nor does it define much on what is or isn't a valid construction type. In my original case, S can be initialized by int, so isn't int a valid initializer for S? If not, why not? Just because? This is what is throwing me off. Seems the root argument is that static arrays are the *only* type that can be initialized form a type that is not implicitly "it", and that this special rule applies *only* during aggregate construction. I see neither of the two points explained in struct.html, nor array.html ? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #7 from Kenji Hara <k.hara.pg gmail.com> 2013-10-09 21:54:03 PDT ---
The inconsistency comes from the incomplete fix of bug 7019.

struct Agg(T) { T val; }
void main()
{
    int[3] sa = 1;                // 1a, OK
    auto agg1 = Agg!(int[3])(1);  // 1b, OK

    struct S { this(int) {} }
    S s = 1;                      // 2a, OK, by fixing issue 7019
    auto agg2 = Agg!S(1);         // 2b
}

Since long time ago, 1a and 1b has been allowed.

On the other hand, from 2.061, 2a has formally become a part of the language
spec, by fixing issue 7019.

However, currently 2b is still disallowed.

Because, when I had wrote a compiler patch for bug 7019, I had thought that
accepting it might cause some ambiguity on multi-dimentional array
initializing.

  struct S { this(int) {} }
  S[2][2] sa = [1, 2];
  // exactly same as:
  //      sa = [[S(1), S(2)], [S(1), S(2)]]
  // or:  sa = [[S(1), S(1)], [S(2), S(2)]]
  // ?

But recently, I found a new consistent rule to resolve the ambiguity. Based on
the rule in my brain, the 2b case would also be accepted.

Therefore, the current inconsistency is a bug to me. If T t = val; is accepted,
the struct literal syntax Aggr!T(val) should also be accepted.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #8 from Maxim Fomin <maxim maxim-fomin.ru> 2013-10-09 23:19:45 PDT
---
(In reply to comment #6)
 (In reply to comment #5)
 Claim is follows: this is a D valid code.
OK.
 Backing:
 1) AGG(1) is a struct literal (struct spec page). Note, that struct literal
 really means struct literal, not "default struct constructor" or "implicit
 function call" or "call expression" or any other 'creative' understaning of
 language rules.
 2) Struct literal contains member initializers which should match in order and
 type to struct member initializer (struct spec page + TDPL).
 3) Integer literal is valid initializer for static array of ints (TDPL).
How do you define "is a valid initializer"? The struct page (http://dlang.org/struct.html ?) doesn't actually define it (nor does it define much on what is or isn't a valid construction type.
TDPL has explicit example in the beginning of fixed array chapter.
 In my original case, S can be initialized by int, so isn't int a valid
 initializer for S? If not, why not? Just because? This is what is throwing me
 off.
struct S{int i;this(int){}} struct AGG(T) { T t; } void main() { AGG!S ts2 = AGG!S(S(2)); //Explicit. Good. AGG!S ts1 = AGG!S(1); //NO! ILLEGAL REQUEST FOR IMPLICIT CONSTRUCTION! } Second does not work because S(1) is not a struct literal but a constructor call. AGG!S(1) initializer now would require function call S.__ctor(1) which is not currently supported.
 Seems the root argument is that static arrays are the *only* type that can be
 initialized form a type that is not implicitly "it", and that this special rule
 applies *only* during aggregate construction.
It seems you starting to understand the issue (but I haven't thought whether static arrays are only types supporting this).
 I see neither of the two points explained in struct.html, nor array.html ?
It is in TDPL. Anyway this feature was working for years. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #9 from Maxim Fomin <maxim maxim-fomin.ru> 2013-10-09 23:31:12 PDT
---
(In reply to comment #7)
 The inconsistency comes from the incomplete fix of bug 7019.
 
 struct Agg(T) { T val; }
 void main()
 {
     int[3] sa = 1;                // 1a, OK
     auto agg1 = Agg!(int[3])(1);  // 1b, OK
 
     struct S { this(int) {} }
     S s = 1;                      // 2a, OK, by fixing issue 7019
     auto agg2 = Agg!S(1);         // 2b
 }
 
 Since long time ago, 1a and 1b has been allowed.
 
 On the other hand, from 2.061, 2a has formally become a part of the language
 spec, by fixing issue 7019.
 
 However, currently 2b is still disallowed.
Formally this is right because struct initializers are not recursive. If Add!int(1) is a valid struct literal doesn't mean that Agg!S(1) is also valid because S(1) is valid (by the way, here you placed constructor not literal). Unfortunately there is no implicit conversion between basic type to struct type even if the latter is constructable from the former.
 Because, when I had wrote a compiler patch for bug 7019, I had thought that
 accepting it might cause some ambiguity on multi-dimentional array
 initializing.
 
   struct S { this(int) {} }
   S[2][2] sa = [1, 2];
   // exactly same as:
   //      sa = [[S(1), S(2)], [S(1), S(2)]]
   // or:  sa = [[S(1), S(1)], [S(2), S(2)]]
   // ?
 
 But recently, I found a new consistent rule to resolve the ambiguity. Based on
 the rule in my brain, the 2b case would also be accepted.
 
 Therefore, the current inconsistency is a bug to me. If T t = val; is accepted,
 the struct literal syntax Aggr!T(val) should also be accepted.
As I have mentioned previously, there is no inconsistency because you implicitly assuming that struct literal/constructors can be recursive or 'nested' in some sense. If you mean allowing AGG!S ts1 = AGG!S(1); in original example, then this is a minor enhancement. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 09 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #10 from monarchdodra gmail.com 2013-10-10 00:50:45 PDT ---
(In reply to comment #8)
 It seems you starting to understand the issue (but I haven't thought whether
 static arrays are only types supporting this).
OK. What about this...? Is it a bug? //---- struct S { int[1] arr; } void main() { uint[] udarr; uint[1] usarr; int[1] arr1 = udarr; //OK int[1] arr2 = usarr; //OK S s1 = S(udarr); //NOPE? S s2 = S(usarr); //NOPE? } //---- I'm not challenging you, I'm really just trying to understand the rules.
 Anyway this feature was working for years.
I make no claim to the contrary. Original confusion comes from what I saw as "inconsistent", and made the "upside down conclusion". I guess I should have filed instead (maybe) that AGG!S(1) should be legal. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #11 from Kenji Hara <k.hara.pg gmail.com> 2013-10-10 01:15:51 PDT
---
(In reply to comment #9)
 As I have mentioned previously, there is no inconsistency because you
 implicitly assuming that struct literal/constructors can be recursive or
 'nested' in some sense. If you mean allowing AGG!S ts1 = AGG!S(1); in original
 example, then this is a minor enhancement.
I knot that it is an enhancement (eg. bug 7255), but I think it's necessary to increase consistency between static array and user-defined struct type, and it's important for more expressiveness on initializing. The start of my thought ---- Currently, BigInt accepts built-in integers as the "valid initializer". BigInt num = 1; This is expressive syntax. But, when you declare a multi-dimensional array of BigInt, it would become too verbose. BigInt[128] sa = [ BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5), BigInt(6), BigInt(7), BigInt(8), ... ]; If T t = v; is allowed, array initializer should also allow T[n] tsa = [v1, v2, ...]; After the enhancement implemented, we will be able to write the BigInt array declaration as: BigInt[128] sa = [1, 2, 3, 4, 5, 6, 7, 8, ..., 128]; ---- The end of my thought I think we could apply the same rule to the relation of struct literal syntax arguments and corresponding struct field type. Agg!S agg = Agg!S(1); // #1 S[1] ssa = [1]; // #2 - In #1, the struct field Agg!S.val is initialized by the corresponding value 1 which is in the struct literal argument list. - In #2, the array element ssa[1] is initialized by the corresponding value 1 which is in the array initializer argument list. In both case, if the initialized storage typed S accepts the corresponding value 1 *as the valid initializer*, the composite array/struct initializing should also work. Additional note: The following code already works currently. Agg!S aggr2 = {val:1}; // struct initializer syntax -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206


Maxim Fomin <maxim maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|accepts-invalid             |
           Severity|normal                      |enhancement


--- Comment #12 from Maxim Fomin <maxim maxim-fomin.ru> 2013-10-10 01:32:06 PDT
---
(In reply to comment #11)
 (In reply to comment #9)
 As I have mentioned previously, there is no inconsistency because you
 implicitly assuming that struct literal/constructors can be recursive or
 'nested' in some sense. If you mean allowing AGG!S ts1 = AGG!S(1); in original
 example, then this is a minor enhancement.
I knot that it is an enhancement (eg. bug 7255), but I think it's necessary to increase consistency between static array and user-defined struct type, and it's important for more expressiveness on initializing. The start of my thought ---- Currently, BigInt accepts built-in integers as the "valid initializer". BigInt num = 1; This is expressive syntax. But, when you declare a multi-dimensional array of BigInt, it would become too verbose. BigInt[128] sa = [ BigInt(1), BigInt(2), BigInt(3), BigInt(4), BigInt(5), BigInt(6), BigInt(7), BigInt(8), ... ]; If T t = v; is allowed, array initializer should also allow T[n] tsa = [v1, v2, ...]; After the enhancement implemented, we will be able to write the BigInt array declaration as: BigInt[128] sa = [1, 2, 3, 4, 5, 6, 7, 8, ..., 128]; ---- The end of my thought
OK. I agree that there is room for improving support for implicit construction.
 I think we could apply the same rule to the relation of struct literal syntax
 arguments and corresponding struct field type.
 
   Agg!S agg = Agg!S(1);  // #1
   S[1] ssa = [1];    // #2
 
It looks like when you are speaking about struct literal syntax you mean both struct literal and struct constructors (probably even opCall). It seems that Agg!S(1) would be valid either if there is constructor taking int or first member is integer type. Do you consider documenting it after merging corresponding pull?
 - In #1, the struct field Agg!S.val is initialized by the corresponding value 1
 which is in the struct literal argument list.
 - In #2, the array element ssa[1] is initialized by the corresponding value 1
 which is in the array initializer argument list.
 
 In both case, if the initialized storage typed S accepts the corresponding
 value 1 *as the valid initializer*, the composite array/struct initializing
 should also work.
 
 Additional note: The following code already works currently.
 
   Agg!S aggr2 = {val:1};   // struct initializer syntax
OK. I changed type of the issue to show it is enhacement now. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206


Maxim Fomin <maxim maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid


--- Comment #13 from Maxim Fomin <maxim maxim-fomin.ru> 2013-10-10 01:46:55 PDT
---
(In reply to comment #10)
 (In reply to comment #8)
 It seems you starting to understand the issue (but I haven't thought whether
 static arrays are only types supporting this).
OK. What about this...? Is it a bug? //---- struct S { int[1] arr; } void main() { uint[] udarr; uint[1] usarr; int[1] arr1 = udarr; //OK int[1] arr2 = usarr; //OK S s1 = S(udarr); //NOPE? S s2 = S(usarr); //NOPE? } //---- I'm not challenging you, I'm really just trying to understand the rules.
Integer arrays as initializers is completely different story. What you are trying was not supported and not documented. However, what is more important is that recently there was an enhacement request to support such conversions (I don't know issue number) or something similar and consensus was to allow it (probably there is a pull for it). Since Kenji is in thread he probably may clarify the situation. (In general this is currently a dark territory of language.)
 
 Anyway this feature was working for years.
I make no claim to the contrary. Original confusion comes from what I saw as "inconsistent", and made the "upside down conclusion". I guess I should have filed instead (maybe) that AGG!S(1) should be legal.
OK, marked as rejects-valid. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|rejects-valid               |


--- Comment #14 from Kenji Hara <k.hara.pg gmail.com> 2013-10-10 02:00:57 PDT
---
(In reply to comment #12)
 I think we could apply the same rule to the relation of struct literal syntax
 arguments and corresponding struct field type.
 
   Agg!S agg = Agg!S(1);  // #1
   S[1] ssa = [1];    // #2
 
It looks like when you are speaking about struct literal syntax you mean both struct literal and struct constructors (probably even opCall). It seems that Agg!S(1) would be valid either if there is constructor taking int or first member is integer type. Do you consider documenting it after merging corresponding pull?
No. I strictly distinguish struct literal and struct constructor call. struct S1 { int num; } // S1(1) is literal syntax struct S2 { this(int); } // S2(1) is ctor call struct S3 { static S3 opCall(int); } // S3(1) is static function call struct A1(T) { T val; } struct A2(T) { this(T); } void main() { S1 s1 = 1; // should be NG, int is not implicitly convertible to S1 S2 s2 = 1; // OK. The S2 ctor accepts int value as a valid initializer, // then it's implicitly invoked for initialization. S3 s3 = 1; // NG. opCall is completely unrelated to initializing. // Note that A1!T(...) is always literal syntax A1!S1 a11 = A1!S1(1); // NG, int is not implicitly convertible to S1 A1!S2 a12 = A1!S2(1); // should be OK, as same as the 's2' case. A1!S3 a13 = A1!S3(1); // Of course NG. // Note that A2!T(...) is constructor call A2!S1 a21 = A2!S1(1); // NG, int is not implicitly convertible to S1 A2!S2 a22 = A2!S2(1); // NG, int is not implicitly convertible to S1 A2!S3 a23 = A2!S3(1); // NG, int is not implicitly convertible to S1 } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 10 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #15 from Kenji Hara <k.hara.pg gmail.com> 2013-10-10 02:21:30 PDT
---
(In reply to comment #10)
   uint[]  udarr;
   uint[1] usarr;
 
   int[1] arr1 = udarr; //OK
   int[1] arr2 = usarr; //OK
Mmm...I think this is a bug. Because following code is also accepted in compilation, and will cause runtime exception! void main() { int[4] sa; ulong[4] sa2 = sa; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 10 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11206



--- Comment #16 from Kenji Hara <k.hara.pg gmail.com> 2013-11-03 01:18:36 PST
---
(In reply to comment #15)
 (In reply to comment #10)
   uint[]  udarr;
   uint[1] usarr;
 
   int[1] arr1 = udarr; //OK
   int[1] arr2 = usarr; //OK
Mmm...I think this is a bug. Because following code is also accepted in compilation, and will cause runtime exception! void main() { int[4] sa; ulong[4] sa2 = sa; }
I opened bug 11426. It is a regression issue from 2.061. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 03 2013