46.15828pt\vbox{\hbox{\hskip-46.15826pt\hbox{\hbox{$\displaystyle\displaystyle\&{\omega}\,{p}\,\mathop{{\small\boldsymbol{\mathsf{live\,at}}}}\,I$}\hskip
20.00003pt\hbox{\hbox{$\displaystyle\displaystyle
p\mathop{\\#}p^{\prime}$}}}}\vbox{}}}\over\hbox{\hskip
32.89809pt\vbox{\vbox{}\hbox{\hskip-32.89807pt\hbox{\hbox{$\displaystyle\displaystyle{p^{\prime}}\,\mathop{{\small\boldsymbol{\mathsf{missing}}}}\,{{\color[rgb]{0.21875,0.4765625,0.83984375}\boldsymbol{\mathsf{W}}}}\,\mathop{{\small\boldsymbol{\mathsf{at}}}}\,{I}$}}}}}}$}}\hbox{\hbox{}\hbox{$\displaystyle\;\hbox{\small\small{(\lx@cref{creftype~refnum}{tr:p-missing-
write-own})}}$}}$ }$}}}\vbox{}}}}\over\hbox{\hskip
37.57127pt\vbox{\vbox{}\hbox{\hskip-37.57127pt\hbox{\hbox{$\displaystyle\displaystyle{\small\boldsymbol{\mathsf{permission\text{-}error}}}~{}{G}$}}}}}}$
(6)

Sub-case: 5::

