-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error: Definition of base has to precede definition of derived contract
when specific file in standard-json-input outputSelection
but works when outputSelection
file is specific
#12932
Comments
Definition of base has to precede definition of derived contract
when specific file in outputSelection
but works when outputSelection
file is specificDefinition of base has to precede definition of derived contract
when specific file in standard-json outputSelection
but works when outputSelection
file is specific
Definition of base has to precede definition of derived contract
when specific file in standard-json outputSelection
but works when outputSelection
file is specificDefinition of base has to precede definition of derived contract
when specific file in standard-json-input outputSelection
but works when outputSelection
file is specific
I have extracted minimal code that lets to reproduce the issue:
The interesting thing about the above code is it can be compiled seamlessly after renaming source file names ( |
The proper way to deal with this issue would be to make |
Closing the issue, since it'll be fixed as part of #13365 |
I'm going to reopen this because it does not look like we'll have the full solution promised in #13365 before experimental type system is released (the issue is in fact closed) and such cycles are probably common, which is a significant obstacle for parallelizing compilation. Even if a proper solution requires a rewrite of the whole type checker, I think that there is still a viable workaround that would be good enough. Since full compilation, with all outputs selected, does not seem to have this problem, we could simply run analysis on more files than were selected for output. This would be unnecessary work, but it's just analysis, which is very fast compared to full compilation and optimization, and it's better than not being able to compile at all. I think this must be pretty common, because I stumbled into this problem already in the first project I tried to parallelize, which happened to be Uniswap v4. When comparing the output after compiling each contract independently, I noticed a small discrepancy: artifacts for It could also be worked around at the tooling level - by detecting the circular dependency and requesting more outputs, but this is another wart that will make parallelization more complex for tools. We should be doing it in the compiler instead. I'm going to try to fix it, because the alternative is having to do this in the parallelization PoC instead. ReproDistlled exampleJust for reference, here's the repro that reflects the structure I found in Uniswap: {
"language": "Solidity",
"sources": {
"IX.sol": {"content": "import {I4} from \"I4.sol\"; interface IX {}"},
"I2.sol": {"content": "import {I1} from \"IX.sol\"; interface I2 is I1 {}"},
"I3.sol": {"content": "import {I2} from \"I2.sol\"; interface I3 {}"},
"I4.sol": {"content": "import {S} from \"S.sol\"; interface I4 {}"},
"S.sol": {"content": "import {I3} from \"I3.sol\"; struct S { uint x; }"}
},
"settings": {
"outputSelection": {
"IX.sol": {"*": []}
}
}
} EDIT: Updated the example to rename Full Uniswap reprogit clone https://github.com/Uniswap/v4-core
cd v4-core/
git checkout d0700ceb251afa48df8cc26d593fe04ee5e6b775 # branch main as of 2024-05-10
cat <<-EOF > input.json
{
"language": "Solidity",
"sources": {
"src/interfaces/IProtocolFees.sol": {"urls": ["src/interfaces/IProtocolFees.sol"]}
},
"settings": {
"outputSelection": {
"src/interfaces/IProtocolFees.sol": {"*": ["*"]}
}
}
}
EOF
solc --standard-json input.json --pretty-json --json-indent 4 Output: {
"errors":
[
{
"component": "general",
"errorCode": "2449",
"formattedMessage": "TypeError: Definition of base has to precede definition of derived contract\n --> src/interfaces/IPoolManager.sol:15:27:\n |\n15 | interface IPoolManager is IProtocolFees, IERC6909Claims, IExtsload {\n | ^^^^^^^^^^^^^\n\n",
"message": "Definition of base has to precede definition of derived contract",
"severity": "error",
"sourceLocation":
{
"end": 581,
"file": "src/interfaces/IPoolManager.sol",
"start": 568
},
"type": "TypeError"
}
],
"sources": {}
} |
After spending more time on this, I don't fully agree with analysis in #12932 (comment). I mean, making it possible to avoid this error is indeed a bigger problem and better delegated to #13365 (or actually #14284 which replaced it). The thing is, this issue is not really about that error itself but about the discrepancy that appears when using I investigated the cause and it looks like a bug in the mechanism we have for excluding non-requested contracts (#7018) from compilation: solidity/libsolidity/interface/CompilerStack.cpp Lines 1303 to 1304 in cb1d21a
When a contract is present in the original input but not marked as requested, it is skipped. The problem is that later another contract may pull it in via an import, which means it will still end up in This is entirely fixable. There's just a question if this is not breaking though. By changing the other we'll make the repro compile but I suspect that there will be some cases that compiled and now won't. Still, with this discrepancy affecting parallelization, I think we're much better off treating it as a bug and fixing regardless. |
Description
When compiling with the specific file in the standard-json-input's
outputSelection
field, the compiler throws the errorDefinition of base has to precede definition of derived contract
but when the files in theoutputSelection
is given as"*"
the compiler compiles successfully.Noticed this as the Sourcify recompiler targets the specific file and output in the generated json-input and couldn't compile but the user was able to compile and deploy the contract via Hardhat (which has
"*"
inoutputSelection
.)I'd say the error is correct since according to the order of importing the definition of the base contract is below the inheriting contract, as suggested by the error. Nevertheless a change in the
outputSelection
should not be effecting how the compiler behaves.this
outputSelection
throws:while this compiles:
Environment
Steps to Reproduce
I am adding the full standard-json-input files with just the diff in the
outputSelection
. Also adding the.sol
files for reference.compiles-with-asterisk.json.txt
error-specific-file.json.txt
TeleportToken.sol.txt
TeleportTokenFactory.sol.txt
The text was updated successfully, but these errors were encountered: