Skip to content

Commit b8bfcf3

Browse files
committed
Add code to writeup of examples
1 parent b78a976 commit b8bfcf3

File tree

3 files changed

+47
-19
lines changed

3 files changed

+47
-19
lines changed
Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,5 @@
11
package main
22

3-
import "fmt"
4-
5-
// Let's remember Bar in the type parameter constraint is syntactic sugar for
6-
// an anonymous type set interface: interface { Bar }. The only type
7-
// this constraint can be instantiated with is Bar (struct type).
8-
//
9-
// This code compiles in this declaration order, but fails to compile if
10-
// we reverse the order of struct declarations.
11-
//
12-
// The code also (rightfully so) fails to compile if we add a field of type b,
13-
// as this would violate the notContains constraint. However e.g. a field of type
14-
// pointer to b is fine.
15-
//
16-
// I.e. by introducing type set interfaces, we need to extend notContains
17-
// checks to type parameters in generic types.
183
type Foo[T any] struct {
194
x T
205
}
@@ -24,8 +9,4 @@ type Bar struct {
249
}
2510

2611
func main() {
27-
x := Foo[Bar]{}
28-
y := Bar{x: x}
29-
fmt.Println(x)
30-
fmt.Println(y)
3112
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package main
2+
3+
import "fmt"
4+
5+
type Foo[T Bar] struct {
6+
x *T
7+
}
8+
9+
type Bar struct {
10+
x Foo[Bar]
11+
}
12+
13+
func main() {
14+
x := Foo[Bar]{}
15+
y := Bar{x: x}
16+
fmt.Println(x)
17+
fmt.Println(y)
18+
}

deliverables/4-cycle-detection-summary/summary.tex

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
\usepackage{stmaryrd}
88
\usepackage{xcolor}
99
\usepackage{hyperref}
10+
\usepackage{listings}
1011

1112
\input{../../projects/go-generic-array-sizes/theory/macros}
1213

@@ -191,6 +192,34 @@ \subsection{Lifting type parameter reference rules}
191192
\end{itemize}
192193

193194
\section{Examples}
195+
\noindent\begin{minipage}[t]{.45\linewidth}
196+
\lstinputlisting[language=Go, tabsize=4, firstline=3]
197+
{./examples/generic-containment-any.go}
198+
199+
The definition of \texttt{Bar} should be rejected, since it creates a type
200+
containment cycle via \texttt{Foo}. The compiler correctly reports \texttt{Bar}
201+
as an invalid recursive type.
202+
\end{minipage}
203+
\hfill
204+
\noindent\begin{minipage}[t]{.45\linewidth}
205+
\lstinputlisting[language=Go, tabsize=4, firstline=3, lastline=35]
206+
{./examples/generic-containment-clean.go}
207+
208+
Using e.g. a pointer to \texttt{T} in the
209+
definition of \texttt{Foo} would make the program valid. We can even
210+
change the type constraint of \texttt{T} from \texttt{any} to \texttt{Bar}, and
211+
the type checker should behave the same. However, as of Go 1.23, such a program
212+
is either rejected or accepted by the type checker depending on the order of the
213+
struct declarations (similar to \href{https://github.com/golang/go/issues/65714}{Issue
214+
\#65714}).
215+
216+
\end{minipage}
217+
218+
\subsection{Type checking derivation with contradiction}
219+
220+
Below, we derive a contradiction while type checking the above program on the
221+
left, showing that the $\notcont$ rule is sufficient for detecting structural
222+
cycles in generic types.
194223

195224
\input{generic-containment-any}
196225

0 commit comments

Comments
 (0)