Table of Contents

5.5.1.1 Static semantics

This section corresponds to MS-VBAL §5.5.1.1 Static semantics.

The pairs of declared types MS-VBAL §5.5.1.1 makes invalid to Let-coerce are checked by LetCoercionStaticSemantics, and reported as VBC09310 (Type mismatch).

An object where a value is expected

Where a value is expected, an object stands for its simple data value: what its default member returns (MS-VBAL §5.5.1.2.13). ObjectValueStaticSemantics checks at compile time that it can have one, as MS-VBA does (recorded in Excel, each statement compiled alone):

The object Where a value of a declared type is expected Abs, Int, Fix Len, LenB Where a Variant is expected
The Nothing literal VBC09304 Invalid use of object VBC09304 VBC09304 compiles
Of a class whose default member takes an argument (a Collection) VBC09339 Argument not optional VBC09339 VBC09339 compiles
Of a class whose default member returns an object VBC09310 Type mismatch compiles VBC09333 Variable required compiles
Of a class whose default member returns a String or a Variant compiles compiles compiles compiles
Of a class whose default member returns another value compiles compiles VBC09333 Variable required compiles
Of a class that has no default member compiles 👉: 438 when it runs, RDC11015 compiles compiles compiles; assigned to a Variant with Let 👉: 438, RDC11015

A value of a declared type is expected:

  • of the value of a Let assignment to a variable of a value type (a number, a String, a Boolean, a Date, an enumeration);
  • of an argument of a parameter declared with a value type, ByVal, or ByRef and given an expression;
  • of an operand of any operator but Is: arithmetic, &, the comparisons, Like, the logical operators;
  • of an argument of a function of the standard library whose parameter MS-VBA types, although MS-VBAL declares it Variant: the conversions CBool to CVErr (not CVar, CVDate or CDec), Sgn, and the $ functions of the Strings module (Left$, Mid$, Trim$, …).

Abs, Int and Fix expect a value of any type. Len and LenB expect "any valid string expression, or any valid variable name" (RD-VBAL §6.1.2.11.1.22): an object's value is no variable, so it must be a String or a Variant. Every other parameter declared Variant takes an object as it is: CVar, Round, Hex, Str, Left, Mid, Trim, the functions of DateTime and Information, IIf, Choose. A standard-library parameter says which it is with StdLibValueAttribute.

👉 MS-VBAL §5.5.1.1 makes an object of a class that has no accessible default member statically invalid to Let-coerce. MS-VBA compiles it, and raises run-time error 438 (Object doesn't support this property or method) when it runs, or 91 (Object variable or With block variable not set) when the variable holds Nothing (Excel, oracle\s46 F16a-c: c = o, c = CInt(o), Split("a,b,c", ",", o)). RD-VBA does what MS-VBA does: the object is read for a value when it runs, as a late-bound one is. Where a value of a declared type is expected, or a Variant is Let-assigned the object, the static pass states it (ValueExpressionSemanticFlags.ValueOfObjectWithNoDefaultMember), and RDCore.Diagnostics reports RDC11015, a warning that stands in for the compile error the specification makes it. A parameter declared Variant, and Abs, Int, Fix, Len and LenB, take the object as it is: the coercion there is the run time's, and nothing is reported. And the specification asks only for an "accessible default Property Get or function", where MS-VBA also asks that it take no argument, which RD-VBA does too.

A LongLong

MS-VBAL §5.5.1.1 makes it invalid to implicitly Let-coerce a LongLong to any declared type other than LongLong or Variant. MS-VBA refuses only what is narrower than it, and RD-VBA does what MS-VBA does (recorded in Excel, 64-bit):

To Implicitly
Byte, Integer, Long, an enumeration, Currency VBC09310 Type mismatch
Single, Double, String, a fixed-length String, Boolean, Date, LongPtr, Variant compiles

A LongPtr is a LongLong in a 64-bit environment and a Long in a 32-bit one (RD-VBAL §2.4.1), and so is the address an AddressOf expression gives: ByVal lpfn As Long takes one in a 32-bit environment, and refuses it in a 64-bit one. The rule holds wherever a value is Let-coerced: an assignment, and an argument given to a parameter of a value type.

The Empty and Null literals

MS-VBAL §3.3.5.2 gives the Empty and Null literals a declared type of Variant, and a Variant is valid to Let-coerce to an array. So a = Empty, with a declared As Integer(), compiles, and so do a = Null and F = Empty in a function declared As Integer(); the value each holds is no array, and the assignment raises run-time error 13 (Type mismatch) when it runs. This is what MS-VBA does (Excel, oracle\s46 F17a-b, oracle\s48 J01-J02). The static pass states it (ValueExpressionSemanticFlags.EmptyLetToArray), and RDCore.Diagnostics reports RDC11016: the assignment fails whenever it runs.


⏮️ RD-VBAL §5.5.1 Let-coercion | ⏭️ RD-VBAL §5.5.1.2 Runtime semantics