Received InternalCompilerError without any description when we are trying to pass a struct to a function as a memory argument (using ABIEncoderV2) and the struct contains a mapping in it. Although, passing a mapping to a function is not allowed by design, i think to have an InternalCompilerError without any description is a real issue indeed.
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12 <0.7.0;
pragma experimental ABIEncoderV2;
library TestModel0 {
struct Data {
mapping (uint => uint) d;
}
function addData(Data storage self, Data memory _data) public {
/* any code here */
}
}

I think this ICE is valid only for pragma solidity <0.7.0; The ICE goes away for pragma solidity >0.7.0;
I think this ICE is valid only for pragma solidity <0.7.0; The ICE goes away for pragma solidity >0.7.0;
Thanks for your reply. May i know if there is any chance to have this fix in 0.6.x or even earlier versions?
unfortunately, i still encounter an InternalCompilerError (with no description) in 0.7.1 when i have a get function, which outputs a storage, in the above library and use another contract to import the library and call that get function.
Can you provide an example for the above scenario?
Can you provide an example for the above scenario?
try to compile the following code in Remix, solc 0.7.1
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0;
pragma experimental ABIEncoderV2;
library TestLibrary {
struct Items {
mapping (uint => uint) a;
}
struct Data {
mapping (uint => Items) d;
}
function get(Data storage self, uint _key) public returns (Items storage) {
return self.d[_key];
}
}
contract TestContract {
using TestLibrary for TestLibrary.Data;
TestLibrary.Data s_data;
function testFunction(uint _key) public {
// The following 2 lines are expected to do the same thing...
// TestLibrary.Items storage _items_1 = s_data.get(1); // Uncomment this line will give InternalCompilerError:
TestLibrary.Items storage _items_2 = s_data.d[1];
}
}
thanks a lot for the help there.
Smaller example:
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.1;
pragma experimental ABIEncoderV2;
library TestLibrary {
struct Items {
mapping (uint => uint) a;
}
function get() public returns (Items storage x) {
assembly { x.slot := 0 }
}
}
contract TestContract {
function testFunction() public {
TestLibrary.get();
}
}
Yeah the above scenario seems like a bug. ICE gets generated when compiling the above code using SMTEncoder.
/solidity/libsolidity/ast/Types.cpp(2337):Throw in function virtual bool
solidity::frontend::StructType::isDynamicallyEncoded() const Dynamic exception type:
boost::wrapexcept<solidity::langutil::InternalCompilerError>
std::exception::what:
[solidity::util::tag_comment*] =
Yeah the above scenario seems like a bug. ICE gets generated when compiling the above code using SMTEncoder.
/solidity/libsolidity/ast/Types.cpp(2337):Throw in function virtual bool solidity::frontend::StructType::isDynamicallyEncoded() const Dynamic exception type: boost::wrapexcept<solidity::langutil::InternalCompilerError> std::exception::what: [solidity::util::tag_comment*] =
Thanks for confirming.
Any work around for the moment?
Yeah. Thanks for mentioning the issue :)
As a workaround, you could pass it over as a different type (a struct with a single integer member, for example) and then use inline assembly on both sides to change the type...
As a workaround, you could pass it over as a different type (a struct with a single integer member, for example) and then use inline assembly on both sides to change the type...
not quite familiar with the inline assembly, any hope to have some more hints on that?
thanks.
Fuzzer eventually turns this up, too. Not a fuzz-blocker, per se, but a false positive (well, dup) that has to be inspected from time to time.
Most helpful comment
Smaller example: