https://andpad.connpass.com/event/212051/
空の型セットを検出したいhttps://andpad.connpass.com/event/212051/2021/05/19(水) @shino_nobishii
View Slide
自己紹介- Nobishii(のびしー) @shino_nobishii- Go言語経験 2020年2月〜- 静的解析初心者- Go言語仕様書の知識が少しあります
目次- 背景: 型パラメータと型制約と型セット- 型セットの具体例- 問題: 空の型セット- Underlying type- サンプルコード: Underlying typeが自分自身かどうかを判定する- 参考資料
型セットってなんだ?いきなり知らないものが出てきたけど...
背景- 型パラメータ(ジェネリクス) Proposal: accepted- 型制約をinterfaceとして記述する- 型セットProposal: acceptedではないけどacceptされそうな状況- 型制約の記述方法を改善するもの- 全ての型は、型セットを持つ- 「型Tがinterface Iを実装する」は「型TがIの型セットに属する」と同じ意味になる
型セットの具体例
underlying typeってなんだ?また知らないものが出てきたけど...少し後で出てきます!
空の型セット問題: これを実装する型は存在しない!https://github.com/golang/go/issues/45346 より引用
結論:コンパイラで空の型セットはチェックされない我々は諦めない。コンパイラも使わず、コードを実行もせずに型セットの性質を調べる、そんな手段を見つけさえすればいいのだ。あるいは夢物語かもしれないが ...
静的解析で型セットを調べる- 「空の型セット」の検出を一般的に解決するのは難しい- 特定の場合なら解決できる- その一つが”underlying type”に関係するパターン- 静的解析を使う
underlying typeとは
underlying typeとは- ~Tは、「underlying typeがTであるような全ての型」の集合- ~int は{int , MyInt, MyMyInt, …}- ~MyInt は {} (空集合)- underlying typeがMyIntになるような型は存在しないから- intの特徴: underlying typeが自分自身
判定方法- ~SomeTypeをParseする(※今日は行いません)- SomeTypeのunderlying typeがSomeTypeに等しいかどうか調べる- 使う関数:- (*types.Package).Scope() *types.Scope- パッケージレベルで宣言されたモノを取得- (*types.Scope).Lookup(name string) types.Object- Scopeから名前で検索- (types.Type).Underlying() types.Type- ある型のunderlying typeを返す
Underlying typeが自分自身かどうかを判定する- サンプルコードをきれいに貼れなかったのでGitHubで説明します- https://github.com/nobishino/studyast/blob/main/main.go#L40
参考資料- Go公式資料- Type Parameters Proposal 型パラメータ(ジェネリクス)に関するProposal(accepted)- https://github.com/golang/go/issues/45346 型セットに関するProposal- その他資料- Go の "Type Sets" proposal を読む- underlying types by DQNEOさん- 発表アーカイブ動画- 勇者さま一行のイラストは いらすとや様からお借りしました