computeInterfaceTypeSet may be called with check == nil.
(check *Checker, pos Pos, ityp *Interface)
| 152 | |
| 153 | // computeInterfaceTypeSet may be called with check == nil. |
| 154 | func computeInterfaceTypeSet(check *Checker, pos Pos, ityp *Interface) *_TypeSet { |
| 155 | if ityp.tset != nil { |
| 156 | return ityp.tset |
| 157 | } |
| 158 | |
| 159 | // If the interface is not fully set up yet, the type set will |
| 160 | // not be complete, which may lead to errors when using the |
| 161 | // type set (e.g. missing method). Don't compute a partial type |
| 162 | // set (and don't store it!), so that we still compute the full |
| 163 | // type set eventually. Instead, return the top type set and |
| 164 | // let any follow-on errors play out. |
| 165 | if !ityp.complete { |
| 166 | return &topTypeSet |
| 167 | } |
| 168 | |
| 169 | if check != nil && check.conf.Trace { |
| 170 | // Types don't generally have position information. |
| 171 | // If we don't have a valid pos provided, try to use |
| 172 | // one close enough. |
| 173 | if !pos.IsKnown() && len(ityp.methods) > 0 { |
| 174 | pos = ityp.methods[0].pos |
| 175 | } |
| 176 | |
| 177 | check.trace(pos, "-- type set for %s", ityp) |
| 178 | check.indent++ |
| 179 | defer func() { |
| 180 | check.indent-- |
| 181 | check.trace(pos, "=> %s ", ityp.typeSet()) |
| 182 | }() |
| 183 | } |
| 184 | |
| 185 | // An infinitely expanding interface (due to a cycle) is detected |
| 186 | // elsewhere (Checker.validType), so here we simply assume we only |
| 187 | // have valid interfaces. Mark the interface as complete to avoid |
| 188 | // infinite recursion if the validType check occurs later for some |
| 189 | // reason. |
| 190 | ityp.tset = &_TypeSet{terms: allTermlist} // TODO(gri) is this sufficient? |
| 191 | |
| 192 | var unionSets map[*Union]*_TypeSet |
| 193 | if check != nil { |
| 194 | if check.unionTypeSets == nil { |
| 195 | check.unionTypeSets = make(map[*Union]*_TypeSet) |
| 196 | } |
| 197 | unionSets = check.unionTypeSets |
| 198 | } else { |
| 199 | unionSets = make(map[*Union]*_TypeSet) |
| 200 | } |
| 201 | |
| 202 | // Methods of embedded interfaces are collected unchanged; i.e., the identity |
| 203 | // of a method I.m's Func Object of an interface I is the same as that of |
| 204 | // the method m in an interface that embeds interface I. On the other hand, |
| 205 | // if a method is embedded via multiple overlapping embedded interfaces, we |
| 206 | // don't provide a guarantee which "original m" got chosen for the embedding |
| 207 | // interface. See also issue #34421. |
| 208 | // |
| 209 | // If we don't care to provide this identity guarantee anymore, instead of |
| 210 | // reusing the original method in embeddings, we can clone the method's Func |
| 211 | // Object and give it the position of a corresponding embedded interface. Then |
no test coverage detected