“Static import” of symbols from library

Currently in Solidity any references to symbols defined in an imported library need to be qualified with the name of that library, e.g.:

// Lib.sol
library Lib {
    struct Counter { … }
    uint256 constant internal ZERO = 0;
}

import { Counters } from "./Lib.sol";
contract Example {
    using Counters for Counters.Counter;
    Counters.Counter private _counter;
    function test() external pure returns (uint256) {
      return Lib.ZERO;
    }
}

How do you feel about something like:

import { Counters, Counters.Counter, Counters.ZERO } from "./Lib.sol";
contract Example {
    using Counters for Counter;
    Counter private _counter;
    function test() external pure returns (uint256) {
      return ZERO;
    }
}

?

We could have something like import {Counters.Counter as Counter} from "./Lib.sol", but I’m not sure we should allow reaching inside scopes. On the other hand, Solidity currently allows most of the items you put inside the library to be put at file level, so maybe this is not such a problem after all?

struct Counter { .... }
uint256 constant ZERO = 0;
...
library Counters {
  /* only the functions need to be here and only because we have not implemented "using" for file-level functions yet */
}
2 Likes

Thank you so much @chriseth. I had no idea this was possible! Nor that it was possible to write free functions. TBH I’ve never witnessed any of these “in the wild.”

I believe the possibility to define these “free” symbols renders my original “static import” suggestion redundant. I’m glad I asked this question :slightly_smiling_face:. Thanks again.