I have a really specific obscure bug I've found with getting some code to compile with both Intel Fortran (I'm using version 22.214.171.124 Build 20170213) and gfortran 6.2. I apologize in advance for my horrible overly long example code, it's simplified by quite a bit from the code from which the issue arose. In this example code, I have 3 modules: (1) A module "polymod" that defines a type "Thing"; (2) a module "testpolytype" that has a type "SimpleType" that has a type bound procedure that has a dummy argument of type "Thing"; (3) a module that has a function (TestUseWithTypeDef) that uses variables of type SimpleType and type Thing to call the type bound procedure in SimpleType.
*The attached code will not compile in gfortran (as I would expect, I get "Error: Derived type ‘thing’ at (1) is being used before it is defined"), if I don't explicitly "use polymod" (line 51) in the function "TestUseWithTypeDef", but compiles with intel fortran unless I specifically state "use testpolymod, only: SimpleType" (line 52). It seems to me that SimpleType should not come in to scope because it is used in a type bound procedure that is being called. Or am I misunderstanding some weird scoping issue with typebound procedures?*
module polymod implicit none interface Thing module procedure Initialize end interface Thing type :: Thing integer :: thingProp end type Thing contains subroutine Initialize(this, thingProp) class(Thing) :: this integer, intent(in) :: thingProp this%thingProp = thingProp end subroutine Initialize end module polymod module testpolymod implicit none type SimpleType contains private procedure, public :: UseThing end type SimpleType contains subroutine UseThing(this,dummyThing) use polymod class(SimpleType) :: this type(Thing), intent(inout) :: dummyThing dummyThing = Thing(42) end subroutine UseThing end module testpolymod module callermod implicit none contains function TestUseWithTypeDef() result(intOut) ! use polymod use testpolymod integer :: intOut type(SimpleType) :: sT type(Thing) :: local_thing call sT%UseThing(local_thing) write(*,*)"thing prop: ", local_thing%thingProp intOut = local_thing%thingProp end function TestUseWithTypeDef end module callermod program testpoly use callermod implicit none write(*,*)TestUseWithTypeDef() end program testpoly
I agree with you - this should not compile. The specific issue is the reference to type thing in line 55. This is NOT a type exported by module testpolymod and hence is inaccessible in the function. I recall seeing similar issues of declarations "leaking" in similar circumstances.