crates/lint/docs/var-read-using-this.md
thisSeverity: Gas
ID: var-read-using-this
Flags reads of the contract's own state through this.X(...). Calling a public state-variable
getter or any view/pure function via this performs an external STATICCALL to the same
address, paying the call overhead for data that could be read directly.
Reports this.<name>(<args>) calls where <name> resolves (via overload resolution by arity) to
a function reachable on the contract's external interface (public or external) whose state
mutability is view or pure. This includes:
public state variable (simple variables, mappings, arrays).public/external view/pure function declared in a base contract.When the offending call is the auto-generated getter for a state variable, the lint emits a code fix:
this.foo() → foo (machine-applicable).this.m(k) → m[k] (maybe-incorrect; double-check the rewrite).Calls that carry call options (e.g. this.foo{gas: 1000}()) are still flagged, but no fix is
suggested — the developer is intentionally reaching for the external-call machinery.
Each this.X(...) call compiles to a STATICCALL to the contract's own address. That costs a
fixed amount of gas, plus the encoding/decoding of arguments and return data, in addition to the
storage read itself. Reading the variable directly skips the call entirely.
contract C {
uint256 public counter;
mapping(uint256 => address) public owners;
function readDirect() external view returns (uint256, address) {
// Each `this.X` performs an unnecessary STATICCALL.
return (this.counter(), this.owners(0));
}
}
contract C {
uint256 public counter;
mapping(uint256 => address) public owners;
function readDirect() external view returns (uint256, address) {
// Direct storage reads — no external call.
return (counter, owners[0]);
}
}
This is a Gas-severity lint and is not applied to test or script files.
For external view/pure functions, calling them via this from inside the contract is the
only in-contract syntax that resolves; the recommended fix is to extract the body into an
internal helper that both the external entry point and the local caller invoke.