sway icon indicating copy to clipboard operation
sway copied to clipboard

Wrong `TyStructDecl::call_path` when using glob imports with local shadowing

Open ironcev opened this issue 1 year ago • 0 comments

#5418 fixed the issue of finding the proper decls in the namespace in case of shadowing, but it turns out we still have issues in the content of the found decls. The concrete example is having TyStructDecl::call_path containing wrong path, namely not the one to the local struct but the one to the shadowed struct, although the rest of the decl contains valid information.

To observe the wrong call_path, we need to debug the compiler. As a sample tryout project, create a new Sway script with an internal library lib.sw containing the following code:

library;

pub struct TestStruct {
    a: u64,
}

Put the following code in main.sw:

script;

mod lib;

use lib::*;

struct TestStruct {
   x: u64,
   y: u64,
}

fn main() {
   let ts = TestStruct { x: 0, y: 0 };
   poke(ts.x);
}

fn poke<T>(_x: T) { }

The program will compile without errors, thus resolving the local TestStruct as fixed in #5418.

To observe the erroneous behavior, go to sway-core/src/type_system/info.rs, to TypeInfo::apply_subfields and add the following debugging lines into the second match arm Some(field) =>:

if decl.call_path.suffix.as_str() == "TestStruct" {
    dbg!(&field.name);
    dbg!(&decl.call_path.prefixes);
    for field in decl.fields.iter() {
        dbg!(&field.name);
    }
    dbg!(&decl.span.as_str());
}

The output will be as follows:

[sway-core/src/type_system/info.rs:1274] &field.name = x
[sway-core/src/type_system/info.rs:1275] &decl.call_path.prefixes = [
    plays,
    lib,    // !!!!!!! Wrong path! This is the path to the lib TestStruct.
]
[sway-core/src/type_system/info.rs:1277] &field.name = x
[sway-core/src/type_system/info.rs:1277] &field.name = y
[sway-core/src/type_system/info.rs:1279] &decl.span.as_str() = "struct TestStruct {\n   x: u64,\n   y: u64,\n}"

Note that the fields are valid, and that also the span points to the local TestStruct.

Comment out the TestStruct in the lib.sw and rebuild the project. This time, as expected, the call_path will contain the valid path to the local TestStruct in main.sw.

[sway-core/src/type_system/info.rs:1274] &field.name = x
[sway-core/src/type_system/info.rs:1275] &decl.call_path.prefixes = [
    plays,
]
[sway-core/src/type_system/info.rs:1277] &field.name = x
[sway-core/src/type_system/info.rs:1277] &field.name = y
[sway-core/src/type_system/info.rs:1279] &decl.span.as_str() = "struct TestStruct {\n   x: u64,\n   y: u64,\n}"

Fixing this issue will also need to check:

  • [ ] if there are other struct decl fields which are wrongly populated
  • [ ] consistency of other items behind structs:
    • [ ] enums
    • [ ] impls
    • [ ] functions
    • [ ] consts

ironcev avatar Jan 21 '24 16:01 ironcev