Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 5257c4a

Browse files
owen-mcsmowton
authored andcommitted
Add control flow test
1 parent 26d4acd commit 5257c4a

File tree

3 files changed

+245
-0
lines changed

3 files changed

+245
-0
lines changed

ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/CFG.expected

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,111 @@ edges
496496
| exprs.go:94:16:94:16 | (...) is false | exprs.go:94:21:94:21 | z |
497497
| exprs.go:94:16:94:16 | (...) is true | exprs.go:94:9:94:21 | ...\|\|... |
498498
| exprs.go:94:21:94:21 | z | exprs.go:94:9:94:21 | ...\|\|... |
499+
| generic.go:0:0:0:0 | entry | generic.go:3:1:5:1 | skip |
500+
| generic.go:3:1:5:1 | skip | generic.go:7:28:7:35 | skip |
501+
| generic.go:7:1:7:1 | entry | generic.go:7:7:7:7 | argument corresponding to g |
502+
| generic.go:7:1:7:55 | function declaration | generic.go:9:1:12:1 | skip |
503+
| generic.go:7:7:7:7 | argument corresponding to g | generic.go:7:7:7:7 | initialization of g |
504+
| generic.go:7:7:7:7 | initialization of g | generic.go:7:37:7:37 | argument corresponding to u |
505+
| generic.go:7:28:7:35 | skip | generic.go:7:1:7:55 | function declaration |
506+
| generic.go:7:37:7:37 | argument corresponding to u | generic.go:7:37:7:37 | initialization of u |
507+
| generic.go:7:37:7:37 | initialization of u | generic.go:7:53:7:53 | u |
508+
| generic.go:7:46:7:53 | return statement | generic.go:7:55:7:55 | exit |
509+
| generic.go:7:53:7:53 | u | generic.go:7:46:7:53 | return statement |
510+
| generic.go:9:1:12:1 | skip | generic.go:14:31:14:39 | skip |
511+
| generic.go:14:1:14:1 | entry | generic.go:14:7:14:7 | argument corresponding to g |
512+
| generic.go:14:1:14:59 | function declaration | generic.go:16:6:16:21 | skip |
513+
| generic.go:14:7:14:7 | argument corresponding to g | generic.go:14:7:14:7 | initialization of g |
514+
| generic.go:14:7:14:7 | initialization of g | generic.go:14:41:14:41 | argument corresponding to u |
515+
| generic.go:14:31:14:39 | skip | generic.go:14:1:14:59 | function declaration |
516+
| generic.go:14:41:14:41 | argument corresponding to u | generic.go:14:41:14:41 | initialization of u |
517+
| generic.go:14:41:14:41 | initialization of u | generic.go:14:57:14:57 | u |
518+
| generic.go:14:50:14:57 | return statement | generic.go:14:59:14:59 | exit |
519+
| generic.go:14:57:14:57 | u | generic.go:14:50:14:57 | return statement |
520+
| generic.go:16:1:16:1 | entry | generic.go:16:30:16:30 | argument corresponding to t |
521+
| generic.go:16:1:18:1 | function declaration | generic.go:20:6:20:21 | skip |
522+
| generic.go:16:6:16:21 | skip | generic.go:16:1:18:1 | function declaration |
523+
| generic.go:16:30:16:30 | argument corresponding to t | generic.go:16:30:16:30 | initialization of t |
524+
| generic.go:16:30:16:30 | initialization of t | generic.go:17:9:17:9 | t |
525+
| generic.go:17:2:17:9 | return statement | generic.go:18:1:18:1 | exit |
526+
| generic.go:17:9:17:9 | t | generic.go:17:2:17:9 | return statement |
527+
| generic.go:20:1:20:1 | entry | generic.go:20:33:20:33 | argument corresponding to s |
528+
| generic.go:20:1:22:1 | function declaration | generic.go:24:6:24:12 | skip |
529+
| generic.go:20:6:20:21 | skip | generic.go:20:1:22:1 | function declaration |
530+
| generic.go:20:33:20:33 | argument corresponding to s | generic.go:20:33:20:33 | initialization of s |
531+
| generic.go:20:33:20:33 | initialization of s | generic.go:20:38:20:38 | argument corresponding to t |
532+
| generic.go:20:38:20:38 | argument corresponding to t | generic.go:20:38:20:38 | initialization of t |
533+
| generic.go:20:38:20:38 | initialization of t | generic.go:21:9:21:9 | s |
534+
| generic.go:21:2:21:12 | return statement | generic.go:22:1:22:1 | exit |
535+
| generic.go:21:9:21:9 | s | generic.go:21:12:21:12 | t |
536+
| generic.go:21:12:21:12 | t | generic.go:21:2:21:12 | return statement |
537+
| generic.go:24:1:24:1 | entry | generic.go:25:2:25:4 | skip |
538+
| generic.go:24:1:35:1 | function declaration | generic.go:0:0:0:0 | exit |
539+
| generic.go:24:6:24:12 | skip | generic.go:24:1:35:1 | function declaration |
540+
| generic.go:25:2:25:4 | assignment to gs1 | generic.go:26:2:26:2 | skip |
541+
| generic.go:25:2:25:4 | skip | generic.go:25:9:25:35 | struct literal |
542+
| generic.go:25:9:25:35 | struct literal | generic.go:25:32:25:34 | "x" |
543+
| generic.go:25:32:25:34 | "x" | generic.go:25:32:25:34 | init of "x" |
544+
| generic.go:25:32:25:34 | init of "x" | generic.go:25:2:25:4 | assignment to gs1 |
545+
| generic.go:26:2:26:2 | assignment to a | generic.go:27:2:27:4 | skip |
546+
| generic.go:26:2:26:2 | skip | generic.go:26:7:26:9 | gs1 |
547+
| generic.go:26:7:26:9 | gs1 | generic.go:26:7:26:18 | selection of Identity |
548+
| generic.go:26:7:26:18 | selection of Identity | generic.go:26:20:26:26 | "hello" |
549+
| generic.go:26:7:26:27 | call to Identity | generic.go:26:2:26:2 | assignment to a |
550+
| generic.go:26:7:26:27 | call to Identity | generic.go:35:1:35:1 | exit |
551+
| generic.go:26:20:26:26 | "hello" | generic.go:26:7:26:27 | call to Identity |
552+
| generic.go:27:2:27:4 | assignment to gs2 | generic.go:28:2:28:2 | skip |
553+
| generic.go:27:2:27:4 | skip | generic.go:27:9:27:48 | struct literal |
554+
| generic.go:27:9:27:48 | struct literal | generic.go:27:40:27:42 | "y" |
555+
| generic.go:27:40:27:42 | "y" | generic.go:27:40:27:42 | init of "y" |
556+
| generic.go:27:40:27:42 | init of "y" | generic.go:27:45:27:47 | "z" |
557+
| generic.go:27:45:27:47 | "z" | generic.go:27:45:27:47 | init of "z" |
558+
| generic.go:27:45:27:47 | init of "z" | generic.go:27:2:27:4 | assignment to gs2 |
559+
| generic.go:28:2:28:2 | assignment to b | generic.go:29:2:29:2 | skip |
560+
| generic.go:28:2:28:2 | skip | generic.go:28:7:28:9 | gs2 |
561+
| generic.go:28:7:28:9 | gs2 | generic.go:28:7:28:19 | selection of Identity1 |
562+
| generic.go:28:7:28:19 | selection of Identity1 | generic.go:28:21:28:21 | a |
563+
| generic.go:28:7:28:22 | call to Identity1 | generic.go:28:2:28:2 | assignment to b |
564+
| generic.go:28:7:28:22 | call to Identity1 | generic.go:35:1:35:1 | exit |
565+
| generic.go:28:21:28:21 | a | generic.go:28:7:28:22 | call to Identity1 |
566+
| generic.go:29:2:29:2 | assignment to c | generic.go:30:2:30:2 | skip |
567+
| generic.go:29:2:29:2 | skip | generic.go:29:7:29:22 | genericIdentity1 |
568+
| generic.go:29:7:29:22 | genericIdentity1 | generic.go:29:32:29:32 | b |
569+
| generic.go:29:7:29:33 | call to genericIdentity1 | generic.go:29:2:29:2 | assignment to c |
570+
| generic.go:29:7:29:33 | call to genericIdentity1 | generic.go:35:1:35:1 | exit |
571+
| generic.go:29:32:29:32 | b | generic.go:29:7:29:33 | call to genericIdentity1 |
572+
| generic.go:30:2:30:2 | assignment to d | generic.go:31:2:31:2 | skip |
573+
| generic.go:30:2:30:2 | skip | generic.go:30:7:30:22 | genericIdentity1 |
574+
| generic.go:30:7:30:22 | genericIdentity1 | generic.go:30:24:30:24 | c |
575+
| generic.go:30:7:30:25 | call to genericIdentity1 | generic.go:30:2:30:2 | assignment to d |
576+
| generic.go:30:7:30:25 | call to genericIdentity1 | generic.go:35:1:35:1 | exit |
577+
| generic.go:30:24:30:24 | c | generic.go:30:7:30:25 | call to genericIdentity1 |
578+
| generic.go:31:2:31:2 | assignment to e | generic.go:31:2:31:53 | ... := ...[1] |
579+
| generic.go:31:2:31:2 | skip | generic.go:31:5:31:5 | skip |
580+
| generic.go:31:2:31:53 | ... := ...[0] | generic.go:31:2:31:2 | assignment to e |
581+
| generic.go:31:2:31:53 | ... := ...[1] | generic.go:31:5:31:5 | assignment to f |
582+
| generic.go:31:5:31:5 | assignment to f | generic.go:32:2:32:2 | skip |
583+
| generic.go:31:5:31:5 | skip | generic.go:31:10:31:25 | genericIdentity2 |
584+
| generic.go:31:10:31:25 | genericIdentity2 | generic.go:31:43:31:43 | d |
585+
| generic.go:31:10:31:53 | call to genericIdentity2 | generic.go:31:2:31:53 | ... := ...[0] |
586+
| generic.go:31:10:31:53 | call to genericIdentity2 | generic.go:35:1:35:1 | exit |
587+
| generic.go:31:43:31:43 | d | generic.go:31:46:31:52 | "hello" |
588+
| generic.go:31:46:31:52 | "hello" | generic.go:31:10:31:53 | call to genericIdentity2 |
589+
| generic.go:32:2:32:2 | assignment to g | generic.go:32:2:32:31 | ... := ...[1] |
590+
| generic.go:32:2:32:2 | skip | generic.go:32:5:32:5 | skip |
591+
| generic.go:32:2:32:31 | ... := ...[0] | generic.go:32:2:32:2 | assignment to g |
592+
| generic.go:32:2:32:31 | ... := ...[1] | generic.go:32:5:32:5 | assignment to h |
593+
| generic.go:32:5:32:5 | assignment to h | generic.go:33:2:33:2 | skip |
594+
| generic.go:32:5:32:5 | skip | generic.go:32:10:32:25 | genericIdentity2 |
595+
| generic.go:32:10:32:25 | genericIdentity2 | generic.go:32:27:32:27 | e |
596+
| generic.go:32:10:32:31 | call to genericIdentity2 | generic.go:32:2:32:31 | ... := ...[0] |
597+
| generic.go:32:10:32:31 | call to genericIdentity2 | generic.go:35:1:35:1 | exit |
598+
| generic.go:32:27:32:27 | e | generic.go:32:30:32:30 | f |
599+
| generic.go:32:30:32:30 | f | generic.go:32:10:32:31 | call to genericIdentity2 |
600+
| generic.go:33:2:33:2 | skip | generic.go:33:6:33:6 | g |
601+
| generic.go:33:6:33:6 | g | generic.go:34:2:34:2 | skip |
602+
| generic.go:34:2:34:2 | skip | generic.go:34:6:34:6 | h |
603+
| generic.go:34:6:34:6 | h | generic.go:35:1:35:1 | exit |
499604
| hello.go:0:0:0:0 | entry | hello.go:3:1:3:12 | skip |
500605
| hello.go:3:1:3:12 | skip | hello.go:5:7:5:13 | skip |
501606
| hello.go:5:7:5:13 | assignment to message | hello.go:7:6:7:13 | skip |

ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.expected

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,111 @@
495495
| exprs.go:94:16:94:16 | (...) is false | exprs.go:94:21:94:21 | z |
496496
| exprs.go:94:16:94:16 | (...) is true | exprs.go:94:9:94:21 | ...\|\|... |
497497
| exprs.go:94:21:94:21 | z | exprs.go:94:9:94:21 | ...\|\|... |
498+
| generic.go:0:0:0:0 | entry | generic.go:3:1:5:1 | skip |
499+
| generic.go:3:1:5:1 | skip | generic.go:7:28:7:35 | skip |
500+
| generic.go:7:1:7:1 | entry | generic.go:7:7:7:7 | argument corresponding to g |
501+
| generic.go:7:1:7:55 | function declaration | generic.go:9:1:12:1 | skip |
502+
| generic.go:7:7:7:7 | argument corresponding to g | generic.go:7:7:7:7 | initialization of g |
503+
| generic.go:7:7:7:7 | initialization of g | generic.go:7:37:7:37 | argument corresponding to u |
504+
| generic.go:7:28:7:35 | skip | generic.go:7:1:7:55 | function declaration |
505+
| generic.go:7:37:7:37 | argument corresponding to u | generic.go:7:37:7:37 | initialization of u |
506+
| generic.go:7:37:7:37 | initialization of u | generic.go:7:53:7:53 | u |
507+
| generic.go:7:46:7:53 | return statement | generic.go:7:55:7:55 | exit |
508+
| generic.go:7:53:7:53 | u | generic.go:7:46:7:53 | return statement |
509+
| generic.go:9:1:12:1 | skip | generic.go:14:31:14:39 | skip |
510+
| generic.go:14:1:14:1 | entry | generic.go:14:7:14:7 | argument corresponding to g |
511+
| generic.go:14:1:14:59 | function declaration | generic.go:16:6:16:21 | skip |
512+
| generic.go:14:7:14:7 | argument corresponding to g | generic.go:14:7:14:7 | initialization of g |
513+
| generic.go:14:7:14:7 | initialization of g | generic.go:14:41:14:41 | argument corresponding to u |
514+
| generic.go:14:31:14:39 | skip | generic.go:14:1:14:59 | function declaration |
515+
| generic.go:14:41:14:41 | argument corresponding to u | generic.go:14:41:14:41 | initialization of u |
516+
| generic.go:14:41:14:41 | initialization of u | generic.go:14:57:14:57 | u |
517+
| generic.go:14:50:14:57 | return statement | generic.go:14:59:14:59 | exit |
518+
| generic.go:14:57:14:57 | u | generic.go:14:50:14:57 | return statement |
519+
| generic.go:16:1:16:1 | entry | generic.go:16:30:16:30 | argument corresponding to t |
520+
| generic.go:16:1:18:1 | function declaration | generic.go:20:6:20:21 | skip |
521+
| generic.go:16:6:16:21 | skip | generic.go:16:1:18:1 | function declaration |
522+
| generic.go:16:30:16:30 | argument corresponding to t | generic.go:16:30:16:30 | initialization of t |
523+
| generic.go:16:30:16:30 | initialization of t | generic.go:17:9:17:9 | t |
524+
| generic.go:17:2:17:9 | return statement | generic.go:18:1:18:1 | exit |
525+
| generic.go:17:9:17:9 | t | generic.go:17:2:17:9 | return statement |
526+
| generic.go:20:1:20:1 | entry | generic.go:20:33:20:33 | argument corresponding to s |
527+
| generic.go:20:1:22:1 | function declaration | generic.go:24:6:24:12 | skip |
528+
| generic.go:20:6:20:21 | skip | generic.go:20:1:22:1 | function declaration |
529+
| generic.go:20:33:20:33 | argument corresponding to s | generic.go:20:33:20:33 | initialization of s |
530+
| generic.go:20:33:20:33 | initialization of s | generic.go:20:38:20:38 | argument corresponding to t |
531+
| generic.go:20:38:20:38 | argument corresponding to t | generic.go:20:38:20:38 | initialization of t |
532+
| generic.go:20:38:20:38 | initialization of t | generic.go:21:9:21:9 | s |
533+
| generic.go:21:2:21:12 | return statement | generic.go:22:1:22:1 | exit |
534+
| generic.go:21:9:21:9 | s | generic.go:21:12:21:12 | t |
535+
| generic.go:21:12:21:12 | t | generic.go:21:2:21:12 | return statement |
536+
| generic.go:24:1:24:1 | entry | generic.go:25:2:25:4 | skip |
537+
| generic.go:24:1:35:1 | function declaration | generic.go:0:0:0:0 | exit |
538+
| generic.go:24:6:24:12 | skip | generic.go:24:1:35:1 | function declaration |
539+
| generic.go:25:2:25:4 | assignment to gs1 | generic.go:26:2:26:2 | skip |
540+
| generic.go:25:2:25:4 | skip | generic.go:25:9:25:35 | struct literal |
541+
| generic.go:25:9:25:35 | struct literal | generic.go:25:32:25:34 | "x" |
542+
| generic.go:25:32:25:34 | "x" | generic.go:25:32:25:34 | init of "x" |
543+
| generic.go:25:32:25:34 | init of "x" | generic.go:25:2:25:4 | assignment to gs1 |
544+
| generic.go:26:2:26:2 | assignment to a | generic.go:27:2:27:4 | skip |
545+
| generic.go:26:2:26:2 | skip | generic.go:26:7:26:9 | gs1 |
546+
| generic.go:26:7:26:9 | gs1 | generic.go:26:7:26:18 | selection of Identity |
547+
| generic.go:26:7:26:18 | selection of Identity | generic.go:26:20:26:26 | "hello" |
548+
| generic.go:26:7:26:27 | call to Identity | generic.go:26:2:26:2 | assignment to a |
549+
| generic.go:26:7:26:27 | call to Identity | generic.go:35:1:35:1 | exit |
550+
| generic.go:26:20:26:26 | "hello" | generic.go:26:7:26:27 | call to Identity |
551+
| generic.go:27:2:27:4 | assignment to gs2 | generic.go:28:2:28:2 | skip |
552+
| generic.go:27:2:27:4 | skip | generic.go:27:9:27:48 | struct literal |
553+
| generic.go:27:9:27:48 | struct literal | generic.go:27:40:27:42 | "y" |
554+
| generic.go:27:40:27:42 | "y" | generic.go:27:40:27:42 | init of "y" |
555+
| generic.go:27:40:27:42 | init of "y" | generic.go:27:45:27:47 | "z" |
556+
| generic.go:27:45:27:47 | "z" | generic.go:27:45:27:47 | init of "z" |
557+
| generic.go:27:45:27:47 | init of "z" | generic.go:27:2:27:4 | assignment to gs2 |
558+
| generic.go:28:2:28:2 | assignment to b | generic.go:29:2:29:2 | skip |
559+
| generic.go:28:2:28:2 | skip | generic.go:28:7:28:9 | gs2 |
560+
| generic.go:28:7:28:9 | gs2 | generic.go:28:7:28:19 | selection of Identity1 |
561+
| generic.go:28:7:28:19 | selection of Identity1 | generic.go:28:21:28:21 | a |
562+
| generic.go:28:7:28:22 | call to Identity1 | generic.go:28:2:28:2 | assignment to b |
563+
| generic.go:28:7:28:22 | call to Identity1 | generic.go:35:1:35:1 | exit |
564+
| generic.go:28:21:28:21 | a | generic.go:28:7:28:22 | call to Identity1 |
565+
| generic.go:29:2:29:2 | assignment to c | generic.go:30:2:30:2 | skip |
566+
| generic.go:29:2:29:2 | skip | generic.go:29:7:29:22 | genericIdentity1 |
567+
| generic.go:29:7:29:22 | genericIdentity1 | generic.go:29:32:29:32 | b |
568+
| generic.go:29:7:29:33 | call to genericIdentity1 | generic.go:29:2:29:2 | assignment to c |
569+
| generic.go:29:7:29:33 | call to genericIdentity1 | generic.go:35:1:35:1 | exit |
570+
| generic.go:29:32:29:32 | b | generic.go:29:7:29:33 | call to genericIdentity1 |
571+
| generic.go:30:2:30:2 | assignment to d | generic.go:31:2:31:2 | skip |
572+
| generic.go:30:2:30:2 | skip | generic.go:30:7:30:22 | genericIdentity1 |
573+
| generic.go:30:7:30:22 | genericIdentity1 | generic.go:30:24:30:24 | c |
574+
| generic.go:30:7:30:25 | call to genericIdentity1 | generic.go:30:2:30:2 | assignment to d |
575+
| generic.go:30:7:30:25 | call to genericIdentity1 | generic.go:35:1:35:1 | exit |
576+
| generic.go:30:24:30:24 | c | generic.go:30:7:30:25 | call to genericIdentity1 |
577+
| generic.go:31:2:31:2 | assignment to e | generic.go:31:2:31:53 | ... := ...[1] |
578+
| generic.go:31:2:31:2 | skip | generic.go:31:5:31:5 | skip |
579+
| generic.go:31:2:31:53 | ... := ...[0] | generic.go:31:2:31:2 | assignment to e |
580+
| generic.go:31:2:31:53 | ... := ...[1] | generic.go:31:5:31:5 | assignment to f |
581+
| generic.go:31:5:31:5 | assignment to f | generic.go:32:2:32:2 | skip |
582+
| generic.go:31:5:31:5 | skip | generic.go:31:10:31:25 | genericIdentity2 |
583+
| generic.go:31:10:31:25 | genericIdentity2 | generic.go:31:43:31:43 | d |
584+
| generic.go:31:10:31:53 | call to genericIdentity2 | generic.go:31:2:31:53 | ... := ...[0] |
585+
| generic.go:31:10:31:53 | call to genericIdentity2 | generic.go:35:1:35:1 | exit |
586+
| generic.go:31:43:31:43 | d | generic.go:31:46:31:52 | "hello" |
587+
| generic.go:31:46:31:52 | "hello" | generic.go:31:10:31:53 | call to genericIdentity2 |
588+
| generic.go:32:2:32:2 | assignment to g | generic.go:32:2:32:31 | ... := ...[1] |
589+
| generic.go:32:2:32:2 | skip | generic.go:32:5:32:5 | skip |
590+
| generic.go:32:2:32:31 | ... := ...[0] | generic.go:32:2:32:2 | assignment to g |
591+
| generic.go:32:2:32:31 | ... := ...[1] | generic.go:32:5:32:5 | assignment to h |
592+
| generic.go:32:5:32:5 | assignment to h | generic.go:33:2:33:2 | skip |
593+
| generic.go:32:5:32:5 | skip | generic.go:32:10:32:25 | genericIdentity2 |
594+
| generic.go:32:10:32:25 | genericIdentity2 | generic.go:32:27:32:27 | e |
595+
| generic.go:32:10:32:31 | call to genericIdentity2 | generic.go:32:2:32:31 | ... := ...[0] |
596+
| generic.go:32:10:32:31 | call to genericIdentity2 | generic.go:35:1:35:1 | exit |
597+
| generic.go:32:27:32:27 | e | generic.go:32:30:32:30 | f |
598+
| generic.go:32:30:32:30 | f | generic.go:32:10:32:31 | call to genericIdentity2 |
599+
| generic.go:33:2:33:2 | skip | generic.go:33:6:33:6 | g |
600+
| generic.go:33:6:33:6 | g | generic.go:34:2:34:2 | skip |
601+
| generic.go:34:2:34:2 | skip | generic.go:34:6:34:6 | h |
602+
| generic.go:34:6:34:6 | h | generic.go:35:1:35:1 | exit |
498603
| hello.go:0:0:0:0 | entry | hello.go:3:1:3:12 | skip |
499604
| hello.go:3:1:3:12 | skip | hello.go:5:7:5:13 | skip |
500605
| hello.go:5:7:5:13 | assignment to message | hello.go:7:6:7:13 | skip |
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
type GenericStruct1[T any] struct {
4+
Field T
5+
}
6+
7+
func (g GenericStruct1[U]) Identity(u U) U { return u }
8+
9+
type GenericStruct2[S, T any] struct {
10+
Field1 S
11+
Field2 T
12+
}
13+
14+
func (g GenericStruct2[U, _]) Identity1(u U) U { return u }
15+
16+
func genericIdentity1[T any](t T) T {
17+
return t
18+
}
19+
20+
func genericIdentity2[S, T any](s S, t T) (S, T) {
21+
return s, t
22+
}
23+
24+
func generic() {
25+
gs1 := GenericStruct1[string]{"x"}
26+
a := gs1.Identity("hello")
27+
gs2 := GenericStruct2[string, string]{"y", "z"}
28+
b := gs2.Identity1(a)
29+
c := genericIdentity1[string](b)
30+
d := genericIdentity1(c)
31+
e, f := genericIdentity2[string, string](d, "hello")
32+
g, h := genericIdentity2(e, f)
33+
_ = g
34+
_ = h
35+
}

0 commit comments

Comments
 (0)