Support inherited constructor override
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 29
Description
## Abstract
I want to do this:
```solidity
abstract contract A {
uint256 immutable FOO;
constructor (uint256 _foo) {
FOO = _foo;
}
}
contract B is A {
uint256 immutable BAR;
constructor (uint256 _bar) A(block.timestamp){
BAR = _bar;
}
}
contract C is B {
constructor (uint256 _foo, uint256 _bar)
A(_foo)
B(_bar)
{
}
}
```
## Motivation
Sometimes changing the behavior of a constructor is needed. Specially when it is overriding another constructor.
I have a contract structure like this:
```solidity
// SPDX-License-Identifier: MIT-1.0
pragma solidity ^0.8.28;
contract MyStorage {
uint256 value;
function setValue(uint256 _value) external {
value = _value;
}
function getValue() external returns (uint256) {
return value;
}
}
abstract contract MyLogic {
MyStorage immutable public MY_STORAGE;
constructor (MyStorage myStorage) {
MY_STORAGE = myStorage;
}
}
contract MyImplementation is MyLogic {
constructor () MyLogic(new MyStorage()){
}
}
contract MyImplementationUpdated is MyImplementation {
MyImplementation immutable PARENT_IMPLEMENTATION;
constructor (MyImplementation _parentImplementation)
MyLogic(_parentImplementation.MY_STORAGE())
{
_parentImplementation = PARENT_IMPLEMENTATION;
}
}
```
This errors:
```
DeclarationError: Base constructor arguments given twice.
--> InheritanceConstructor.sol:37:9:
|
37 | MyLogic(_parentImplementation.MY_STORAGE())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: Second constructor call is here:
--> InheritanceConstructor.sol:26:20:
|
26 | constructor () MyLogic(new MyStorage()){
| ^^^^^^^^^^^^^^^^^^^^^^^^
```
## Specification
My suggestion is to allow remove the automatic inherit of constructor when needed,then developers call super() or allow the use of `override` keyword in constructor - which then would remove the automatic inherited constructor.
Using override:
```solidity
constructor (MyImplementation _parentImplementation) override
MyLogic(_parentImplementation.MY_STORAGE())
{
_parentImplementation = PARENT_IMPLEMENTATION;
}
```
Using super:
```solidity
constructor (MyImplementation _parentImplementation)
{
super.MyLogic(_parentImplementation.MY_STORAGE());
_parentImplementation = PARENT_IMPLEMENTATION;
}
```
## Backwards Compatibility
If not using super or override, the behavior would be as it is.
Contributor guide
Research direction
Start by reproducing the Solidity examples and the “Base constructor arguments given twice” diagnostic, then compare the proposed override and super forms with the current inheritance behavior. Done means an agreed constructor-override design, defined behavior for the examples, and preserved behavior when neither form is used.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- solidity
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100