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

Another (!) bug with IMPORT

OP1
New Contributor III
188 Views

As shown, the following code does not compile with ifx 2026.0.0 (Debug and Release) on Windows.

MODULE M
IMPLICIT NONE
TYPE :: T
    CONTAINS 
    PROCEDURE, NOPASS :: S => T_S
    ! PROCEDURE, NOPASS :: SOME_OTHER_BINDING_NAME => T_S
END TYPE T
INTERFACE
    MODULE SUBROUTINE T_S
    END SUBROUTINE T_S
END INTERFACE
END MODULE M
 
 
MODULE N
IMPLICIT NONE
INTERFACE
    MODULE SUBROUTINE S
    END SUBROUTINE S
END INTERFACE
END MODULE N

 
SUBMODULE (N) S
USE :: M, ONLY : T
IMPORT, ALL
IMPLICIT NONE
CONTAINS
MODULE SUBROUTINE S
END SUBROUTINE S
END SUBMODULE S

The compiler erroneously claims that on line 26:

error #8847: A use-associated entity from module M conflicts with a host-associated entity explicitly made accessible by an IMPORT statement in the same scope.   [S]

 This does not make any sense at all, since S is simply a binding name for a procedure bound to the derived type T.

The code will compile if you comment out line 5 and uncomment line 6 (essentially, using a different binding name that does not "collide" with S).

Or, the code will compile if lines 5 and 6 are left as they are and line 25 is commented out.

3 Replies
Shiquan_Su
Moderator
100 Views

Hi,

I think the error message said the MODULE SUBROUTINE S in module N is conflicting with the procedure S (pointing to MODULE SUBROUTINE T_S ) in module M.

I edited your code as follows, and it passes the compilation:

 

$ cat test.f90
MODULE M
IMPLICIT NONE
TYPE :: T
CONTAINS
PROCEDURE, NOPASS :: S => T_S
! PROCEDURE, NOPASS :: SOME_OTHER_BINDING_NAME => T_S
END TYPE T
INTERFACE
MODULE SUBROUTINE T_S
END SUBROUTINE T_S
END INTERFACE
END MODULE M


MODULE N
IMPLICIT NONE
INTERFACE
MODULE SUBROUTINE S_avoid_conflict_M
END SUBROUTINE S_avoid_conflict_M
END INTERFACE
END MODULE N


SUBMODULE (N) S1
USE :: M, ONLY : T
IMPORT, ALL
IMPLICIT NONE
!CONTAINS
INTERFACE
MODULE SUBROUTINE S
END SUBROUTINE S
END INTERFACE
END SUBMODULE S1
$ cat runme.sh
#!/bin/bash
module purge
module load intel/oneapi/2026.0
ifx -c test.f90
$ . ./runme.sh
$

 

OP1
New Contributor III
77 Views

@Shiquan_Su , I suspect you miss the point here. The issue with IMPORT, ALL is not due to an interface in module N having the same name as a module subroutine in submodule M. That particular scenario is legitimate, and you can convince yourself of its validity by compiling the simple example here, which does not trigger any compiler error (as expected):

MODULE N
IMPLICIT NONE
INTERFACE
    MODULE SUBROUTINE S
    END SUBROUTINE S
END INTERFACE
END MODULE N
 
SUBMODULE (N) S
IMPORT, ALL
IMPLICIT NONE
CONTAINS
MODULE SUBROUTINE S
END SUBROUTINE S
END SUBMODULE S

The compiler error I am reporting has a different nature: for some reason, the compiler thinks that the BINDING NAME S for the procedure T_S of the derived type T in module M conflicts with the module subroutine S in submodule S. This is wrong, there is no collision here.

Shiquan_Su
Moderator
24 Views

This is the current situation of the implementation. We suggest you remove the "IMPORT, ALL" from the "SUBMODULE (N) S".
Without IMPORT, ALL, the submodule can still access module N's entities (including the declaration of S) through implicit host association.
Host association means that everything declared in the parent module (N) is automatically accessible in the submodule - you don't need IMPORT for basic access.
Here's the key difference:

SUBMODULE (N) S
USE :: M, ONLY : T
! No IMPORT statement
IMPLICIT NONE
CONTAINS
MODULE SUBROUTINE S
print *, "in submodule S module subroutine S"
END SUBROUTINE S
END SUBMODULE S

In this case:
- The submodule is implementing the module subroutine S that was declared in N
- It doesn't need to explicitly "import" the declaration - it knows about it through host association
- The implementation just provides the body for the interface declared in module N

When do you need IMPORT?

IMPORT is mainly needed in interface bodies or when you want to make host association explicit (to resolve potential ambiguities or for clarity). For example:

INTERFACE
MODULE SUBROUTINE some_proc(x)
IMPORT :: some_type ! Need IMPORT here to use host's some_type
TYPE(some_type) :: x
END SUBROUTINE
END INTERFACE

The conflict with IMPORT, ALL:

When you add IMPORT, ALL, it makes the host association explicit, and the compiler then checks for conflicts with USE-associated names. That's why the error occurs - without it, the implicit host association doesn't trigger the same conflict check.

You may try out the following example:

 

$module load intel/oneapi/2026.0 && ifx test.f90 submod_m.f90 driver2.f90 -o driver2 && ./driver2

$cat test.f90:
MODULE M
IMPLICIT NONE
TYPE :: T
CONTAINS
PROCEDURE, NOPASS :: S => T_S
! PROCEDURE, NOPASS :: SOME_OTHER_BINDING_NAME => T_S
END TYPE T
INTERFACE
MODULE SUBROUTINE T_S
END SUBROUTINE T_S
END INTERFACE
END MODULE M


MODULE N
IMPLICIT NONE
INTERFACE
MODULE SUBROUTINE S
END SUBROUTINE S
END INTERFACE
END MODULE N


SUBMODULE (N) S
USE :: M, ONLY : T
! IMPORT, ALL
IMPLICIT NONE

CONTAINS
MODULE SUBROUTINE S
print *, "in submodule S module subroutine S"
END SUBROUTINE S
END SUBMODULE S

$cat submod_m.f90:
SUBMODULE (M) M_impl
IMPLICIT NONE
CONTAINS
MODULE SUBROUTINE T_S
print *, "in module M's T_S subroutine"
END SUBROUTINE T_S
END SUBMODULE M_impl

$cat driver2.f90:
PROGRAM driver2
USE :: M
USE :: N
IMPLICIT NONE

TYPE(T) :: my_t

print *, "=== Testing M's S (type-bound procedure) ==="
CALL my_t%S()

print *, ""
print *, "=== Testing N's S (module subroutine from submodule) ==="
CALL S()

print *, ""
print *, "Driver2 program completed successfully"

END PROGRAM driver2

Output:
=== Testing M's S (type-bound procedure) ===
in module M's T_S subroutine

=== Testing N's S (module subroutine from submodule) ===
in submodule S module subroutine S

Driver2 program completed successfully

0 Kudos
Reply