Skip to content

[Bug] Imported struct and record types have inconsistent behavior #28705

@alexanderkim11

Description

@alexanderkim11

🐛 Bug Report

There are a couple of bugged or inconsistent behaviors when trying to using struct and record types declared in an imported program. These can likely be separated out into separate sub-issues, but I’ll leave that to the team to decide.

1. Structs/Records declared in external file but not initialized are erased by compiler

The Leo compiler erases any struct or record types that are declared in a file but never used in that file.

main.leo (external)

// The 'external' program.

program external.aleo {
    record externalRecord {
        owner : address
    }

    struct externalStruct {
        number : u8
    }

    transition dummy(){

    }
}

external.aleo

program external.aleo;

function dummy:

This is fine if an application is contained entirely in one Leo program, but it becomes an issue if you want to modularize your program into some imported helper files.

It also seems to print out the error twice, but only for structs and not for records

main.leo (import_structs_bug)

// The 'import_structs_bug' program.

import external.aleo;

program import_structs_bug.aleo {
    transition external_test(x : external.aleo/externalStruct){}
}

Terminal:

       Leo     3 statements before dead code elimination.
       Leo     1 statements after dead code elimination.
       Leo ✅ Compiled 'external.aleo' into Aleo instructions
Error [ETYC0372017]: The type `externalStruct` is not found in the current scope.
    --> /Users/AlexanderKim/Code/sandbox/import_structs_bug/src/main.leo:9:35
     |
   9 |     function external_test(x : external.aleo/externalStruct){
     |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = If you are using an external type, make sure to preface with the program name. Ex: `credits.aleo/credits` instead of `credits`

Error [ETYC0372017]: The type `externalStruct` is not found in the current scope.
    --> /Users/AlexanderKim/Code/sandbox/import_structs_bug/src/main.leo:9:35
     |
   9 |     function external_test(x : external.aleo/externalStruct){
     |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = If you are using an external type, make sure to preface with the program name. Ex: `credits.aleo/credits` instead of `credits`

2. Syntax for using imported structs is inconsistent with imported records

Imported records must be declared using the following syntax:

{PROGRAM_NAME}.aleo/{RECORD_NAME}

Attempting to use the record name without the preceding program name correctly results in an error saying that type is not found in the current scope.

However, imported structs exhibit different behavior than imported records. Assume the following imported program which has been corrected from above:

main.leo (external)

// The 'external' program.

program external.aleo {
    record externalRecord {
        owner : address
    }

    struct externalStruct {
        number : u8
    }

    transition dummy(){
        let dummy_struct = externalStruct{
            number : 1,
        };
        let dummy_record = externalRecord {
            owner : self.caller
        };
    }
}

external.aleo

program external.aleo;

record externalRecord:
    owner as address.private;

struct externalStruct:
    number as u8;

function dummy:

Attempting to declare the external struct with the same syntax as an external record ({PROGRAM_NAME}.aleo/{STRUCT_NAME}) seems to correctly compile the code, but also prints out an ambiguous error:

main.leo (import_structs_bug)

// The 'import_structs_bug' program.

import external.aleo;

program import_structs_bug.aleo {
    transition external_test (x : external.aleo/externalStruct) {

    }
}

Terminal

       Leo     5 statements before dead code elimination.
       Leo     1 statements after dead code elimination.
       Leo ✅ Compiled 'external.aleo' into Aleo instructions
       Leo     1 statements before dead code elimination.
       Leo     1 statements after dead code elimination.
       Leo ✅ Compiled 'import_structs_bug.aleo' into Aleo instructions
Error [EUTL03710003]: Failed to parse the source file for `import_structs_bug.aleo` into a valid Aleo program.

However, removing the leading {PROGRAM_NAME} results in both correct compliation and no errors printed.

main.leo (import_structs_bug)

// The 'import_structs_bug' program.

import external.aleo;

program import_structs_bug.aleo {
    transition external_test (x : externalStruct) {

    }
}

Terminal

       Leo     5 statements before dead code elimination.
       Leo     1 statements after dead code elimination.
       Leo ✅ Compiled 'external.aleo' into Aleo instructions
       Leo     1 statements before dead code elimination.
       Leo     1 statements after dead code elimination.
       Leo ✅ Compiled 'import_structs_bug.aleo' into Aleo instructions

Your Environment

  • Leo v2.7.1
  • rustc 1.86.0 (05f9846f8 2025-03-31)
  • MacOS (aarch64) Sequoia 15.5

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions