Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-56292

Broken recursive instantiation checks

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.7.0
    • None

    Description

      There appears to be some kind of checking for infinite recursion in the cases of QML elements self or cross reference, but it doesn't output anything meaningful in the console - there is no error, no warning, no crash, no window, no nothing.

      What is worse, this prevents code from running even if it isn't the case of infinite recursion, take this trivial example:

      // Object.qml
      Row {
        property int c : 0
        Rectangle {
          width: 50
          height: 50
          color: "red"
          border.color: "black"
          MouseArea {
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton
            onClicked: {
              if (mouse.button === Qt.LeftButton) c++
              else if (c) c--
            }
          }
        }
        List { model: c }
      }
      
      // List.qml
      Column {
        property alias model : r.model
        Repeater {
          id: r
          delegate: Object {} // wont work
        }
      }
      

      There is no possibility of infinite recursion here even though there is cross reference between the two elements, since whether or not a delegate is going to be created is determine by the model, which stops the propagation of infinite recursion.

      Note that this behavior is likely triggered by the "compiler" rather than the runtime, as removing the "literal" reference from the source does the trick, either one of the solutions:

      // solution 1
      Column {
        property alias model : r.model
        Repeater {
          id: r
          delegate: Loader { source: "Object.qml" }
        }
      }
      
      // solution 2
      Loader {
         Component.onCompleted: setSource("List.qml", {"model": Qt.binding(function() {return c})})
       }
      

      Last but not least, there is also this little gem:

      // Obj.qml
      Item {
        id: main
        property Obj thisObj : main
      }
      

      Which does actually complains that "Obj is instantiated recursively" but it really isn't, this time the check produces some output, but it is erroneous, as Obj is most definitely NOT instantiated recursively. The check catches the "literal" self-reference when it is used in the context of a type, without actually instantiating an object and even though QML object properties are actually implemented as references. It would work if the type is changed to Item, but then you lose all the "intellisense" for the otherwise very handy dynamic scope property, you'd be stuck with an Item without the functionality, defined in Obj.

      What needs fixing:

      1 - the check should not catch QML types when they are used in the context of property types
      2 - the check should not catch QML types which are inside a delegate, being inside a delegate outta be enough to imply it is not the case of a newbish accidental infinite recursion
      3 - when the check catches an actual case of infinite recursion, it should display a warning or error rather than absolutely nothing

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qtqmlteam Qt Qml Team User
            dgo dgo
            Votes:
            5 Vote for this issue
            Watchers:
            9 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes