Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29236 Discussions

Calling concrete type bound procedures on abstarct derived types

Andrew_Smith
Valued Contributor I
562 Views

A non-abstract subclass of an abstract type can call procedures on its abstract parent. But if the child overrides the parent procedure then it is no longer possible. I think there is no reason to have this restriction. Is there a way to overcome the compile errors without adding code to the parent type ?

Example:

[fortran]

module ParentType

implicit none

private

public Parent

type, abstract :: Parent

contains

procedure astractStuff

procedure doSomeStuff

end type

 

contains

subroutine astractStuff(item)

class(Parent), intent(inout) :: item

end subroutine

 

subroutine doSomeStuff(item)

class(Parent), intent(inout) :: item

end subroutine

 

end module

module ChildType

use ParentType

implicit none

type, extends(Parent) :: Child

contains

procedure :: doSomeStuff

end type

 

contains

subroutine doSomeStuff(item)

class(Child), intent(inout) :: item

call item%astractStuff() !OK to call non-overridden method in abstract type

call item%Parent%doSomeStuff() !Not OK when overridden

end subroutine

 

end module[/fortran]

The compile errors are:

1>D:\temp\Console1\Console1\Console1.f90(38): error #8314: If the rightmost part-name is of abstract type, data-ref shall be polymorphic [PARENT]1>D:\temp\Console1\Console1\Console1.f90(38): error #8422: If the component immediately preceding the type-bound procedure is abstract, the entire data reference before the procedure name must be polymorphic. [PARENT]

0 Kudos
1 Reply
IanH
Honored Contributor III
562 Views

The problem is that the term item%Parent attempts to reference a concept that doesn't exist - a non-polymorphic abstract object - an object that has a dynamic type of Parent.  Because the object is abstract, there is the potential for the bindings of the type to be incompletely specified (they are in your case - but in that case the parent doesn't need to be abstract).  You know that the specific binding that you are calling exists, but how about all the other bindings, that might subsequently be referenced as part of the problematic CALL?

The easy solution (and conceptually consistent to a degree) is to make the procedure that implements the binding in the parent type public, and then call it directly using a normal call statement (CALL procedure(object, ...), not the object%binding(...) syntax.  Because your extension is type compatible with the parent this should be straightforward.

In other cases you can split the parent type into a concrete grand-parent type and an abstract intermediate.  If you can't do this split - that highlights that the potential problem discussed in the first paragraph was real.

My view is that the syntax `object%binding` implies that you want to do dynamic type or object bound lookup of the procedure to call.  With the object%Parent%binding syntax you are not doing a dynamic lookup.  If you are not doing a dynamic lookup, then don't use the dynamic lookup syntax.  Issues around accessibility muddy this a little, but I still think this is the conceptually cleanest approach.

0 Kudos
Reply