Errors #6259, #7715, #6355, #6303 in defining Derived Type specific assignment/operator procedures

93 Views Asked by At

First of all, Hi to everyone ! Wish you all a good starting week :)

In enhancing (as well as simplifying some syntax) a previously developed Derived Type, I was (and some still) encountering some errors as in the title specification (NOTE: for details about full messages and their cause, please read the comment lines in the code below :) ).

Among them, the ones I was not understand the most (of the why I am getting them) are error #6355: This binary operation is invalid for this data type. for the operator(==), and error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands. for the assignment(=).

Here is an example of source code (NOTE: in order to reproduce those errors, comment out the type-bound procedure part, and uncomment out the two interface bodies):

module MPolicyMod
   implicit none
   private
   public :: MPolicy

   type, public :: MPolicy_t
      real(kind = 8) :: delta_fI_fct_
      real(kind = 8) :: delta_fJ_fct_
      real(kind = 8) :: interp_I_fct_
      real(kind = 8) :: interp_J_fct_
      integer :: id_pol_
   contains
      generic :: assignment(=) => MPolicy_fromPol_sub, MPolicy_fromID_sub
      procedure, private, pass :: MPolicy_fromID_sub, MPolicy_fromPol_sub
      generic :: operator(==) => MPolicy_isID
      procedure, pass, private :: MPolicy_isID
   end type MPolicy_t

   integer, public, parameter :: MPolicy_NULL  = 0
   integer, public, parameter :: MPolicy_DEF   = 1
   integer, public, parameter :: MPolicy_CONST = 2


   interface MPolicy_t
      module procedure MPolicy_constructor_integer
      module procedure MPolicy_constructor_real
      module procedure MPolicy_fromID
   end interface

   ! interface assignment(=)
   !   module procedure MPolicy_fromPol_sub
   !   module procedure MPolicy_fromID_sub
   ! end interface assignment(=)

   ! interface operator(==)
   !   module procedure MPolicy_isID
   ! end interface operator(==)


contains

   !> Main default constructor.
   function MPolicy_constructor_real(dfi, dfj, interpi, interpj, id) result(pol)
      real(kind = 8), intent(in) :: dfi, dfj, interpi, interpj
      integer, intent(in) :: id
      type(MPolicy_t) :: pol

      print *, ' Default constructor (as compiler)...'

      pol%delta_fI_fct_ = dfi
      pol%delta_fJ_fct_ = dfj
      pol%interp_I_fct_ = interpi
      pol%interp_J_fct_ = interpj
      pol%id_pol_       = id
   end function MPolicy_constructor_real


   function MPolicy_constructor_integer(dfi, dfj, interpi, interpj, id) result(pol)
      integer, intent(in) :: dfi, dfj, interpi, interpj, id
      type(MPolicy_t) :: pol

      print *, ' Default constructor (integer version)...'

      pol = MPolicy_t(real(dfi, 8), &
                        real(dfj, 8), &
                        real(interpi, 8), &
                        real(interpj, 8), id)
   end function


   function MPolicy_fromID(id) result(pol)
      integer, intent(in) :: id
      type(MPolicy_t)     :: pol

      print *, ' Constructor from ID...'

      select case (id)
         case (MPolicy_NULL)
            return
         case (MPolicy_DEF)
            pol = MPolicy_t(2, 2, 2, 2, MPolicy_DEF)
         case (MPolicy_CONST)
            pol = MPolicy_t(1, 1, 1, 1, MPolicy_CONST)
         case default
            block
               character(len=3) :: fmt

               write(fmt, '(i)'), id
               stop ' [ERROR] Unknow policy identifier "id"= '//fmt
            end block
      end select
   end function MPolicy_fromID


   subroutine MPolicy_fromPol_sub(lhs, rhs)
      class(MPolicy_t), intent(in) :: rhs
      class(MPolicy_t), intent(out) :: lhs

      lhs%delta_fI_fct_ = rhs%delta_fI_fct_
      lhs%delta_fJ_fct_ = rhs%delta_fJ_fct_
      lhs%interp_I_fct_ = rhs%interp_I_fct_
      lhs%interp_J_fct_ = rhs%interp_J_fct_
      lhs%id_pol_       = rhs%id_pol_
   end subroutine MPolicy_fromPol_sub


   subroutine MPolicy_fromID_sub(lhs, rhs)
      class(MPolicy_t), intent(out) :: lhs
      integer, intent(in)           :: rhs

      lhs = MPolicy_t(rhs)
   end subroutine MPolicy_fromID_sub


   function MPolicy(mpol) result(pol)
      integer :: mpol
      type(MPolicy_t) :: pol

      pol = MPolicy_t(mpol)
   end function MPolicy


   pure function MPolicy_isID(pol, id) result(isID)
      class(MPolicy_t), intent(in) :: pol
      integer, intent(in) :: id
      logical :: isID

      isID = pol%id_pol_ == id
   end function MPolicy_isID

end module

Example program:

program test

   use MPolicyMod
   implicit none


   ! ! NOTE: generates
   ! !       error #6259: This array or function or substring is invalid in constant expressions.   [MPOLICYMOD^MPOLICY_FROMID]
   ! !       error #7715: Replacing invalid structure constructor by integer 1.   [<NULL_STRING>]
   ! type(MPolicy_t) :: pol = MPolicy_t(MPolicy_NULL)


   type(MPolicy_t) :: pol

   ! =========================================================================
   print *, pol
   pol = MPolicy_t(MPolicy_NULL)
   print *, pol

   ! ! NOTE: generates (without TYPE-BOUND specification)
   ! !       error #6355: This binary operation is invalid for this data type.
   print *, pol == MPolicy_NULL

   pol = MPolicy_t(1, 1, 1, 1, 2)
   print *, pol

   ! ! NOTE: generates (without TYPE-BOUND specification)
   ! !       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.
   pol = MPolicy_DEF
   print *, pol
end program test

Then, after reading through the ISO Fortran Standard 2003 Draft document, at Section 4.5.4 Type-bound procedures, Rule R452 states that we could specify assignment(=) as a generic-spec, in a generic-binding type of proc-binding-stmt. There I realised I was missing the type-bound specifications for those operator/assignment procedures.

Why, then, only the interface body was not enough to make it work?

After this, I also wonder why the initialisation statement type(MPolicy_t) :: pol = MPolicy_t(MPolicy_NULL) generates errors #6259 and #7715.

For that, I still didn't search by my own. But if you come with an asnwer before I might find (hopefully) an explanation, it's always good to have constructive as well as polite discussions with You all.

I now go back to my searching. Have a nice day :)

0

There are 0 best solutions below