Repository: shader-slang/slang
File: source/slang/slang-check-conversion.cpp (C++)

Code before:
    Expr** outToExpr,
    InitializerListExpr* fromInitializerListExpr,
    UInt& ioInitArgIndex)
{
    // First, we will check if we have run out of arguments
    // on the initializer list.
    //
    UInt initArgCount = fromInitializerListExpr->args.getCount();
    if (ioInitArgIndex >= initArgCount)
    {
        // If we are at the end of the initializer list,
        // then our ability to read an argument depends
        // on whether the type we are trying to read
        // is default-initializable.
        //
        // For resource types, this is definitely not true.
        // Resource types can only ever be bound to parameters.
        // But there is likely a fair amount of legacy code
        // out there that depends on it being true. This should
        // eventually be an error, but for now it's a warning.
        if (auto resourceType = as<ResourceType>(toType))
        {
            getSink()->diagnose(
                fromInitializerListExpr->loc,
                Diagnostics::cannotUseInitializerListForResourceType,
                toType);
        }

        // For now, we will just pretend like everything
        // is default-initializable and move along.
        return true;
    }

    // Okay, we have at least one initializer list expression,
    // so we will look at the next expression and decide
    // whether to use it to initialize the desired type
    // directly (possibly via casts), or as the first sub-expression
    // for aggregate initialization.
    //
    auto firstInitExpr = fromInitializerListExpr->args[ioInitArgIndex];
    if (shouldUseInitializerDirectly(toType, firstInitExpr))
    {
        ioInitArgIndex++;
        return _coerce(
            CoercionSite::Initializer,
            toType,
            outToExpr,
            firstInitExpr->type,
            firstInitExpr,
            getSink(),
            nullptr);

Review comment (suggestion):
So the one downside here is that instead of the one warning, we end up with two warnings, because a later chunk of code notices that the source is uninitialized:
```
tests/spirv/zero-init-tex2d-field.slang(27): warning 30506: cannot use initializer list for resource type 'Texture2D<vector<float,4>>'
    S s = (S)0;
          ^
tests/spirv/zero-init-tex2d-field.slang(27): warning 41016: use of uninitialized variable ''
    S s = (S)0;
          ^
```


Code after:
    Expr** outToExpr,
    InitializerListExpr* fromInitializerListExpr,
    UInt& ioInitArgIndex)
{
    // First, we will check if we have run out of arguments
    // on the initializer list.
    //
    UInt initArgCount = fromInitializerListExpr->args.getCount();
    if (ioInitArgIndex >= initArgCount)
    {
        // If we are at the end of the initializer list,
        // then our ability to read an argument depends
        // on whether the type we are trying to read
        // is default-initializable.
        //
        // For now, we will just pretend like everything
        // is default-initializable and move along.
        return true;
    }

    // Okay, we have at least one initializer list expression,
    // so we will look at the next expression and decide
    // whether to use it to initialize the desired type
    // directly (possibly via casts), or as the first sub-expression
    // for aggregate initialization.
    //
    auto firstInitExpr = fromInitializerListExpr->args[ioInitArgIndex];
    if (shouldUseInitializerDirectly(toType, firstInitExpr))
    {
        ioInitArgIndex++;
        return _coerce(
            CoercionSite::Initializer,
            toType,
            outToExpr,
            firstInitExpr->type,
            firstInitExpr,
            getSink(),
            nullptr);
    }

    // If there is somehow an error in one of the initialization
    // expressions, then everything could be thrown off and we
    // shouldn't keep trying to read arguments.
    //
    if (IsErrorExpr(firstInitExpr))
    {
        // Stop reading arguments, as if we'd reached
        // the end of the list.
        //
        ioInitArgIndex = initArgCount;
        return true;