diff --git a/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo b/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo index 75038053fce..7d6c7e96249 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFTyping.mo @@ -542,12 +542,13 @@ algorithm dimension := match dimension local Expression exp; + Option oexp; Variability var; Dimension dim; Binding b; Type ty; TypingError ty_err; - Integer parent_dims; + Integer parent_dims, dim_index; // Print an error when a dimension that's currently being processed is // found, which indicates a dependency loop. Another way of handling this @@ -649,14 +650,32 @@ algorithm // to get the dimension we're looking for. case Binding.UNTYPED_BINDING() algorithm - (dim, _, ty_err) := typeExpDim(b.bindingExp, index + Binding.propagatedDimCount(b) + parent_dims, - ExpOrigin.setFlag(origin, ExpOrigin.DIMENSION), info); + dim_index := index + Binding.propagatedDimCount(b) + parent_dims; + (dim, oexp, ty_err) := typeExpDim(b.bindingExp, dim_index, ExpOrigin.setFlag(origin, ExpOrigin.DIMENSION), info); + + // If the deduced dimension is unknown, evaluate the binding and try again. + if Dimension.isUnknown(dim) and not TypingError.isError(ty_err) then + exp := if isSome(oexp) then Util.getOption(oexp) else b.bindingExp; + exp := Ceval.evalExp(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info)); + (dim, ty_err) := nthDimensionBoundsChecked(Expression.typeOf(exp), dim_index); + end if; then (dim, ty_err); // A typed binding, get the dimension from the binding's type. case Binding.TYPED_BINDING() - then nthDimensionBoundsChecked(b.bindingType, index + Binding.propagatedDimCount(b) + parent_dims); + algorithm + dim_index := index + Binding.propagatedDimCount(b) + parent_dims; + (dim, ty_err) := nthDimensionBoundsChecked(b.bindingType, dim_index); + + // If the deduced dimension is unknown, evaluate the binding and try again. + if Dimension.isUnknown(dim) and not TypingError.isError(ty_err) then + exp := Ceval.evalExp(b.bindingExp, Ceval.EvalTarget.DIMENSION(component, index, b.bindingExp, info)); + (dim, ty_err) := nthDimensionBoundsChecked(Expression.typeOf(exp), dim_index); + end if; + then + (dim, ty_err); + end match; () := match ty_err diff --git a/testsuite/flattening/modelica/scodeinst/Makefile b/testsuite/flattening/modelica/scodeinst/Makefile index f595a78bec3..afab465d947 100644 --- a/testsuite/flattening/modelica/scodeinst/Makefile +++ b/testsuite/flattening/modelica/scodeinst/Makefile @@ -710,6 +710,7 @@ RecordConstructor1.mo \ RecordConstructor2.mo \ RecordExtends1.mo \ RecordExtends2.mo \ +RecordUnknownDim1.mo \ RecursiveExtends1.mo \ RecursiveExtends3.mo \ RecursiveInst1.mo \ diff --git a/testsuite/flattening/modelica/scodeinst/RecordUnknownDim1.mo b/testsuite/flattening/modelica/scodeinst/RecordUnknownDim1.mo new file mode 100644 index 00000000000..f9153bd31f9 --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/RecordUnknownDim1.mo @@ -0,0 +1,33 @@ +// name: RecordUnknownDim1 +// keywords: +// status: correct +// cflags: -d=newInst +// +// + +record R2 + Integer i[:]; +end R2; + +record R + R2 r; +end R; + +function f + output R2 r; +algorithm + r := R2({1, 2}); +end f; + +model RecordUnknownDim1 + R r = R(f()); +end RecordUnknownDim1; + +// Result: +// class RecordUnknownDim1 +// Integer r.r.i[1]; +// Integer r.r.i[2]; +// equation +// r.r.i = {1, 2}; +// end RecordUnknownDim1; +// endResult