# Examples of Intrinsic Assignment to Polymorphic Variables

Intrinsic assignment to an allocatable polymorphic variable is allowed. The variable must be type compatible with the expression and of the same rank. If it is allocated but the dynamic type differs from that of the expression, it is deallocated. If it is not allocated or becomes deallocated, it is allocated with the dynamic type of the expression.

Syntax:

assignment-stmt is variable = expr

variable is an allocatable polymorphic and expr is not necessarily an allocatable, but variable and expr must be type compatible.

A polymorphic entity that is not an unlimited polymorphic entity is type compatible with entities of the same declared type or any of its extensions. Even though an unlimited polymorphic entity is not considered to have a declared type, it is type compatible with all entities.

variable and expr must be of the same rank.

If expr is a scalar and variable is allocated, then expr is treated as an array with the same bounds as variable, so the bounds of variable would remain unchanged. It is an error if variable is unallocated when expr is a scalar.

In the examples below, we have the following types:

    Type type1
    End type

    Type type2
    End type

    Type, extends(type1) :: type3
    End type

Example of same type and same size:

If variable is the same type and size as expr then just do the assignment.

    Class(type1), allocatable :: var
    Class(type1), allocatable :: expr
    Allocate(expr, source=type1())
    Allocate(var, source=type1())
    var = expr             ! No deallocation of var, simple assignment

Example of same type and different size:

If variable is the same type as expr but their sizes are not the same then deallocate `var`, reallocate it, and then do the assignment.

    Class(type1), allocatable :: var(:)
    Class(type1), allocatable :: expr(:)
    Allocate(var(5), source=type1())
    Allocate(expr(6), source=type1())
    var = expr             ! var deallocated and then
                           ! allocated to the size of expr - then
                           ! the usual assignment is performed

Example of different types or shape and same size:

If variable and expr are of different types or shapes but of the same size, then do the assignment and update the type/bounds of `var` to be same as that of `expr`, only if type1 and type3 are type compatible.

    Class(type1), allocatable :: var(:,:)
    Class(type1), allocatable :: expr(:,:)
    Allocate(var(2,3), source=type1())
    Allocate(expr(3,2), source=type3())
    var = expr             ! No deallocation
                           ! simple assignment with var’s
                           ! bounds updated

Example of different types or shape and different size:

If variable and expr are of different types or shapes and of different sizes, then deallocate `var` and allocate it with the same type and shape as `expr`, only if type1 and type3 are type compatible.

    Class(type1), allocatable :: var(:,:)
    Class(type3), allocatable :: expr(:,:)
    Allocate(var(2,4), source=type1())
    Allocate(expr(3,3), source=type3())
    var = expr             ! var deallocated and then
                           ! allocated to the size of expr and
                           ! then the usual assignment var
                           ! has dynamic type set to type3

Example of incompatible types on Left-Hand Side (LHS) and Right-Hand Side (RHS):

If LHS and RHS are type incompatible then you get an error.

    Class(type1), allocatable :: var
    Class(type2), allocatable :: expr
    Allocate(var,source=type1())
    Allocate(expr,source=type2())
    var = expr             ! This is an error

Example of unallocated allocatable polymorphic on the LHS:

If `var` is unallocated then `expr` must be a scalar or it is a shape mismatch error.

    Class(*), allocatable :: var(:)
    var = 5                ! This is an error

Otherwise, allocate `var` with same dynamic type, shape, and size as `expr`.

    Class(*), allocatable :: var
    var = 5                ! This is valid

Example of unlimited polymorphic on the LHS:

Unlimited polymorphic allocatable on the LHS is type compatible with any type. If `var` is of a different size than `expr`, `var` is deallocated and then allocated with the type and shape of `expr`.

    Class(*), allocatable :: var
    Class(type2), allocatable :: expr
    Allocate(var, source=type1())
    Allocate(expr, source=type2())
    var = expr              ! var is an unlimited polymorphic
                            ! so it is type compatible with
                            ! any type expr

Parent topic: Intrinsic Assignment Statements