sway icon indicating copy to clipboard operation
sway copied to clipboard

Non-primitive types are not supported in configuration-time constants

Open matt-user opened this issue 2 years ago • 2 comments

The following code compiles, but throws an error when the owner variable is accessed in a .sw file.

[constants]
owner = { type = "Identity", value = "std::identity::Identity::Address( std::address::Address { value: 0x09c0b2d1a486c439a87bcba6b46a7a1a23f3897cc83a94521a96da5c23bc58db })" }

Error:

  |               ^^^^^ Internal compiler error: Error recovery type cannot be resolved in IR.

Edit: There also seems to be a bug where the type of the literal does not need to match type as in:

[constants]
owner = { type = "Identity", value = "0x09c0b2d1a486c439a87bcba6b46a7a1a23f3897cc83a94521a96da5c23bc58db" }

The above should not compile but it does!

matt-user avatar Aug 29 '22 20:08 matt-user

I slightly modified the title and the description.

The issue here is that the constants are added at the start of the AST and therefore they are type-checked too early. Instead, they should be type-checked in the order that node_dependencies decides on, just like other constants.

For the time being, this feature seems to only be available for primitive types.

mohammadfawaz avatar Aug 29 '22 21:08 mohammadfawaz

Closed this by mistake.

mohammadfawaz avatar Aug 31 '22 13:08 mohammadfawaz

With the new approach of overwriting sections of the bytecode, this won't be possible without performing constant evaluation in the SDK and thusly introducing a dependency on the language. Or, we could try to rip out a constant evaluator library for just the SDK? But that could be quite messy.

Thoughts? @digorithm @mohammadfawaz @adlerjohn

sezna avatar Sep 30 '22 15:09 sezna

this won't be possible without performing constant evaluation in the SDK

Why so? The value to be injected is determined by executing the Rust script, then ABI-encoded.

adlerjohn avatar Sep 30 '22 15:09 adlerjohn

The memory layout spec of Sway is not the same layout as Rust, so evaluating, e.g. Option::Some(0x123123123...) in Rust won't necessarily give you the same bytes as valid Sway would.

sezna avatar Sep 30 '22 15:09 sezna

The memory layout spec of Sway is not the same layout as Rust, so evaluating, e.g. Option::Some(0x123123123...) in Rust won't necessarily give you the same bytes as valid Sway would.

I haven't given much thought to it yet, so I might be missing something here, but wouldn't fuels-rs's ABI encoder deal with it properly? Shouldn't the bytes that are valid Sway adhere to the ABI encoding spec? Option::Some(0x123123123...) from Rust to Fuel's bytecode equivalent should work the same way as it does when we encode/decode when passing non-primitive types in/from contract methods 🤔

digorithm avatar Sep 30 '22 15:09 digorithm

Rust to Fuel's bytecode equivalent should work the same way as it does when we encode/decode when passing non-primitive types in/from contract methods

That's starting to make sense to me as well. The memory layout differences are already handled for function arguments, right?

mohammadfawaz avatar Sep 30 '22 16:09 mohammadfawaz

I see. I was thinking we wanted to support anything that could be in a const, which would be anything constantly evaluatable. The encoder would handle literal cases, but the ABI encoder/decoder doesn't handle arbitrary non-primitives right? So we would have to draw the line there.

sezna avatar Sep 30 '22 17:09 sezna

Closing. The new approach implemented in https://github.com/FuelLabs/sway/pull/3536 does not have this issue.

mohammadfawaz avatar Jan 22 '23 19:01 mohammadfawaz