Skip to content
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

[DO NOT MERGE] Clean up inheritance specification. #3729

Closed
wants to merge 2 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 51 additions & 9 deletions docs/contracts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -818,9 +818,9 @@ Additional Resources for Understanding Events
Inheritance
***********

Solidity supports multiple inheritance by copying code including polymorphism.
Solidity supports multiple inheritance including polymorphism.

All function calls are virtual, which means that the most derived function
All function calls (this includes external and internal calls) are virtual, which means that the most derived function
is called, except when the contract name is explicitly given.

When a contract inherits from multiple contracts, only a single
Expand All @@ -831,6 +831,48 @@ The general inheritance system is very similar to
`Python's <https://docs.python.org/3/tutorial/classes.html#inheritance>`_,
especially concerning multiple inheritance.

If a function is callable on a contract, it must also be callable in the derived contract.
This means that visibility and mutability of functions cannot be restricted, but it
can be extended. The visibility can change from external to public, but not from public
to external or from external to internal. Functions that are marked ``view`` in the
super contract, can be marked ``pure`` in the derived contract, but not the other
way around.

If a function overrides a function from a super contract, it needs the ``override`` specifier,
everything else is treated as an error.

An external function (but not a function of any other visibility) can be overridden by a public
state variable. This means that the public state variable also needs the ``override`` keyword.

Any other use of overriding between functions, modifiers, state variable or user-defined types
(meaning overriding a function with a modifier or a state variable with a function, etc.) is disallowed.
This means that you cannot declare a struct which has the same name as a function in super contract.

Modifiers are treated in much the same way as functions: They use virtual lookup, require the
``override`` specifier, can use overloading and can have a missing implementation.

It is an error for two contracts in an inheritance hierarchy to have a member of the same name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this can be simplified:

Every function of a contract must be defined once, and may be overridden as per the rules above. Therefore it is an error for a contract's inheritance hierarchy (of contracts and interfaces) to include the same function definition more than once.

or...

Every function of a contract must be defined once, and may be overridden as per the rules above. Therefore it is an error for a contract's inheritance hierarchy of contracts to include the same function definition more than once.

More discussion on this is at: #3729 (comment)

unless one member (``f_B``) is defined in a class (``B``) that derives (directly or indirectly) from the
class (``A``) the other member (``f_A``) is defined in; and: ``f_B`` uses the ``override`` keyword, ``f_A`` is a
function and ``f_B`` is either a function or a public state variable, both are compatible with
regards to visibility and state mutability as per the above rules and both have exactly the same
parameter and return types.

This in particular means that `private` members are not hidden from this mechanism and that
overriding and overloading is incompatible. It also means that it is disallowed to inherit
members of the same name that come from different base contracts unless they share a common
base contract that defines the function to be overridden.

As it is often useful to inherit the natspec comments for functions from super contracts.
This has to be done explicitly using the ``@inherit`` natspec tag. This tag
will inherit all properties that are not re-defined in the function of the derived contract.

TODO:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move TODO to PR discussion, not the PR commits.


- [ ] shall we make overriding and overloading work at the same time?
- [ ] shall we allow name clashes with private members?
- [ ] what about functions that have different return types?

Details are given in the following example.

::
Expand Down Expand Up @@ -1116,13 +1158,13 @@ facilitating patterns like the `Template method <https://en.wikipedia.org/wiki/T
Interfaces
**********

Interfaces are similar to abstract contracts, but they cannot have any functions implemented. There are further restrictions:
Interfaces are restrictions of abstract contracts in the following way:

#. Cannot inherit other contracts or interfaces.
#. Cannot define constructor.
#. Cannot define variables.
#. Cannot define structs.
#. Cannot define enums.
#. Interfaces cannot have implemented functions (only function declarations).
#. Interfaces cannot inherit other contracts (but they can inherit interfaces).
#. Interfaces cannot define a constructor.
#. Interfaces cannot define variables.
#. Functions in interfaces have to have ``external`` visibility.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

must have


Some of these restrictions might be lifted in the future.

Expand All @@ -1136,7 +1178,7 @@ Interfaces are denoted by their own keyword:
pragma solidity ^0.4.11;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please bump this version, because of external.


interface Token {
function transfer(address recipient, uint amount) public;
function transfer(address recipient, uint amount) external;
}

Contracts can inherit interfaces as they would inherit other contracts.
Expand Down