Dear Intel developer,
The ifort compiler (16.0.0 20150815) refuses to compile valid Fortran 2003 code if this contains overridden assignment in a polymorphic type. The self containing code below demonstrates the issue. The compiler stops with the error message
test.F90(59): error #6197: An assignment of different structure types is invalid. [MYEXT1] pExt1 = myExt1
although an assignment operator for the polymorphic variable pExt1 is defined. Other Fortran 2003 compilers seem to have no problems with it.
module typedefs implicit none type :: Base contains procedure :: assignFrom => Base_assignFrom generic :: assignment(=) => assignFrom end type Base type, extends(Base) :: Extended integer :: data contains procedure :: assignFrom => Extended_assignFrom end type Extended contains subroutine Base_assignFrom(this, other) class(Base), intent(inout) :: this class(Base), intent(in) :: other select type (other) type is (Base) continue class default print *, "Wrong data type for Base%assignFrom" error stop 1 end select end subroutine Base_assignFrom subroutine Extended_assignFrom(this, other) class(Extended), intent(inout) :: this class(Base), intent(in) :: other select type (other) type is (Extended) this%data = other%data class default print *, "Wrong data type for Extended%assignFrom" error stop 1 end select end subroutine Extended_assignFrom end module typedefs program test use typedefs implicit none type(Extended) :: myExt1 class(Base), pointer :: pExt1 myExt1%data = -1 allocate(pExt1, source=myExt1) pExt1 = myExt1 select type (pExt1) type is (Extended) print *, "VALUE:", pExt1%data class default print *, "Unexpected type" end select end program test
If I recall correctly, 'polymorphic assignment' is a Fortran 2008 feature that is not yet supported by Intel Fortran. Even when it does get supported, I think the generic resolution issue, similar to the other incident you posted (https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x), will remain given how you put together the Base and Extended derived types. So with polymorphic variable pExt1 declared as 'class(Base', my impression is you will still need to do along the following lines but I'm open to the possibility of being wrong about this:
program test use typedefs implicit none type(Extended) :: myExt1 class(Base), pointer :: pExt1 myExt1%data = -1 allocate(pExt1, source=myExt1) select type (pExt1) type is (Extended) pExt1 = myExt1 print *, "VALUE:", pExt1%data class default print *, "Unexpected type" end select end program test
The assignment to an allocatable polymorphic variable is indeed Fortran 2008. However, here we have an assignment to a static polymorphic variable and that is Fortran 2003, as far as I know. I can not point out the part in the standard, but I've checked it also with another commercial compiler which I have found the most reliable so far when in doubt about the standard, and it compiles the code in F2003 mode.
Also, thanks for the workaround, but that won't help in my situation, as in my application I can not know the possible types in advance. I would like to implement a general purpose container holding arbitrary extensions of a given derived type with user overridden assignments.
Intrinsic assignment to a polymorphic variable is not standard F2003:
17 An intrinsic assignment statement is an assignment statement that is not a defined assignment 18 statement (188.8.131.52). In an intrinsic assignment statement, variable shall not be polymorphic, and 19 (1) If expr is an array then variable shall also be an array, 20 (2) Either variable shall be an allocatable array of the same rank as expr or the shapes of 21 variable and expr shall conform, and (3) The declared types of variable 1 and expr shall conform as specified in Table 7.8.
However, this is defined assignment which is not so restricted.