protected final DataType setOutputType(DataType actualOutput, DataType requiredOutput, DataType requiredType,
                                           TypeContext context) {
        if (actualOutput != null && requiredOutput != null && ! actualOutput.isAssignableTo(requiredOutput))
            throw new VerificationException(this, "This produces type " + actualOutput.getName() + " but " + requiredOutput.getName() + " is required");
        if (requiredType != null && requiredOutput != null && ! requiredOutput.isAssignableTo(requiredType))
            throw new VerificationException(this, "This is required to produce type " + requiredOutput.getName() + " but is produces " + requiredType.getName());;
        return assignOutputType(actualOutput != null ? actualOutput : requiredOutput); // Use the more precise type when known
    }
Sets the output type of this and returns the resulting input type, or null if it cannot be
uniquely determined, with additional arguments for convenience type checking.
This implementation returns the same type, which is appropriate for all statements
that do not change the type.

@param actualOutput the type actually produced by this, must be assignable to the requiredOutput,
                    or null if not known
@param requiredOutput the type required by the next expression, which actualOutput must be assignable to,
                      or null if it cannot be uniquely determined.
@param requiredType a type the required output must be assignable to, or null to not verify this
@param context the context of this
@return the actualOutput if set, requiredOutput otherwise
@throws IllegalArgumentException if actualOutput
indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/Expression.java