diff --git a/Test/baseResults/hlsl.constructArray.vert.out b/Test/baseResults/hlsl.constructArray.vert.out
new file mode 100755
index 0000000000000000000000000000000000000000..dd2c2434aaf56e555cfd35e344b6240dbeed2e97
--- /dev/null
+++ b/Test/baseResults/hlsl.constructArray.vert.out
@@ -0,0 +1,381 @@
+hlsl.constructArray.vert
+Shader version: 500
+0:? Sequence
+0:2  Function Definition: @main( ( temp 4-component vector of float)
+0:2    Function Parameters: 
+0:?     Sequence
+0:4      Sequence
+0:4        move second child to first child ( temp 2-element array of 4-component vector of float)
+0:4          'float4_array_times' ( temp 2-element array of 4-component vector of float)
+0:4          Construct structure ( temp 2-element array of 4-component vector of float)
+0:4            Convert int to float ( temp 4-component vector of float)
+0:4              direct index ( temp 4-component vector of int)
+0:4                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:4                Constant:
+0:4                  0 (const int)
+0:4            Convert int to float ( temp 4-component vector of float)
+0:4              direct index ( temp 4-component vector of int)
+0:4                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:4                Constant:
+0:4                  1 (const int)
+0:5      Sequence
+0:5        move second child to first child ( temp 4-element array of 2-component vector of float)
+0:5          'float2_array_times2' ( temp 4-element array of 2-component vector of float)
+0:5          Construct structure ( temp 4-element array of 2-component vector of float)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    0 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    1 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    2 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    3 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    0 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    1 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    2 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    3 (const int)
+0:6      Sequence
+0:6        move second child to first child ( temp 2-element array of 4-component vector of int)
+0:6          'int4_array2' ( temp 2-element array of 4-component vector of int)
+0:6          Construct structure ( temp 2-element array of 4-component vector of int)
+0:6            direct index ( temp 4-component vector of int)
+0:6              'int4_array' ( temp 3-element array of 4-component vector of int)
+0:6              Constant:
+0:6                0 (const int)
+0:6            direct index ( temp 4-component vector of int)
+0:6              'int4_array' ( temp 3-element array of 4-component vector of int)
+0:6              Constant:
+0:6                1 (const int)
+0:7      Sequence
+0:7        move second child to first child ( temp 2-element array of int)
+0:7          'int1_array' ( temp 2-element array of int)
+0:7          Construct structure ( temp 2-element array of int)
+0:7            direct index ( temp int)
+0:7              direct index ( temp 4-component vector of int)
+0:7                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:7                Constant:
+0:7                  0 (const int)
+0:7              Constant:
+0:7                0 (const int)
+0:7            direct index ( temp int)
+0:7              direct index ( temp 4-component vector of int)
+0:7                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:7                Constant:
+0:7                  0 (const int)
+0:7              Constant:
+0:7                1 (const int)
+0:9      Branch: Return with expression
+0:9        Constant:
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:2  Function Definition: main( ( temp void)
+0:2    Function Parameters: 
+0:?     Sequence
+0:2      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' ( out 4-component vector of float Position)
+0:2        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' ( out 4-component vector of float Position)
+
+
+Linked vertex stage:
+
+
+Shader version: 500
+0:? Sequence
+0:2  Function Definition: @main( ( temp 4-component vector of float)
+0:2    Function Parameters: 
+0:?     Sequence
+0:4      Sequence
+0:4        move second child to first child ( temp 2-element array of 4-component vector of float)
+0:4          'float4_array_times' ( temp 2-element array of 4-component vector of float)
+0:4          Construct structure ( temp 2-element array of 4-component vector of float)
+0:4            Convert int to float ( temp 4-component vector of float)
+0:4              direct index ( temp 4-component vector of int)
+0:4                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:4                Constant:
+0:4                  0 (const int)
+0:4            Convert int to float ( temp 4-component vector of float)
+0:4              direct index ( temp 4-component vector of int)
+0:4                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:4                Constant:
+0:4                  1 (const int)
+0:5      Sequence
+0:5        move second child to first child ( temp 4-element array of 2-component vector of float)
+0:5          'float2_array_times2' ( temp 4-element array of 2-component vector of float)
+0:5          Construct structure ( temp 4-element array of 2-component vector of float)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    0 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    1 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    2 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      0 (const int)
+0:5                  Constant:
+0:5                    3 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    0 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    1 (const int)
+0:5            Convert int to float ( temp 2-component vector of float)
+0:5              Construct ivec2 ( temp 2-component vector of int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    2 (const int)
+0:5                direct index ( temp int)
+0:5                  direct index ( temp 4-component vector of int)
+0:5                    'int4_array' ( temp 3-element array of 4-component vector of int)
+0:5                    Constant:
+0:5                      1 (const int)
+0:5                  Constant:
+0:5                    3 (const int)
+0:6      Sequence
+0:6        move second child to first child ( temp 2-element array of 4-component vector of int)
+0:6          'int4_array2' ( temp 2-element array of 4-component vector of int)
+0:6          Construct structure ( temp 2-element array of 4-component vector of int)
+0:6            direct index ( temp 4-component vector of int)
+0:6              'int4_array' ( temp 3-element array of 4-component vector of int)
+0:6              Constant:
+0:6                0 (const int)
+0:6            direct index ( temp 4-component vector of int)
+0:6              'int4_array' ( temp 3-element array of 4-component vector of int)
+0:6              Constant:
+0:6                1 (const int)
+0:7      Sequence
+0:7        move second child to first child ( temp 2-element array of int)
+0:7          'int1_array' ( temp 2-element array of int)
+0:7          Construct structure ( temp 2-element array of int)
+0:7            direct index ( temp int)
+0:7              direct index ( temp 4-component vector of int)
+0:7                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:7                Constant:
+0:7                  0 (const int)
+0:7              Constant:
+0:7                0 (const int)
+0:7            direct index ( temp int)
+0:7              direct index ( temp 4-component vector of int)
+0:7                'int4_array' ( temp 3-element array of 4-component vector of int)
+0:7                Constant:
+0:7                  0 (const int)
+0:7              Constant:
+0:7                1 (const int)
+0:9      Branch: Return with expression
+0:9        Constant:
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:9          0.000000
+0:2  Function Definition: main( ( temp void)
+0:2    Function Parameters: 
+0:?     Sequence
+0:2      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' ( out 4-component vector of float Position)
+0:2        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' ( out 4-component vector of float Position)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 89
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 87
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 9  "@main("
+                              Name 15  "float4_array_times"
+                              Name 21  "int4_array"
+                              Name 36  "float2_array_times2"
+                              Name 68  "int4_array2"
+                              Name 76  "int1_array"
+                              Name 87  "@entryPointOutput"
+                              Decorate 87(@entryPointOutput) BuiltIn Position
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeFunction 7(fvec4)
+              11:             TypeInt 32 0
+              12:     11(int) Constant 2
+              13:             TypeArray 7(fvec4) 12
+              14:             TypePointer Function 13
+              16:             TypeInt 32 1
+              17:             TypeVector 16(int) 4
+              18:     11(int) Constant 3
+              19:             TypeArray 17(ivec4) 18
+              20:             TypePointer Function 19
+              22:     16(int) Constant 0
+              23:             TypePointer Function 17(ivec4)
+              27:     16(int) Constant 1
+              32:             TypeVector 6(float) 2
+              33:     11(int) Constant 4
+              34:             TypeArray 32(fvec2) 33
+              35:             TypePointer Function 34
+              37:     11(int) Constant 0
+              38:             TypePointer Function 16(int)
+              41:     11(int) Constant 1
+              44:             TypeVector 16(int) 2
+              66:             TypeArray 17(ivec4) 12
+              67:             TypePointer Function 66
+              74:             TypeArray 16(int) 12
+              75:             TypePointer Function 74
+              82:    6(float) Constant 0
+              83:    7(fvec4) ConstantComposite 82 82 82 82
+              86:             TypePointer Output 7(fvec4)
+87(@entryPointOutput):     86(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              88:    7(fvec4) FunctionCall 9(@main()
+                              Store 87(@entryPointOutput) 88
+                              Return
+                              FunctionEnd
+       9(@main():    7(fvec4) Function None 8
+              10:             Label
+15(float4_array_times):     14(ptr) Variable Function
+  21(int4_array):     20(ptr) Variable Function
+36(float2_array_times2):     35(ptr) Variable Function
+ 68(int4_array2):     67(ptr) Variable Function
+  76(int1_array):     75(ptr) Variable Function
+              24:     23(ptr) AccessChain 21(int4_array) 22
+              25:   17(ivec4) Load 24
+              26:    7(fvec4) ConvertSToF 25
+              28:     23(ptr) AccessChain 21(int4_array) 27
+              29:   17(ivec4) Load 28
+              30:    7(fvec4) ConvertSToF 29
+              31:          13 CompositeConstruct 26 30
+                              Store 15(float4_array_times) 31
+              39:     38(ptr) AccessChain 21(int4_array) 22 37
+              40:     16(int) Load 39
+              42:     38(ptr) AccessChain 21(int4_array) 22 41
+              43:     16(int) Load 42
+              45:   44(ivec2) CompositeConstruct 40 43
+              46:   32(fvec2) ConvertSToF 45
+              47:     38(ptr) AccessChain 21(int4_array) 22 12
+              48:     16(int) Load 47
+              49:     38(ptr) AccessChain 21(int4_array) 22 18
+              50:     16(int) Load 49
+              51:   44(ivec2) CompositeConstruct 48 50
+              52:   32(fvec2) ConvertSToF 51
+              53:     38(ptr) AccessChain 21(int4_array) 27 37
+              54:     16(int) Load 53
+              55:     38(ptr) AccessChain 21(int4_array) 27 41
+              56:     16(int) Load 55
+              57:   44(ivec2) CompositeConstruct 54 56
+              58:   32(fvec2) ConvertSToF 57
+              59:     38(ptr) AccessChain 21(int4_array) 27 12
+              60:     16(int) Load 59
+              61:     38(ptr) AccessChain 21(int4_array) 27 18
+              62:     16(int) Load 61
+              63:   44(ivec2) CompositeConstruct 60 62
+              64:   32(fvec2) ConvertSToF 63
+              65:          34 CompositeConstruct 46 52 58 64
+                              Store 36(float2_array_times2) 65
+              69:     23(ptr) AccessChain 21(int4_array) 22
+              70:   17(ivec4) Load 69
+              71:     23(ptr) AccessChain 21(int4_array) 27
+              72:   17(ivec4) Load 71
+              73:          66 CompositeConstruct 70 72
+                              Store 68(int4_array2) 73
+              77:     38(ptr) AccessChain 21(int4_array) 22 37
+              78:     16(int) Load 77
+              79:     38(ptr) AccessChain 21(int4_array) 22 41
+              80:     16(int) Load 79
+              81:          74 CompositeConstruct 78 80
+                              Store 76(int1_array) 81
+                              ReturnValue 83
+                              FunctionEnd
diff --git a/Test/hlsl.constructArray.vert b/Test/hlsl.constructArray.vert
new file mode 100644
index 0000000000000000000000000000000000000000..52c4b6f0c9219bf4f45b0ac39b1a4743b93f3364
--- /dev/null
+++ b/Test/hlsl.constructArray.vert
@@ -0,0 +1,10 @@
+float4 main() :  SV_POSITION 
+{
+    int4 int4_array[3];
+    float4 float4_array_times[2] = (float4[2])int4_array;
+    float2 float2_array_times2[4] = (float2[4])int4_array;
+    int4 int4_array2[2] = (int4[2])int4_array;
+    int int1_array[2] = (int[2])int4_array;
+
+    return (float4)0.0;
+}
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 12dbd16468987c93dc6be51658486485c69e80a1..f2002341a18a08015c09f063866b37c114afd455 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -5425,6 +5425,9 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const
 // Test for the correctness of the parameters passed to various constructor functions
 // and also convert them to the right data type, if allowed and required.
 //
+// 'node' is what to construct from.
+// 'type' is what type to construct.
+//
 // Returns nullptr for an error or the constructed node (aggregate or typed) for no error.
 //
 TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* node, const TType& type)
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index 51f9d49e315474015af61cc639b1261b997e62a0..43c4c4015030529bf12c5ebcf7fbf49ec4ed1984 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -100,6 +100,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.comparison.vec.frag", "main"},
         {"hlsl.conditional.frag", "PixelShaderFunction"},
         {"hlsl.constantbuffer.frag", "main"},
+        {"hlsl.constructArray.vert", "main"},
         {"hlsl.constructexpr.frag", "main"},
         {"hlsl.constructimat.frag", "main"},
         {"hlsl.depthGreater.frag", "PixelShaderFunction"},
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index 5a546f5ba4e05e6b287804bfe528f936b77aefdf..aab3cb141c7834a5756b43d025cad0a07fe194f6 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -2732,9 +2732,14 @@ bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
     if (acceptTokenClass(EHTokLeftParen)) {
         TType castType;
         if (acceptType(castType)) {
+            // recognize any array_specifier as part of the type
+            TArraySizes* arraySizes = nullptr;
+            acceptArraySpecifier(arraySizes);
+            if (arraySizes != nullptr)
+                castType.newArraySizes(*arraySizes);
+            TSourceLoc loc = token.loc;
             if (acceptTokenClass(EHTokRightParen)) {
                 // We've matched "(type)" now, get the expression to cast
-                TSourceLoc loc = token.loc;
                 if (! acceptUnaryExpression(node))
                     return false;
 
@@ -2754,6 +2759,11 @@ bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
                 // the '(int' part.  We must back up twice.
                 recedeToken();
                 recedeToken();
+
+                // Note, there are no array constructors like
+                //   (float[2](...))
+                if (arraySizes != nullptr)
+                    parseContext.error(loc, "parenthesized array constructor not allowed", "([]())", "", "");
             }
         } else {
             // This isn't a type cast, but it still started "(", so if it is a
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 67933b45d2e21007e335c35b8cb23ac585f19468..e60ff60ef595d39e69a0a054cc72586a95b11e1d 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -5401,7 +5401,8 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
         if (type.isImplicitlySizedArray()) {
             // auto adapt the constructor type to the number of arguments
             type.changeOuterArraySize(function.getParamCount());
-        } else if (type.getOuterArraySize() != function.getParamCount()) {
+        } else if (type.getOuterArraySize() != function.getParamCount() &&
+                   type.computeNumComponents() > size) {
             error(loc, "array constructor needs one argument per array element", "constructor", "");
             return true;
         }
@@ -5430,6 +5431,12 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node
         }
     }
 
+    // Some array -> array type casts are okay
+    if (arrayArg && function.getParamCount() == 1 && op != EOpConstructStruct && type.isArray() &&
+        !type.isArrayOfArrays() && !function[0].type->isArrayOfArrays() &&
+        type.getVectorSize() >= 1 && function[0].type->getVectorSize() >= 1)
+        return false;
+
     if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) {
         error(loc, "constructing non-array constituent from array argument", "constructor", "");
         return true;
@@ -7336,17 +7343,20 @@ TIntermTyped* HlslParseContext::handleConstructor(const TSourceLoc& loc, TInterm
 
 // Add a constructor, either from the grammar, or other programmatic reasons.
 //
+// 'node' is what to construct from.
+// 'type' is what type to construct.
+//
+// Returns the constructed object.
 // Return nullptr if it can't be done.
 //
 TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyped* node, const TType& type)
 {
-    TIntermAggregate* aggrNode = node->getAsAggregate();
     TOperator op = intermediate.mapTypeToConstructorOp(type);
 
     // Combined texture-sampler constructors are completely semantic checked
     // in constructorTextureSamplerError()
     if (op == EOpConstructTextureSampler)
-        return intermediate.setAggregateOperator(aggrNode, op, type, loc);
+        return intermediate.setAggregateOperator(node->getAsAggregate(), op, type, loc);
 
     TTypeList::const_iterator memberTypes;
     if (op == EOpConstructStruct)
@@ -7360,7 +7370,8 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyp
         elementType.shallowCopy(type);
 
     bool singleArg;
-    if (aggrNode) {
+    TIntermAggregate* aggrNode = node->getAsAggregate();
+    if (aggrNode != nullptr) {
         if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
             singleArg = true;
         else
@@ -7370,9 +7381,15 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyp
 
     TIntermTyped *newNode;
     if (singleArg) {
+        // Handle array -> array conversion
+        // Constructing an array of one type from an array of another type is allowed,
+        // assuming there are enough components available (semantic-checked earlier).
+        if (type.isArray() && node->isArray())
+            newNode = convertArray(node, type);
+
         // If structure constructor or array constructor is being called
         // for only one parameter inside the structure, we need to call constructAggregate function once.
-        if (type.isArray())
+        else if (type.isArray())
             newNode = constructAggregate(node, elementType, 1, node->getLoc());
         else if (op == EOpConstructStruct)
             newNode = constructAggregate(node, *(*memberTypes).type, 1, node->getLoc());
@@ -7537,13 +7554,86 @@ TIntermTyped* HlslParseContext::constructBuiltIn(const TType& type, TOperator op
     return intermediate.setAggregateOperator(newNode, op, type, loc);
 }
 
+// Convert the array in node to the requested type, which is also an array.
+// Returns nullptr on failure, otherwise returns aggregate holding the list of
+// elements needed to construct the array.
+TIntermTyped* HlslParseContext::convertArray(TIntermTyped* node, const TType& type)
+{
+    assert(node->isArray() && type.isArray());
+    if (node->getType().computeNumComponents() < type.computeNumComponents())
+        return nullptr;
+
+    // TODO: write an argument replicator, for the case the argument should not be
+    // executed multiple times, yet multiple copies are needed.
+
+    TIntermTyped* constructee = node->getAsTyped();
+    // track where we are in consuming the argument
+    int constructeeElement = 0;
+    int constructeeComponent = 0;
+
+    // bump up to the next component to consume
+    const auto getNextComponent = [&]() {
+        TIntermTyped* component;
+        component = handleBracketDereference(node->getLoc(), constructee, 
+                                             intermediate.addConstantUnion(constructeeElement, node->getLoc()));
+        if (component->isVector())
+            component = handleBracketDereference(node->getLoc(), component,
+                                                 intermediate.addConstantUnion(constructeeComponent, node->getLoc()));
+        // bump component pointer up
+        ++constructeeComponent;
+        if (constructeeComponent == constructee->getVectorSize()) {
+            constructeeComponent = 0;
+            ++constructeeElement;
+        }
+        return component;
+    };
+
+    // make one subnode per constructed array element
+    TIntermAggregate* constructor = nullptr;
+    TType derefType(type, 0);
+    TType speculativeComponentType(derefType, 0);
+    TType* componentType = derefType.isVector() ? &speculativeComponentType : &derefType;
+    TOperator componentOp = intermediate.mapTypeToConstructorOp(*componentType);
+    TType crossType(node->getBasicType(), EvqTemporary, type.getVectorSize());
+    for (int e = 0; e < type.getOuterArraySize(); ++e) {
+        // construct an element
+        TIntermTyped* elementArg;
+        if (type.getVectorSize() == constructee->getVectorSize()) {
+            // same element shape
+            elementArg = handleBracketDereference(node->getLoc(), constructee,
+                                                  intermediate.addConstantUnion(e, node->getLoc()));
+        } else {
+            // mismatched element shapes
+            if (type.getVectorSize() == 1)
+                elementArg = getNextComponent();
+            else {
+                // make a vector
+                TIntermAggregate* elementConstructee = nullptr;
+                for (int c = 0; c < type.getVectorSize(); ++c)
+                    elementConstructee = intermediate.growAggregate(elementConstructee, getNextComponent());
+                elementArg = addConstructor(node->getLoc(), elementConstructee, crossType);
+            }
+        }
+        // convert basic types
+        elementArg = intermediate.addConversion(componentOp, derefType, elementArg);
+        if (elementArg == nullptr)
+            return nullptr;
+        // combine with top-level constructor
+        constructor = intermediate.growAggregate(constructor, elementArg);
+    }
+
+    return constructor;
+}
+
 // This function tests for the type of the parameters to the structure or array constructor. Raises
 // an error message if the expected type does not match the parameter passed to the constructor.
 //
 // Returns nullptr for an error or the input node itself if the expected and the given parameter types match.
 //
-TIntermTyped* HlslParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount, const TSourceLoc& loc)
+TIntermTyped* HlslParseContext::constructAggregate(TIntermNode* node, const TType& type, int paramCount,
+                                                   const TSourceLoc& loc)
 {
+    // Handle cases that map more 1:1 between constructor arguments and constructed.
     TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped());
     if (! converted || converted->getType() != type) {
         error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h
index 9e772d166e69ed0d0b89648867bfd2aa59947896..9a881fbb68de76cbf70ff959b316ea511d9e0229 100755
--- a/hlsl/hlslParseHelper.h
+++ b/hlsl/hlslParseHelper.h
@@ -146,6 +146,7 @@ public:
     void lengthenList(const TSourceLoc&, TIntermSequence& list, int size, TIntermTyped* scalarInit);
     TIntermTyped* handleConstructor(const TSourceLoc&, TIntermTyped*, const TType&);
     TIntermTyped* addConstructor(const TSourceLoc&, TIntermTyped*, const TType&);
+    TIntermTyped* convertArray(TIntermTyped*, const TType&);
     TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
     TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
     void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0, TArraySizes* arraySizes = 0);