diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp index d1158f969c..7f4c20568e 100644 --- a/src/qmlcompiler/qqmljstypepropagator.cpp +++ b/src/qmlcompiler/qqmljstypepropagator.cpp @@ -104,6 +104,11 @@ void QQmlJSTypePropagator::generate_Ret() setError(u"cannot convert from %1 to %2"_qs .arg(m_state.accumulatorIn.descriptiveName(), m_returnType.descriptiveName())); + + m_logger->logWarning(u"Cannot assign binding of type %1 to %2"_qs.arg( + m_typeResolver->containedTypeName(m_state.accumulatorIn), + m_typeResolver->containedTypeName(m_returnType)), + Log_Type, getCurrentBindingSourceLocation()); return; } @@ -250,6 +255,15 @@ QQmlJS::SourceLocation QQmlJSTypePropagator::getCurrentSourceLocation() const return location; } +QQmlJS::SourceLocation QQmlJSTypePropagator::getCurrentBindingSourceLocation() const +{ + Q_ASSERT(m_currentContext->sourceLocationTable); + const auto &entries = m_currentContext->sourceLocationTable->entries; + + Q_ASSERT(!entries.isEmpty()); + return combine(entries.constFirst().location, entries.constLast().location); +} + void QQmlJSTypePropagator::handleUnqualifiedAccess(const QString &name) const { auto location = getCurrentSourceLocation(); diff --git a/src/qmlcompiler/qqmljstypepropagator_p.h b/src/qmlcompiler/qqmljstypepropagator_p.h index 69dc685e61..cd86c1d442 100644 --- a/src/qmlcompiler/qqmljstypepropagator_p.h +++ b/src/qmlcompiler/qqmljstypepropagator_p.h @@ -264,6 +264,7 @@ private: void checkDeprecated(QQmlJSScope::ConstPtr scope, const QString &name, bool isMethod) const; bool checkRestricted(const QString &propertyName) const; QQmlJS::SourceLocation getCurrentSourceLocation() const; + QQmlJS::SourceLocation getCurrentBindingSourceLocation() const; void propagateBinaryOperation(QSOperator::Op op, int lhs); void propagateCall(const QList &methods, int argc, int argv); diff --git a/tests/auto/qml/qmllint/data/bindingTypeMismatch.qml b/tests/auto/qml/qmllint/data/bindingTypeMismatch.qml new file mode 100644 index 0000000000..ffde545e7d --- /dev/null +++ b/tests/auto/qml/qmllint/data/bindingTypeMismatch.qml @@ -0,0 +1,5 @@ +import QtQuick + +Item { + property int number: 3 + "Hello" +} diff --git a/tests/auto/qml/qmllint/data/bindingTypeMismatchFunction.qml b/tests/auto/qml/qmllint/data/bindingTypeMismatchFunction.qml new file mode 100644 index 0000000000..74d5be4edb --- /dev/null +++ b/tests/auto/qml/qmllint/data/bindingTypeMismatchFunction.qml @@ -0,0 +1,6 @@ +import QtQuick + +Item { + function returnsString() : string {} + property int number: returnsString() +} diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp index 7c4ad622cb..83ce4ee432 100644 --- a/tests/auto/qml/qmllint/tst_qmllint.cpp +++ b/tests/auto/qml/qmllint/tst_qmllint.cpp @@ -620,6 +620,12 @@ void TestQmllint::dirtyQmlCode_data() QTest::newRow("WithStatement") << QStringLiteral("WithStatement.qml") << QStringLiteral("with statements are strongly discouraged") << QString() << false; + QTest::newRow("BindingTypeMismatch") + << QStringLiteral("bindingTypeMismatch.qml") + << QStringLiteral("Cannot assign binding of type QString to int") << QString() << false; + QTest::newRow("BindingTypeMismatchFunction") + << QStringLiteral("bindingTypeMismatchFunction.qml") + << QStringLiteral("Cannot assign binding of type QString to int") << QString() << false; } void TestQmllint::dirtyQmlCode()