-
Notifications
You must be signed in to change notification settings - Fork 2k
Go: Update to 1.27 #22042
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Go: Update to 1.27 #22042
Changes from all commits
076f53e
36c7fba
f0d1d65
4af6fed
0c12d92
966f86b
45e420b
91e1d28
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,7 +32,13 @@ import ( | |
| ) | ||
|
|
||
| var MaxGoRoutines int | ||
| var typeParamParent map[*types.TypeParam]types.Object = make(map[*types.TypeParam]types.Object) | ||
|
|
||
| type typeParamParentEntry struct { | ||
| parent types.Object | ||
| index int | ||
| } | ||
|
|
||
| var typeParamParent map[*types.TypeParam]typeParamParentEntry = make(map[*types.TypeParam]typeParamParentEntry) | ||
|
|
||
| func init() { | ||
| // this sets the number of threads that the Go runtime will spawn; this is separate | ||
|
|
@@ -530,8 +536,10 @@ func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label) | |
| // do not appear as objects in any scope, so they have to be dealt | ||
| // with separately in extractMethods. | ||
| if funcObj, ok := obj.(*types.Func); ok { | ||
| populateTypeParamParents(funcObj.Type().(*types.Signature).TypeParams(), obj) | ||
| populateTypeParamParents(funcObj.Type().(*types.Signature).RecvTypeParams(), obj) | ||
| typeParams := funcObj.Type().(*types.Signature).TypeParams() | ||
| populateTypeParamParents(typeParams, obj, 0) | ||
| recvTypeParams := funcObj.Type().(*types.Signature).RecvTypeParams() | ||
| populateTypeParamParents(recvTypeParams, obj, typeParams.Len()) | ||
| } | ||
| // Populate type parameter parents for defined types and alias types. | ||
| if typeNameObj, ok := obj.(*types.TypeName); ok { | ||
|
|
@@ -542,9 +550,9 @@ func extractObjects(tw *trap.Writer, scope *types.Scope, scopeLabel trap.Label) | |
| // careful with alias types because before Go 1.24 they would | ||
| // return the underlying type. | ||
| if tp, ok := typeNameObj.Type().(*types.Named); ok && !typeNameObj.IsAlias() { | ||
| populateTypeParamParents(tp.TypeParams(), obj) | ||
| populateTypeParamParents(tp.TypeParams(), obj, 0) | ||
| } else if tp, ok := typeNameObj.Type().(*types.Alias); ok { | ||
| populateTypeParamParents(tp.TypeParams(), obj) | ||
| populateTypeParamParents(tp.TypeParams(), obj, 0) | ||
| } | ||
| } | ||
| extractObject(tw, obj, lbl) | ||
|
|
@@ -570,8 +578,10 @@ func extractMethod(tw *trap.Writer, meth *types.Func) trap.Label { | |
| if !exists { | ||
| // Populate type parameter parents for methods. They do not appear as | ||
| // objects in any scope, so they have to be dealt with separately here. | ||
| populateTypeParamParents(meth.Type().(*types.Signature).TypeParams(), meth) | ||
| populateTypeParamParents(meth.Type().(*types.Signature).RecvTypeParams(), meth) | ||
| typeParams := meth.Type().(*types.Signature).TypeParams() | ||
| populateTypeParamParents(typeParams, meth, 0) | ||
| recvTypeParams := meth.Type().(*types.Signature).RecvTypeParams() | ||
| populateTypeParamParents(recvTypeParams, meth, typeParams.Len()) | ||
| extractObject(tw, meth, methlbl) | ||
| } | ||
|
|
||
|
|
@@ -1660,7 +1670,8 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label { | |
| // parent scope, so they are not dealt with by `extractScopes` | ||
| for i := 0; i < origintp.NumMethods(); i++ { | ||
| meth := origintp.Method(i).Origin() | ||
|
|
||
| typeParams := tp.Method(i).Type().(*types.Signature).TypeParams() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure that this line wants to use the instantiated receiver type ( Perhaps we should put a short comment here, as it will no doubt be confusing to future readers as well.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I can tell, it needs to be |
||
| populateTypeParamParents(typeParams, meth, 0) | ||
| extractMethod(tw, meth) | ||
| } | ||
|
|
||
|
|
@@ -1684,9 +1695,9 @@ func extractType(tw *trap.Writer, tp types.Type) trap.Label { | |
| } | ||
| case *types.TypeParam: | ||
| kind = dbscheme.TypeParamType.Index() | ||
| parentlbl := getTypeParamParentLabel(tw, tp) | ||
| parentlbl, idx := getTypeParamParentLabel(tw, tp) | ||
| constraintLabel := extractType(tw, tp.Constraint()) | ||
| dbscheme.TypeParamTable.Emit(tw, lbl, tp.Obj().Name(), constraintLabel, parentlbl, tp.Index()) | ||
| dbscheme.TypeParamTable.Emit(tw, lbl, tp.Obj().Name(), constraintLabel, parentlbl, idx) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should update the QLDoc for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm happy to switch the order. I just kept things in the order in which the code appears for now. |
||
| case *types.Union: | ||
| kind = dbscheme.TypeSetLiteral.Index() | ||
| for i := 0; i < tp.Len(); i++ { | ||
|
|
@@ -1826,8 +1837,7 @@ func getTypeLabel(tw *trap.Writer, tp types.Type) (trap.Label, bool) { | |
| } | ||
| lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%s};definedtype", entitylbl)) | ||
| case *types.TypeParam: | ||
| parentlbl := getTypeParamParentLabel(tw, tp) | ||
| idx := tp.Index() | ||
| parentlbl, idx := getTypeParamParentLabel(tw, tp) | ||
| lbl = tw.Labeler.GlobalID(fmt.Sprintf("{%v},%d,%s;typeparamtype", parentlbl, idx, tp.Obj().Name())) | ||
| case *types.Union: | ||
| var b strings.Builder | ||
|
|
@@ -2013,10 +2023,10 @@ func extractTypeParamDecls(tw *trap.Writer, fields *ast.FieldList, parent trap.L | |
| } | ||
|
|
||
| // populateTypeParamParents sets `parent` as the parent of the elements of `typeparams` | ||
| func populateTypeParamParents(typeparams *types.TypeParamList, parent types.Object) { | ||
| func populateTypeParamParents(typeparams *types.TypeParamList, parent types.Object, offset int) { | ||
| if typeparams != nil { | ||
| for idx := 0; idx < typeparams.Len(); idx++ { | ||
| setTypeParamParent(typeparams.At(idx), parent) | ||
| setTypeParamParent(typeparams.At(idx), parent, idx+offset) | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -2065,24 +2075,24 @@ func trackInstantiatedStructFields(tw *trap.Writer, tp, origintp *types.Named) { | |
| } | ||
| } | ||
|
|
||
| func getTypeParamParentLabel(tw *trap.Writer, tp *types.TypeParam) trap.Label { | ||
| parent, exists := typeParamParent[tp] | ||
| func getTypeParamParentLabel(tw *trap.Writer, tp *types.TypeParam) (trap.Label, int) { | ||
| entry, exists := typeParamParent[tp] | ||
| if !exists { | ||
| log.Fatalf("Parent of type parameter does not exist: %s %s", tp.String(), tp.Constraint().String()) | ||
| } | ||
| parentlbl, _ := tw.Labeler.ScopedObjectID(parent, func() trap.Label { | ||
| parentlbl, _ := tw.Labeler.ScopedObjectID(entry.parent, func() trap.Label { | ||
| log.Fatalf("getTypeLabel() called for parent of type parameter %s", tp.String()) | ||
| return trap.InvalidLabel | ||
| }) | ||
| return parentlbl | ||
| return parentlbl, entry.index | ||
| } | ||
|
|
||
| func setTypeParamParent(tp *types.TypeParam, newobj types.Object) { | ||
| obj, exists := typeParamParent[tp] | ||
| func setTypeParamParent(tp *types.TypeParam, newobj types.Object, idx int) { | ||
| entry, exists := typeParamParent[tp] | ||
| if !exists { | ||
| typeParamParent[tp] = newobj | ||
| } else if newobj != obj { | ||
| log.Fatalf("Parent of type parameter '%s %s' being set to a different value: '%s' vs '%s'", tp.String(), tp.Constraint().String(), obj, newobj) | ||
| typeParamParent[tp] = typeParamParentEntry{newobj, idx} | ||
| } else if entry.parent != newobj || entry.index != idx { | ||
| log.Fatalf("Parent of type parameter '%s %s' being set to a different value: '%s' vs '%s'", tp.String(), tp.Constraint().String(), entry.parent, newobj) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error message is slightly inaccurate, as it only prints the objects but it could be printed if the objects are the same but the indexes are different. It's not a big thing, but consider printing the indexes as well (or the |
||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| --- | ||
| category: majorAnalysis | ||
| --- | ||
| * Go 1.27 is now supported. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package main | ||
|
|
||
| type StructForGenericMethod1 struct{} | ||
|
|
||
| func (*StructForGenericMethod1) GenericMethod1[P any](x P) {} | ||
|
|
||
| type StructForGenericMethod2[P any] struct{} | ||
|
|
||
| func (*StructForGenericMethod2[P]) GenericMethod2[Q any](x Q) {} | ||
|
|
||
| func generic_methods(s1 StructForGenericMethod1, s2 StructForGenericMethod2[int]) { | ||
| // Call the generic method specifying the type | ||
| s1.GenericMethod1[int](1) | ||
| s2.GenericMethod2[string]("hello") | ||
|
|
||
| // Call the generic method without specifying the type | ||
| s1.GenericMethod1("hello") | ||
| s2.GenericMethod2(42) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| module codeql-go-tests/function | ||
|
|
||
| go 1.18 | ||
| go 1.27 | ||
|
|
||
| toolchain go1.27rc1 | ||
|
|
||
| require github.com/anotherpkg v0.0.0-20200203000000-0000000000000 | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In theory these lines shouldn't be needed here, because the comment above says that methods do not appear as objects in any scope, so we should only be dealing with top-level functions. However, rather than deleting it, I think it would be better to create a separate function for these four lines, as they are duplicated lower down. Maybe
populateTypeParamParentsFromFunction(funcObj *types.Func). (Can you tell I like long method names? 😆 )There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to refactor. The only thing I changed here was the addition of the offset. I simply assumed that this code was necessary (because it was already there 😄 ).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point 😆