If a derived type with defined is part of an other derived type, the assignment of the wrapping type does not trigger the user defined assignment of the contained type. The code below should trigger the user defined assignment and print 41 at the end, but it fails to do so.
module testmod implicit none ! Wrapping everything dirty (needing user defined assignment into a special type) type :: dirty_t integer :: val = -1 contains procedure :: dirty_assign generic :: assignment(=) => dirty_assign end type dirty_t ! Extends abstract interface type :: container_t type(dirty_t) :: dirty end type container_t contains subroutine dirty_assign(this, other) class(dirty_t), intent(out) :: this type(dirty_t), intent(in) :: other this%val = other%val - 1 print "(a, i0, a, i0, a)", "dirty_assign (", other%val, " -> ", this%val, ")" end subroutine dirty_assign end module testmod program testprog use testmod implicit none type(container_t), allocatable :: stat1, stat2 class(container_t), allocatable :: dyn allocate(stat1) stat1%dirty%val = 42 stat2 = stat1 print "(a, i0)", "stat2 value: ", stat2%dirty%val dyn = stat2 print "(a, i0)", "dyn value: ", dyn%dirty%val end program testprog
See also some more details on the topic at