Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-67983

The IDL generator cannot manage struct definitions that include an optional variant field

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None
    • Service Arch
    • ALL
    • Hide
      • Define a new IDL struct that includes an field of variant type, such as
        structs:
            CreateCommandRequest:
                strict: true
                fields:
                    clusteredIndex:
                        type:
                            variant: [safeBool, ClusteredIndexSpec]
                        optional: true
                        unstable: false
        
      • Compile the server code

      Expected outcome: the IDL generator should produce valid gen.h/cpp files

      Observed outcome: the code produced by the IDL generator cannot be compiled

      • Sample from the generated code:
        void CreateCommand::parseProtected(const IDLParserErrorContext& ctxt, const BSONObj& bsonObject) {
        ... 
                else if (fieldName == kClusteredIndexFieldName) {
                    if (MONGO_unlikely(usedFields[kClusteredIndexBit])) {
                        ctxt.throwDuplicateField(element);
                    }
        
                    usedFields.set(kClusteredIndexBit);
        
        
                    const BSONType variantType = element.type();
                    switch (variantType) {
                       ...
                    case NumberDouble:
                    {
                        _createCommandRequest.setClusteredIndex(boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec>>(element.trueValue()));
                        break;
                    }
                    case Object:
                        _createCommandRequest.setClusteredIndex(mongo::ClusteredIndexSpec::parse(ctxt, element.Obj())); // <-- THE OFFENDING LINE
                        break;
                    }
        
        }
        
      • Compilation error:
        [210/983 ( 21%) 8.508s] Compiled build/optdebug/mongo/db/commands/create_gen.dyn.o
        FAILED: build/optdebug/mongo/db/commands/create_gen.dyn.o 
        export CCACHE_NOCPP2='1';export CCACHE_PREFIX='/home/ubuntu/mongo/build/scons/icecream/optdebug/run-icecc.sh';export ICECC_CLANG_REMOTE_CPP='1';export PATH='/opt/mongodbtoolchain/v3/bin:/usr/local/bin:/opt/bin:/bin:/usr/bin';/usr/bin/ccache /opt/mongodbtoolchain/v3/bin/clang++ @build/optdebug/mongo/db/commands/create_gen.dyn.o.rsp
        build/optdebug/mongo/db/commands/create_gen.cpp:1083:57: error: no viable conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec> >'
                        _createCommandRequest.setClusteredIndex(mongo::ClusteredIndexSpec::parse(ctxt, element.Obj()));
                                                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        src/third_party/boost/boost/optional/optional.hpp:934:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::none_t' for 1st argument
            optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
            ^
        src/third_party/boost/boost/optional/optional.hpp:938:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> >::argument_type' (aka 'const mpark::variant<bool, mongo::ClusteredIndexSpec> &') for 1st argument
            optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {}
            ^
        src/third_party/boost/boost/optional/optional.hpp:943:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> >::rval_reference_type' (aka 'mpark::variant<bool, mongo::ClusteredIndexSpec> &&') for 1st argument
            optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward<T>(val))
            ^
        src/third_party/boost/boost/optional/optional.hpp:1023:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'const boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> > &' for 1st argument
            optional ( optional const& ) = default;
            ^
        src/third_party/boost/boost/optional/optional.hpp:1033:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> > &&' for 1st argument
            optional ( optional && ) = default;
            ^
        build/optdebug/mongo/db/commands/create_gen.h:188:92: note: passing argument to parameter 'value' here
            void setClusteredIndex(boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec>> value) {  _clusteredIndex = std::move(value);  }
                                                                                                   ^
        build/optdebug/mongo/db/commands/create_gen.cpp:1493:57: error: no viable conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec> >'
                        _createCommandRequest.setClusteredIndex(mongo::ClusteredIndexSpec::parse(ctxt, element.Obj()));
                                                                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        src/third_party/boost/boost/optional/optional.hpp:934:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::none_t' for 1st argument
            optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
            ^
        src/third_party/boost/boost/optional/optional.hpp:938:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> >::argument_type' (aka 'const mpark::variant<bool, mongo::ClusteredIndexSpec> &') for 1st argument
            optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {}
            ^
        src/third_party/boost/boost/optional/optional.hpp:943:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> >::rval_reference_type' (aka 'mpark::variant<bool, mongo::ClusteredIndexSpec> &&') for 1st argument
            optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward<T>(val))
            ^
        src/third_party/boost/boost/optional/optional.hpp:1023:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'const boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> > &' for 1st argument
            optional ( optional const& ) = default;
            ^
        src/third_party/boost/boost/optional/optional.hpp:1033:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> > &&' for 1st argument
            optional ( optional && ) = default;
            ^
        build/optdebug/mongo/db/commands/create_gen.h:188:92: note: passing argument to parameter 'value' here
            void setClusteredIndex(boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec>> value) {  _clusteredIndex = std::move(value);  }
        
      Show
      Define a new IDL struct that includes an field of variant type, such as structs: CreateCommandRequest: strict: true fields: clusteredIndex: type: variant: [safeBool, ClusteredIndexSpec] optional: true unstable: false Compile the server code Expected outcome : the IDL generator should produce valid gen.h/cpp files Observed outcome : the code produced by the IDL generator cannot be compiled Sample from the generated code: void CreateCommand::parseProtected(const IDLParserErrorContext& ctxt, const BSONObj& bsonObject) { ... else if (fieldName == kClusteredIndexFieldName) { if (MONGO_unlikely(usedFields[kClusteredIndexBit])) { ctxt.throwDuplicateField(element); } usedFields.set(kClusteredIndexBit); const BSONType variantType = element.type(); switch (variantType) { ... case NumberDouble: { _createCommandRequest.setClusteredIndex(boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec>>(element.trueValue())); break; } case Object: _createCommandRequest.setClusteredIndex(mongo::ClusteredIndexSpec::parse(ctxt, element.Obj())); // <-- THE OFFENDING LINE break; } } Compilation error: [210/983 ( 21%) 8.508s] Compiled build/optdebug/mongo/db/commands/create_gen.dyn.o FAILED: build/optdebug/mongo/db/commands/create_gen.dyn.o export CCACHE_NOCPP2='1';export CCACHE_PREFIX='/home/ubuntu/mongo/build/scons/icecream/optdebug/run-icecc.sh';export ICECC_CLANG_REMOTE_CPP='1';export PATH='/opt/mongodbtoolchain/v3/bin:/usr/local/bin:/opt/bin:/bin:/usr/bin';/usr/bin/ccache /opt/mongodbtoolchain/v3/bin/clang++ @build/optdebug/mongo/db/commands/create_gen.dyn.o.rsp build/optdebug/mongo/db/commands/create_gen.cpp:1083:57: error: no viable conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec> >' _createCommandRequest.setClusteredIndex(mongo::ClusteredIndexSpec::parse(ctxt, element.Obj())); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/third_party/boost/boost/optional/optional.hpp:934:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::none_t' for 1st argument optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {} ^ src/third_party/boost/boost/optional/optional.hpp:938:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> >::argument_type' (aka 'const mpark::variant<bool, mongo::ClusteredIndexSpec> &') for 1st argument optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {} ^ src/third_party/boost/boost/optional/optional.hpp:943:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> >::rval_reference_type' (aka 'mpark::variant<bool, mongo::ClusteredIndexSpec> &&') for 1st argument optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward<T>(val)) ^ src/third_party/boost/boost/optional/optional.hpp:1023:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'const boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> > &' for 1st argument optional ( optional const& ) = default; ^ src/third_party/boost/boost/optional/optional.hpp:1033:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> > &&' for 1st argument optional ( optional && ) = default; ^ build/optdebug/mongo/db/commands/create_gen.h:188:92: note: passing argument to parameter 'value' here void setClusteredIndex(boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec>> value) { _clusteredIndex = std::move(value); } ^ build/optdebug/mongo/db/commands/create_gen.cpp:1493:57: error: no viable conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec> >' _createCommandRequest.setClusteredIndex(mongo::ClusteredIndexSpec::parse(ctxt, element.Obj())); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/third_party/boost/boost/optional/optional.hpp:934:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::none_t' for 1st argument optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {} ^ src/third_party/boost/boost/optional/optional.hpp:938:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> >::argument_type' (aka 'const mpark::variant<bool, mongo::ClusteredIndexSpec> &') for 1st argument optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {} ^ src/third_party/boost/boost/optional/optional.hpp:943:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> >::rval_reference_type' (aka 'mpark::variant<bool, mongo::ClusteredIndexSpec> &&') for 1st argument optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward<T>(val)) ^ src/third_party/boost/boost/optional/optional.hpp:1023:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'const boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> > &' for 1st argument optional ( optional const& ) = default; ^ src/third_party/boost/boost/optional/optional.hpp:1033:5: note: candidate constructor not viable: no known conversion from 'mongo::ClusteredIndexSpec' to 'boost::optional<mpark::variant<bool, mongo::ClusteredIndexSpec> > &&' for 1st argument optional ( optional && ) = default; ^ build/optdebug/mongo/db/commands/create_gen.h:188:92: note: passing argument to parameter 'value' here void setClusteredIndex(boost::optional<stdx::variant<bool, mongo::ClusteredIndexSpec>> value) { _clusteredIndex = std::move(value); }

      See the "steps to reproduce" section.

            Assignee:
            backlog-server-servicearch [DO NOT USE] Backlog - Service Architecture
            Reporter:
            paolo.polato@mongodb.com Paolo Polato
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: