I'm trying to compile the Fortran module below (using gfortran 7.2.0). The point is to define a derived type that in turn contains two instances of the derived type bspline_3d from the bspline-fortran library (https://github.com/jacobwilliams/bspline-fortran). I then want to define a type-bound procedure that will in turn call the type-bound evaluate procedure of both of those types, and return the result as an array with two elements.
When I try to compile the module below, I get an error message saying
     procedure  :: evaluate => evaluate_2d
             1
Error: Non-polymorphic passed-object dummy argument of 'evaluate_2d' at (1)
I understand absolutely nothing of the error message.
I managed to compile the simple example program found here: http://fortranwiki.org/fortran/show/Object-oriented+programming and as far as I can tell, the only difference is that in my case, the "passed-object" (this) does itself have derived-type member variables (type(bspline_3d) :: fvx, fvy), which in turn probably contain all sorts of stuff.
module interpolator_module
use bspline_module
use parameters, only: WP
implicit none
private
public :: interpolator
type :: interpolator
    type(bspline_3d) :: fvx, fvy
    contains
        private
        procedure  :: evaluate => evaluate_2d
end type interpolator
contains
    function evaluate_2d(this, X, t) result(V)
        implicit none
        ! inputs
        type(interpolator),     intent(inout) :: this
        real(WP), dimension(2), intent(in)    :: X
        real(WP),               intent(in)    :: t
        ! output
        real(WP), dimension(2)                :: V
        ! local variables
        integer                               :: iflag
        integer, parameter                    :: d = 0
        call this%fvx%evaluate(X(1), X(2), t, d, d, d, V(1), iflag)
        call this%fvy%evaluate(X(1), X(2), t, d, d, d, V(2), iflag)
    end function
end module interpolator_module
For a type-bound procedure defined like
type my_type
 contains
  procedure :: proc
end type
the type-bound procedure has a passed argument. That is, when
type(my_type) my_obj
call my_obj%proc
is used, the object my_obj is in the argument list.  With proc defined as
subroutine proc(me)
  type(my_type) me   ! Not correct
end subroutine
then call my_obj%proc is like call proc%(my_obj).1  That's the "passed-object dummy argument" part of the error message.
In the definition of proc above, the passed-object dummy argument type(my_type) me is non-polymorphic.  You can read about polymorphism elsewhere, but to answer the question: a passed-object dummy argument may not be non-polymorphic.  It must be polymorphic, declared using class(my_type) me:
subroutine proc(me)
  class(my_type) me   ! Polymorphic, declared type my_type
end subroutine
This means that an object of type my_type or of a type extending my_type may be passed.  This is a requirement of the Fortran language.
In short: change your
type(interpolator),     intent(inout) :: this
to
class(interpolator),     intent(inout) :: this
To complicate matters, older versions of gfortran, for example, understood type-bound procedures before understanding polymorphism. This means that there are some examples of erroneous use of non-polymorphic passed-objects around.
1 I've deliberately left the binding name as proc the same as the procedure's name. In the context of the question it would be call my_obj%evaluate(...) like call evaluate_2d(my_obj, ...).
The passed dummy argument this must always be polymorphic. That means it must be 
 class(interpolator),     intent(inout) :: this
and not
 type(interpolator),     intent(inout) :: this
That is a fundamental requirement for type-bound procedures. Otherwise you could not usse the procedure for extended types (children).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With