Assigning a product to a triangularView, while using a custom Scalar type that has an explicit single-argument constructor taking an 'int', fails to compile.

When assigning a product to a triangularView, while using a custom Scalar type that has a single-argument constructor that is marked 'explicit' (which is good practice to prevent implicit conversions) taking an 'int', fails to compile (which is a bug / incorrect behavior).

Please see a code example here: https://godbolt.org/z/c9e1zE

The snippet is also copy-pasted into this issue, see further below.

The root of the problem is that in Eigen/src/Core/TriangularMatrix.h, calls like dst._assignProduct(src, 1, 0); fail to explicitly convert the second argument to Scalar.

Changing the following lines to:

line 971: dst._assignProduct(src, Scalar(1), 0);

resp.

line 982: dst._assignProduct(src, Scalar(1), 1);

and

line 993 dst._assignProduct(src, Scalar(-1), 1);

seems to fix the problem.

kind regards, Niek

#include <Eigen/Dense>
#include <iostream>
#include <vector>

class my_int
{
    int v_;
public:

    my_int() = default;

    // UNCOMMENT THE LINE BELOW TO MAKE THIS EXAMPLE COMPILE
    explicit 
    my_int(int x)
    : v_(x)
    {}

private:
    inline friend std::ostream& operator<<(std::ostream& os, const my_int& obj)
    {
        return os << obj.v_;
    }    

    inline friend my_int operator*(my_int const& a, my_int const& b)
    {
        return my_int {a.v_ * b.v_};
    }

    inline friend my_int operator+(my_int const& a, my_int const& b)
    {
        return my_int {a.v_ + b.v_};
    }

    inline friend my_int& operator+=(my_int& a, my_int const& b)
    {
        a.v_ += b.v_;
        return a;
    }
};

// boilerplate for my custom scalar type
namespace Eigen {
template <>
struct NumTraits<my_int> : Eigen::GenericNumTraits<my_int>
{
    using Real = my_int;
    using NonInteger = my_int;
    using Literal = my_int;
    using Nested = my_int;

    static inline Real epsilon()
    {
        return my_int{0};
    }
    static inline Real dummy_precision()
    {
        return my_int{0};
    }
    static inline int digits10()
    {
        return 0;
    }

    enum {
        IsComplex = 0,
        IsInteger = 1,
        IsSigned = 1,
        RequireInitialization = 1,
        ReadCost = 1,
        AddCost = 1,
        MulCost = 1
    };
};


}

int main() {
    using std::cout;
    using myint_mat = Eigen::Matrix<my_int, Eigen::Dynamic, Eigen::Dynamic>; 
    using int_mat = Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic>; 

    myint_mat A (2,2);
    {
        int_mat iA (2,2);
        iA << 1,2,3,4;
        A = iA.cast<my_int>();
    }

    myint_mat B (2,2);
    {
        int_mat iB (2,2);
        iB << 5,6,7,8;
        B = iB.cast<my_int>();
    }

    // THIS LINE BELOW TRIGGERS THE COMPILATION ERROR
    A.template triangularView<Eigen::Upper>() = B * B;


    cout << A << '\n';
}