Remove access to `this` from libraries
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 21
Description
Depends on #16368.
Currently the language in some cases allows accessing `this` outside of the current contract (most notably from within libraries). This breaks the object-oriented abstraction and only "works" because it was not implemented consistently. The only construct usable in practice is `address(this)`.
It would make more sense for `this` to refer to the library instance, but we don't really have those in the language. A simpler solution is to not provide `this` at all.
Once we introduce `msg.to` built-in (#16368), we'll have replacements for all practical use cases.
## Example
```solidity
contract C {
function f() external {}
}
library L {
function f() external {}
function g() external {
C(address(this)).f(); // Calls C.f()
this.f(); // Error: Member "f" not found or not visible after argument-dependent lookup in library L.
C c = this; // Error: Type library L is not implicitly convertible to expected type contract C.
}
```
The language as it is now cannot make up its mind whether it wants `this` to be `C` or `L` and sometimes even ends up with neither (why can't you call either version of `f()` via `this`?).
There are 3 ways to fix the inconsistency:
1. Make `this` refer to the contract instance. This is unintuitive and, if properly implemented, would make `this` a polymorphic variable, something that will only exist in Core Solidity. In the current language it would be possible but only as an odd, hard-coded corner case.
1. Make `this` refer to the library instance. This would be logical, but inconsistent with current design. The language bends backwards not to provide library instances (e.g. unlike with contracts, external functions are called via type name).
- On the other hand it would introduce a natural high-level syntax for delegatecalls between external library functions. Which may or may not be a good thing. Currently it is explicitly disallowed, because it was not seen as desirable.
1. Remove `this` in this context. Least work, no ambiguities. Also does not remove any functionality that is already available by other means.
## Backwards Compatibility
This is a breaking change, unless we keep `address(this)` as a special case.
Contributor guide
Research direction
Start by reading the language-semantics discussion in this issue and its dependency, #16368. Determine how library uses of `this` are currently accepted, including the examples shown, and verify that removing those uses preserves the stated `address(this)` compatibility and leaves clear diagnostics.
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
- 35/100