Let $p^{\prime}$ such that
$p^{\prime}\,\mathop{{\small\boldsymbol{\mathsf{moved\,at}}}}\,I$ and
$p\mathop{\\#}p^{\prime}$. Then we can derive
${\small\boldsymbol{\mathsf{permission\text{-}error}}}~{}{G}$:

$\displaystyle\displaystyle{\hbox{\hskip
128.56393pt\vbox{\hbox{\hskip-94.99121pt\hbox{\hbox{$\displaystyle\displaystyle\raise
10.38887pt\hbox{$\displaystyle{\hbox{$\displaystyle\displaystyle{\hbox{\hskip
25.00087pt\vbox{\hbox{\hskip-25.00085pt\hbox{\hbox{$\displaystyle\displaystyle
p^{\prime}\,\mathop{{\small\boldsymbol{\mathsf{moved\,at}}}}\,I$}}}\vbox{}}}\over\hbox{\hskip
27.87308pt\vbox{\vbox{}\hbox{\hskip-27.87306pt\hbox{\hbox{$\displaystyle\displaystyle{p^{\prime}}\,\mathop{{\small\boldsymbol{\mathsf{needs}}}}\,{{\color[rgb]{0.79296875,0.1640625,0.34375}\boldsymbol{\mathsf{O}}}}\,\mathop{{\small\boldsymbol{\mathsf{at}}}}\,{I}$}}}}}}$}}\hbox{\hbox{}\hbox{$\displaystyle\;\hbox{\small\small{(\lx@cref{creftype~refnum}{tr:p-needs-
own})}}$}}$
}$}}}\vbox{\hbox{\hskip-128.56393pt\hbox{\hbox{$\displaystyle\displaystyle\raise
10.38887pt\hbox{$\displaystyle{\hbox{$\displaystyle\displaystyle{\hbox{\hskip
46.15828pt\vbox{\hbox{\hskip-46.15826pt\hbox{\hbox{$\displaystyle\displaystyle\&{\omega}\,{p}\,\mathop{{\small\boldsymbol{\mathsf{live\,at}}}}\,I$}\hskip
20.00003pt\hbox{\hbox{$\displaystyle\displaystyle
p\mathop{\\#}p^{\prime}$}}}}\vbox{}}}\over\hbox{\hskip
31.64809pt\vbox{\vbox{}\hbox{\hskip-31.64807pt\hbox{\hbox{$\displaystyle\displaystyle{p^{\prime}}\,\mathop{{\small\boldsymbol{\mathsf{missing}}}}\,{{\color[rgb]{0.79296875,0.1640625,0.34375}\boldsymbol{\mathsf{O}}}}\,\mathop{{\small\boldsymbol{\mathsf{at}}}}\,{I}$}}}}}}$}}\hbox{\hbox{}\hbox{$\displaystyle\;\hbox{\small\small{(\lx@cref{creftype~refnum}{tr:p-missing-
write-own})}}$}}$ }$}}}\vbox{}}}}\over\hbox{\hskip
37.57127pt\vbox{\vbox{}\hbox{\hskip-37.57127pt\hbox{\hbox{$\displaystyle\displaystyle{\small\boldsymbol{\mathsf{permission\text{-}error}}}~{}{G}$}}}}}}$
(6)

Case: 5::

Let $p,I$ such that
$p\,\mathop{{\small\boldsymbol{\mathsf{moved\,before}}}}\,I$ and
${p}\,\mathop{{\small\boldsymbol{\mathsf{read\,at}}}}\,{I}$. Then we can
derive ${\small\boldsymbol{\mathsf{permission\text{-}error}}}~{}{G}$:

$\displaystyle\displaystyle{\hbox{\hskip
122.29907pt\vbox{\hbox{\hskip-94.65036pt\hbox{\hbox{$\displaystyle\displaystyle\raise
10.38887pt\hbox{$\displaystyle{\hbox{$\displaystyle\displaystyle{\hbox{\hskip
20.11836pt\vbox{\hbox{\hskip-20.11836pt\hbox{\hbox{$\displaystyle\displaystyle{p}\,\mathop{{\small\boldsymbol{\mathsf{read\,at}}}}\,{I}$}}}\vbox{}}}\over\hbox{\hskip
26.89473pt\vbox{\vbox{}\hbox{\hskip-26.89473pt\hbox{\hbox{$\displaystyle\displaystyle{p}\,\mathop{{\small\boldsymbol{\mathsf{needs}}}}\,{{\color[rgb]{0.9453125,0.60546875,0.21875}\boldsymbol{\mathsf{R}}}}\,\mathop{{\small\boldsymbol{\mathsf{at}}}}\,{I}$}}}}}}$}}\hbox{\hbox{}\hbox{$\displaystyle\;\hbox{\small\small{(\lx@cref{creftype~refnum}{tr:p-needs-
read})}}$}}$
}$}}}\vbox{\hbox{\hskip-122.29907pt\hbox{\hbox{$\displaystyle\displaystyle\raise
10.38887pt\hbox{$\displaystyle{\hbox{$\displaystyle\displaystyle{\hbox{\hskip
32.2434pt\vbox{\hbox{\hskip-32.2434pt\hbox{\hbox{$\displaystyle\displaystyle
p\,\mathop{{\small\boldsymbol{\mathsf{moved\,before}}}}\,I$}}}\vbox{}}}\over\hbox{\hskip
30.66974pt\vbox{\vbox{}\hbox{\hskip-30.66974pt\hbox{\hbox{$\displaystyle\displaystyle{p}\,\mathop{{\small\boldsymbol{\mathsf{missing}}}}\,{{\color[rgb]{0.9453125,0.60546875,0.21875}\boldsymbol{\mathsf{R}}}}\,\mathop{{\small\boldsymbol{\mathsf{at}}}}\,{I}$}}}}}}$}}\hbox{\hbox{}\hbox{$\displaystyle\;\hbox{\small\small{(\lx@cref{creftype~refnum}{tr:p-moved-
no-permissions})}}$}}$ }$}}}\vbox{}}}}\over\hbox{\hskip
37.57127pt\vbox{\vbox{}\hbox{\hskip-37.57127pt\hbox{\hbox{$\displaystyle\displaystyle{\small\boldsymbol{\mathsf{permission\text{-}error}}}~{}{G}$}}}}}}$
(6)

∎

###  A.3. Comprehension Questions

Difference of stack and heap:

tcbcolupperWhich of the following best describes the difference between the
stack and the heap?  tcbcolupperThe stack holds data associated with a
specific function, while the heap holds data that can outlive a function.
tcbcolupperThe stack can hold pointers to data stored on the heap, while the
heap only holds data without pointers. tcbcolupperThe stack holds immutable
data, while the heap holds mutable data. tcbcolupperThe stack holds copyable
data, while the heap holds uncopyable data.

Aliasing in runtime diagram:

tcbcolupperConsider the execution of the following snippet, with the final
state shown:  In the final state, how many copies of the number tcbcolupper15
live anywhere in memory? Write your answer as a digit, such as 0 or 1.
tcbcolupper2

Moves in runtime diagram:

tcbcolupperConsider the execution of the following snippet, with an
intermediate state shown:  In the final state of the snippet, what is the
value of tcbcoluppera[0]? Write your answer as a digit, e.g. 0 or 1.
tcbcolupper6

Defined vs. undefined behavior:

tcbcolupperWhich of the following is NOT a kind of undefined behavior?
tcbcolupperHaving a pointer to freed memory in a stack frame tcbcolupperUsing
a pointer that points to freed memory tcbcolupperFreeing the same memory a
second time tcbcolupperUsing a non-boolean value as an ‘if‘ condition

Compiler error due to move:

tcbcolupperDetermine whether the program will pass the compiler. If it passes,
write the expected output of the program if it were executed. ⬇ 1fn
add_suffix(mut s: String) -> String { 2 s.push_str(" world"); 3 s 4} 5 6fn
main() { 7 let s = String::from("hello"); 8 let s2 = add_suffix(s); 9
println!("{}", s2); 10} tcbcolupperIt does compile, with output “hello world”
tcbcolupperIt does not compile

Dereferencing multiple layers of indirection:

tcbcolupperConsider the following program, showing the state of memory after
the last line:  If you wanted to copy out the number tcbcolupper0 through
tcbcoluppery, how many dereferences would you need to use? Write your answer
as a digit. For example, if the correct expression is tcbcolupper*y, then the
answer is 1.  tcbcolupper3

How moves affect deallocation:

tcbcolupperConsider the following program, showing the state of memory after
the last line:  Which of the following best explains why tcbcolupperv is not
deallocated after calling tcbcolupperget_first?  tcbcolupper tcbcoluppervr is
a reference which does not own the vector it points to tcbcolupper
tcbcoluppervr is not mutated within tcbcolupperget_first tcbcolupper
tcbcolupperget_first returns a value of type tcbcolupperi32, not the vector
itself tcbcolupper tcbcolupperv is used after calling tcbcolupperget_first in
the tcbcolupperprintln

Analysis state in permissions diagram:

tcbcolupperConsider the permissions in the following program:  At the point
marked tcbcolupper/* here */, what are the permissions on the path
tcbcoluppers? Select each permission below, or select “no permissions” if the
path has no permissions.
tcbcolupper${\color[rgb]{0.9453125,0.60546875,0.21875}\boldsymbol{\mathsf{R}}}$
tcbcolupper${\color[rgb]{0.79296875,0.1640625,0.34375}\boldsymbol{\mathsf{O}}}$
tcbcolupper${\color[rgb]{0.21875,0.4765625,0.83984375}\boldsymbol{\mathsf{W}}}$
tcbcolupperNo permissions

Why borrows change permissions:

tcbcolupperConsider the permissions in the following program:  Which of the
following best explains why tcbcolupperstrs loses and regains write
permissions?  tcbcolupper tcbcolupperget_first returns an immutable reference
to data within tcbcolupperstrs, so tcbcolupperstrs is not writable while
tcbcolupperfirst is live tcbcolupper tcbcolupperstrs is not writable while the
immutable reference tcbcolupper&strs passed to tcbcolupperget_first is live
tcbcolupper tcbcolupperstrs does not need write permissions until the
tcbcolupperstrs.push(..) operation, so it only regains write permissions at
that statement tcbcolupperBecause tcbcolupperfirst refers to tcbcolupperstrs,
then tcbcolupperstrs can only be mutated within a nested scope like the if-
statement

How references can cause undefined behavior:

tcbcolupperConsider this unsafe program:  Which of the following best
describes how undefined behavior occurs in this program?  tcbcolupper
tcbcolupperv1[0] reads tcbcolupperv1, which points to deallocated memory
tcbcolupper tcbcolupperv2 owns the vector data on the heap, while
tcbcolupperv1 does not tcbcolupper tcbcolupperv1 has been moved into
tcbcolupperv2 on line 2 tcbcolupper tcbcolupperv1 has its pointer invalidated
by the tcbcolupperpush on line 3

Compiler error due to overlapping borrows:

tcbcolupperDetermine whether the program will pass the compiler. If it passes,
write the expected output of the program if it were executed. ⬇ 1fn main() { 2
let mut s = String::from("hello"); 3 let s2 = &s; 4 let s3 = &mut s; 5
s3.push_str(" world"); 6 println!("{s2}"); 7} tcbcolupperIt does compile, with
output ____ tcbcolupperIt does not compile