@@ -234,13 +234,11 @@ func lockPath(tpkg *types.Package, typ types.Type) typePath {
234
234
return nil
235
235
}
236
236
237
- // We're looking for cases in which a reference to this type
238
- // can be locked , but a value cannot . This differentiates
237
+ // We're looking for cases in which a pointer to this type
238
+ // is a sync.Locker , but a value is not . This differentiates
239
239
// embedded interfaces from embedded values.
240
- if plock := types .NewMethodSet (types .NewPointer (typ )).Lookup (tpkg , "Lock" ); plock != nil {
241
- if lock := types .NewMethodSet (typ ).Lookup (tpkg , "Lock" ); lock == nil {
242
- return []types.Type {typ }
243
- }
240
+ if types .Implements (types .NewPointer (typ ), lockerType ) && ! types .Implements (typ , lockerType ) {
241
+ return []types.Type {typ }
244
242
}
245
243
246
244
nfields := styp .NumFields ()
@@ -254,3 +252,15 @@ func lockPath(tpkg *types.Package, typ types.Type) typePath {
254
252
255
253
return nil
256
254
}
255
+
256
+ var lockerType * types.Interface
257
+
258
+ // Construct a sync.Locker interface type.
259
+ func init () {
260
+ nullary := types .NewSignature (nil , nil , nil , false ) // func()
261
+ methods := []* types.Func {
262
+ types .NewFunc (token .NoPos , nil , "Lock" , nullary ),
263
+ types .NewFunc (token .NoPos , nil , "Unlock" , nullary ),
264
+ }
265
+ lockerType = types .NewInterface (methods , nil ).Complete ()
266
+ }
0 commit comments