►
From YouTube: RustConf 2022 - WHAT IF WE PRETENDED UNSAFE CODE WAS NICE, AND THEN IT WAS? by Aria Beingessner
Description
Rust is often praised for its great docs, libs, and tools. Well, Safe Rust is. Unsafe Rust is a mess. How can you expect more than "it's complicated" when you ask questions about The Thing For Complex Problems? looks around nervously Don't tell anyone but... Unsafe Rust Can Be Good Too, If You Believe. Things that "surely work, don't ask me how" ruin the fun for everyone. So pretend they don't work, and we can make tools which obviously work! Better Docs, Libs, and Tools, just for playing pretend! Learn about the new Strict Provenance APIs and how they help you have Nice Things!
A
Hi
there
I'm
arya
byngesner,
you
might
better
know
me
as
gankra
from
my
time,
working
on
rust
back
in
like
2015
when
I
was
on
the
libs
team,
and
I
did
things
like
the
rest
of
now
icon
and
learn
to
rest
with
entirely
too
many
linked
lists.
A
But
these
days
I
don't
really
do
much
contribution
to
rest
itself.
I
mostly
work
on
firefox
and
particularly
the
dev
tooling,
like
a
crash
reporter
or
our
build
systems,
but
a
few
months
ago
I
got
really
frustrated
about
an
old
thing
that
bothered
me
back
when
I
was
working
on
the
rest
of
my
con
and
what
came
out
of
that
was
something
called
strict
provenance.
A
And
the
core
idea
behind
strict
providence
is
just
what:
if
we
pretended
unsafe
code
was
nice
and
then
it
was
because
we
pretended
it's
a
very
strange
idea.
But
and
it's
weird
because
the
idea
is
very
strange,
but
the
apis
are
very
simple:
they're,
like
a
few
lines
of
code,
you
can
write
them
on
stable
rest.
They
really
don't
do
anything
terribly
special,
but
it's
the
ideas
behind
them
and
for
that
you're
gonna
need
some
background
and
well,
I'm
afraid
to
tell
you.
A
I've
lied
to
you
and
I've
locked
the
doors,
there's
no
escaping
I'm
going
to
try
to
explain
memory
models
and
you're
going
to
have
to
sit
through
it.
So
why
do
we
have
this
thing?
Called
memory
called
a
memory
model
and
fundamentally
it's
about
the
fact
that
programs
need
memory
to
represent
their
state,
but
that
using
memory
is
in
some
sense,
bad.
A
We
don't
want
to
be
accessing
memory
because
it's
slow
and
if
we
use
too
much
memory
our
program
will
crash
because
it's
finite
so
but
at
the
same
time
we
also
don't
want
to
write
super
ridiculously
low
level
and
platform.
Specific
programs
that
say
explicitly
refer
to
the
registers
on
arm
or
the
registers
on
x86.
A
So
we
want
to
get.
We
want
to
write
comp
programs
in
a
kind
of
high-level
way
that
uses
memory
and
then
give
the
compiler
the
latitude
to
reason
about
that
memory,
more
abstractly
and
in
a
first-class
way,
and
so
something
like
a
local
variable
or
a
global
variable
or
a
called.
The
malloc
is
an
abstract
allocation
that
the
compiler
can
optimize
around
and
can
remove
accesses
to
or
even
remove
the
allocation
altogether.
A
A
If
that
was
the
whole
story,
then
everything
would
be
great
right,
but
the
problem
is
programmers,
love
to
do
cute
memory,
tricks
and
then
compilers
make
the
programmers
go
away
because
they
did
something
the
compiler
didn't
think
could
happen
and
it
miscompiled
or
mis-optimized
their
code,
at
least
as
far
as
the
program
is
concerned,
the
compiler
might
disagree.
Compiler
thinks
it's
perfect.
Compilers
do
have
bugs,
though
pro
tip
it
happens.
A
It's
pro
you're
probably
not
running
into
a
compiler
bug,
but
they
happen
more
than
I'd
like
so
to
explain
that
to
explain
memory
models
to
you,
we're
going
to
look
at
puzzle
club
now
you
love
puzzles
who
doesn't
love,
puzzles
and
so
you're
going
to
make
a
puzzle
solving
club
because
that's
the
best
way
to
solve
puzzles.
But
of
course
everyone
knows,
a
club
needs
a
tree
house.
A
So
we're
going
to
create
an
allocation
to
contain
our
state
and
allocations
need
memories.
Our
treehouse
is
memory
and
our
club
is
an
allocation,
and
this
normally
we
would
say.
Oh
the
club
is
the
tree
house,
but
by
separating
these
notions
it
lets
us
eliminate
the
tree
house
or
not
access
the
tree
house.
If
we
don't
really
need
to
the
club,
the
club
was
inside
us
all
along.
A
A
A
But
no,
it
could
still
be
worse.
It's
also
on
terrible,
cliff
art
fire
and
what
that
means
is
we
can't
really
be
in
this
treehouse
for
long
we
can
climb
up
it.
We
can
grab
some
stuff
in
it.
We
can
put
some
stuff
in
it,
but
we
need
to
get
it
out
of
there
fast
and
what
I'm
really
saying
here
is
most
things
can't
be
done
in
memory.
A
We
need
to
take
our
memory
and
load
it
up
into
registers,
like
the
the
really
low
level
state
of
a
cpu
and
manipulate
it
there,
and
I'm
going
to
be
summarizing
that
concept
as
just
calling
it
caching
there
can
be
caching
various
forms,
and
generally
we
want
to
be
caching
things,
and
but
it
is
worth
noting
that
this
caching
is
inside
is
in
a
lot
of
cases
like
a
matter
of
correctness
like
there
are
certain
operations,
you
simply
cannot
do
in
memory.
A
A
Okay,
so
now,
let's
look
at
pinheads,
really
naive
source
code
for
solving
puzzles,
they're
gonna,
climb
up
they're
gonna
grab
two
pieces
climb
back
down
check
if
they
match
and
then
climb
right
back
up
put
those
two
bases
back
grab
another
two
pieces
and
do
that
over
and
over
and
over
and
over,
hopefully,
you
can
see
this
is
miserable
and
bad
and
pinhead's
going
to
catch
on
fire.
Eventually,
this
is
going
to
take
forever
and
we
don't
want
this
program.
We
want
the
compiler
to
clean
this
up.
A
A
Let's
just
go
home
and
like
go
to
bed
like
work
on
it
in
our
bed
and
at
our
own
leisure,
at
our
own
comfort,
as
fast
as
we
can,
and
then
I
guess,
if
we
still
care
about
the
tree
house,
we
could
put
it
back
at
the
end,
but
actually
just
screw
the
tree
house.
Let's
just
not
even
build
the
trios.
Let's
skip
this
allocation
altogether.
A
Why
why?
Why
did
we
say
clubs
need
tree
houses?
I
don't
know
that's
what
I
was
told
okay,
but
this
works
fine
for
simple
small
puzzles
that
are
easy
to
solve.
A
Let's
look
at
some
harder
puzzles
now.
We're
gonna
need
a
friend
to
help
us
with
the
puzzle,
so
we're
gonna
really
need
to
use
the
club,
but
they
are
our
friend
in
fact
they're
our
best
friend.
They
live
in
the
same
house
as
us,
which
is
to
say
they're
in
the
same
function
and
as
it
turns
out,
this
really
isn't
a
problem.
You
two
are
so
in
sync:
you
see
exactly
what
you're
doing,
there's
still
no
problems.
A
While
we're
going
back
and
forth-
and
I
might
say
some
words
that
sound
like
I'm
talking
about
atomics,
but
I
everything
we're
talking
about
is
single
thread.
Don't
worry
about
atomics,
I
even
in
single
threaded
code.
You
do
need
to
synchronize
state
when
you
have
caching,
because
two
different
parts
of
your
program
might
not
know
about
each
other
and
need
to
agree
on
the
state.
A
A
At
that
point,
we
can
do
some
caching,
we
we
can
work
on
it
in
the
grass
at
the
bottom
of
the
tree
and
then
when
we
see
the
other
person
walking
up
to
the
tree,
when
we
see
the
other
pointer
going
to
access
that
memory,
we
have
to
write
back
all
of
our
state
so
that
when
that
pointer,
climbs
up
and
reads
it,
they
don't
see
that
like
half
the
puzzle
is
missing
and
freak
out
and
do
something
terrible
because
you
know
god
forbid.
You
work
on
a
puzzle
and
there's
a
missing
piece.
A
You
you
might
as
well
burn
down
you're
already
burning
down
treehouse,
okay.
So
now
that
we've
looked
at
some
of
the
simple
cases
and
how
the
more
local
and
precise
information
we
have
about
something,
the
more
we
can
eliminate
uses
of
memory.
I'm
sure
you're
wondering
about
the
thing
that
immediately
jumps
to
mind
when
you
think
about
memory
models
and
that's
wandering
plumbers.
A
Classic
computer
science
problem
there's
this
wandering
plumber,
who
thinks
there's
a
bathroom
around
here,
sees
your
tree
house
climbs
up
it
and,
like
I
don't
know,
sees
your
puzzle
pieces
and
like
caulks
them
to
the
floor,
because
it
thinks
they're
bathroom
tiles,
that
sucks
what
oh
it's
memory:
corruption,
we're
talking
about
memory
correction
here,
if
there's
some
other
unrelated
pointers
that
think
your
memory
is
something
else
they're
going
to
make
a
mess
of
it.
A
A
Well
we're
going
to
get
a
guard
for
our
club
and
we're
going
to
say
this
guard
will
only
let
members
in,
but
this
is
still
kind
of
kicking
the
can
down
the
road
because
well
who's
a
member
and
kind
of
circularly
members.
Whoever
we
invite
just
a
member
is
anyone
another
member
has
invited.
So
when
the
club
is
founded,
there's
a
single
founding
member
who
built
the
tree
house
and
they
invite
other
people
who
are
then
allowed
in,
but
okay,
I've
been
lying
to
you
a
bit
here.
A
A
A
A
What
you
do
in
a
program
is
you
copy
pointers
or
you
offset
pointers
and
all
those
copies
and
offsets
those
are
basically
clones
of
the
one
true
original
pointer
that
founded
the
allocation,
like
the
return
value
of
malloc
or
the
variable
name
of
a
local
variable
and
all
of
those
are
implicitly
members
of
the
club
and
actually
in
the
reverse,
they're.
Only
members
of
that
club
they're
not
allowed
to
join
any
other
club
because
they're
your
clones
they're
here
to
solve,
puzzles
for
you.
They
don't
get
to
go
to
hairdressing
club.
A
A
And
everyone
assumes
everyone
else
sets
up
a
guard
dog
to
protect
their
clubhouses.
Well,
you're
not
going
to
go
wandering
up
into
random
clubhouses
anymore.
Are
you
just
going
to
assume
there's
a
guard
dog
and
stay
away,
you're
only
going
to
stick
to
your
your
clubhouse,
and
so,
if
everyone's
already,
acting
as
if
there
is
a
guard
dog
does
do
we
need
a
guard
dog?
A
So
on
the
side
of
definitely
we
need
guard
dogs.
Well,
crimes
are
real.
We
want
to
catch
bugs
and
we
want
to
secure
our
system.
We
have
our
dynamic
checkers.
These
are
things
you
might
not
be
as
familiar
with
working
on
rescue,
there's
kind
of
two
important
cases
that
I
want
to
talk
about
in
this
talk,
there's
miri
the
rust
interpreter,
which
basically
runs
your
program
in
like
a
fully
sandboxed
environment
and
keeps
track
of
everything
perfectly
and
will
catch
things
like.
A
A
It's
physical
hardware
that
actually
exists,
and
it
will
actually
enforce
these.
A
Static
compilers
and
their
entire
thesis
statement
is
just
well.
You
can't
commit
crimes
because
that's
illegal.
A
How
would
you
do
it?
It's
illegal
and
guards
are
expensive,
and
I
want
to
go
fast,
or
at
least
my
users
want
my
code
to
go
fast,
and
this
is
the
philosophy
of
rusty,
swifty
clang,
gcc,
all
your
static
compilers,
they
all
are
built
on
this
premise
of
people,
follow
the
rules
and
especially
for
low
level
things
like
memory
models.
A
A
So
we
need
to
deal
with
clone
containment
and
tracking
and
what
happens
when
clones
escape
and
what
happens
when
mysterious
strangers
show
up
that.
We
don't
know
about,
and
our
answers
to
this
and
our
approaches
to
this
depend
on
how
we
do
our
tracking
and
our
different
approaches:
static
versus
runtime
and
mary
versus
cherry
kind
of
changes.
A
How
this
clone
biohazard
containment
process
works.
So
we're
going
to
go
through
so
first
off
we
have
static
tracking
compilers
like
to
reason
really
function
locally.
They
want
to
be
zoomed
in
on
single
function
and
do
all
the
reasoning
there
and
then
do
that
for
all
the
functions
individually
and
put
the
parts
together
because
they're
so
zoomed
in
on
just
one
thing.
A
It's
really
easy
to
escape
their
view.
If
you
call
a
function
and
pass
another
pointer
into
it,
that
pointer
has
escaped
into
that
function,
but
we
can
see
it
happen
and
we
call
those
situations
where
it
happens,
or
rather
we
can
see
these
situations
where
a
pointer
escapes
our
view
and
call
those
exposing.
A
A
A
They
they
all
need
to
take
turns,
and
so
in
the
limit.
We
end
up
with
this,
like
the
original,
really
naive,
cogen
that
we
really
didn't
want.
But
critically,
if
I'm
working
on
my
puzzle
under
my
tree
house
and
my
tree
house
isn't
marked
as
a
biohazard
because
it
hasn't
been
exposed.
That
means
I
so
far.
I've
perfectly
tracked
my
allocation,
and
so,
if
I
see
a
biohazard
clone
walking
by,
I
don't
need
to
worry
about
it.
A
A
Now,
on
to
runtime
tracking
miri,
unlike
our
function
or
our
compiler,
which
is
zoomed
in
on
function,
muri
is
looking
at
the
whole
program
and
dynamically,
and
that
means
it
basically
sees
the
whole
world
right.
So
nothing
can
ever
possibly
escape
its
view
and,
furthermore,
miri
makes
all
the
pointers
hold
id
cards
and
it
will
check
those
id
cards
whenever
you
access
the
memory.
A
Those
id
cards
are
kind
of
like
keys
into
a
hash
table.
They
contain
a
bunch
of
different
metadata
that
mary
checks,
I'm
not
going
to
try
and
enumerate
at
all,
but
there's
a
bunch
of
different
things
that
will
check.
A
But
actually
does
it
have
a
view
of
the
whole
world
because
there's
places
with
dragons
there's
places
with
native
code,
so
really
mary's
not
really
having
a
view
of
the
whole
world.
It
has
a
view
of
rust.
It
more
has
a
view
of
like
a
country
and
inside
that
country.
It
knows
everything
that's
going
on.
It
knows
all
about
the
rest
code
and
it
can
check
every
axis
in
rest
code,
but
anytime.
A
Miri
can't
track
it
anymore
and
that's
a
problem
because
miri
is
ultimately
not
compatible
with
native
code.
It
can
show
shim
some
known
apis
so
like.
If
you
call
file
open
it'll,
know
what
to
do
to
like
shim
that
if
you
call
certain
linux
apis,
it
knows
what
to
do
to
basically
emulate
those
linux
apis.
A
But
in
the
general
case
it'll
just
crash
it'll
just
be
like.
I
don't
know
what
to
do
here,
crash
the
program
and
that's
a
frustrating
thing
for
people
who
are
trying
to
like
use
miri
to
catch.
All
their
bugs,
if
they
do
a
lot
of
system
apis
mary,
might
not
know
about
them.
Yet
it's
a
very
manual
process.
Let's
deal
with
this,
but
cherry
has
truly
conquered
its
world.
A
It
has
become
native
code.
There
is
no
incompatibility
with
nathan
code.
You
need
to
be
compatible
with
it,
and
so
it
truly
does
have
perfect
tracking,
except
for
time,
travelers
can't
track
time,
travelers
and
the
reason
it
can't
track
time.
Travelers
is
because
cherry
is
actually
implemented
in
a
very
specific
way
to
kind
of
balance,
performance
and
precision.
A
What
a
cherry
pointer
is
is
well
for
one,
it's
twice
as
big.
So
for
a
64-bit
system,
it's
actually
128-bit
pointers
and
what
they
store
in
those
extra
bits
is
an
entire
other
slice
like
a
rough
slice,
saying
like
here's,
the
range
of
memory
that
this
pointer
is
allowed
to
search
around
in,
and
that
is
that
membership
id
that
we're
talking
about.
It's
saying
like
hey
puzzle
club,
is
this
big.
A
So
let's
just
cut
down
the
tree.
Let's
free
that
allocation,
but
you
know
time
will
pass
eventually
that
tree
will
regrow
and
also
catch
on
fire
for
some
reason,
and
someone
will
build
another
clubhouse
in
there
and
it'll
be
hairdresser
club
or
whatever
is
this
the
same
club
or
is
it
not?
Can
our
old
clones
enter
this
clubhouse?
Can
puzzle
club
clones
enter
this
clubhouse?
It's
where
their
club
was
there's
a
club
there.
As
far
as
cherry
is
concerned
with
its
oh,
I
track
where
pointers
can
be.
A
This
is
fine
because
oh
a
pointer
is
just
a
location,
but
no
it's
not
that's
a
use
after
free.
We
don't
like
this.
This.
This
clone
has
become
a
freelance
plumber
in
its
retirement.
That's
no
good!
We
can't
let
this
this
puzzle-solving
plumber
wander
into
hairdresser
club
and
so
clearly
just
thinking
of
of
the
like
membership
tracking
of
this
guard
as
just
a
location
is
insufficient.
A
A
Your
membership
says
what
location
you
lived
at
and
what
the
club
was,
and
we
call
that
temporal
because
it
only
really
matters
when
time
passes,
because
it
only
matters
when
clubs
can
go
away
and
then
something
new
can
show
up
in
that
place.
A
But
really
it's
just
remembering
the
club
we
were
in,
and
I
don't
really
have
time
to
get
in
this.
But
it
is
interesting
that
this
actually
is
kind
of
a
fractal
thing,
because
we
care
about
allocators
in
some
sense,
but
your
opera,
your
your
system,
your
program,
has
a
lot
of
nested
allocators
because
there's
like
the
kernel,
allocator
and
then
malik
allocates
pages
from
that
and
your
program
allocates
pages.
A
How
would
we
know
that?
Did
their
membership
id
turn
into
energy
with
them
and
follow
them,
or
did
they
drop
it
on
the
ground
and,
as
it
turns
out,
both
of
those
are
valid
answers?
So,
let's
look
at
how
our
different
approaches
kind
of
try
to
address
this
question.
A
Our
static
compilers
say:
actually,
this
is
kind
of
okay.
They
mostly
want
to
reason
spatially.
A
Whenever
you
do
these
operations
and
that's
basically,
all
you
really
need
to
do
to
be
careful
about
this
transcendent
stuff
is
just
be
careful
when
these
operations
happen
and,
unfortunately,
our
compiler
back-ends.
Don't
really
do
this,
and
this
is
one
of
the
frustrations.
I
had
that
got
me
to
work
on
this
stuff
we'll
get
into
well.
A
The
high
level
detail
is
just
llvm
doesn't
want
to
treat
turning
a
pointer
into
an
integer
as
an
exposing
operation,
because
that
would
pessimize
all
the
code
that
touches
that
allocation.
But
you
need
to
do
it
because
otherwise
you
can
get
miscompilations
and
they
do
exist.
A
Because
now
we
really
do
need
to
answer
that
question
about
what
happens
when
it
turns
into
energy.
Does
it
drop
its
membership
on
the
ground,
or
does
it
take
it
with
it?
Because
in
something
like
cherry,
a
pointer
is
128
bits
wide,
but
the
address
part
that's
only
64
bits
wide.
So
if
I
could
just
get
the
address
part,
that's
a
big
space
savings,
that'll
cut
my
memory
usage
in
half
and
really
most
of
the
time.
People
are
actually
only
interested
in
the
address
part,
but
maybe
they
want
to
do
this.
A
They
want
to
come
back
as
a
pointer,
and
maybe
that
means
I
need
to
carry
all
the
bits
around
and
yeah
the
the
address
part.
A
A
We
saw
with
the
static
compiler
that
allowing
these
things
or
tracking
this
concept
of
exposing
kind
of
made
everything
okay.
So
what
if
we
dynamically
model
that
concept
and
basically
when
we
turn
an
integer
back
into
a
pointer,
we
look
at
all
of
the
currently
exposed
allocations
and
check
if
it's
inside
of
one,
we
do
a
hit
test
on
them
and
if
it
is
inside
one
well,
we
just
forge
an
id
for
it.
A
Now.
This
leads
to
two
problems:
the
philosophical
problem
that
frustrates
me,
which
might
not
be
that
big
of
a
problem
in
practice,
but
still
annoying,
is
this
basically
reintroduces
the
concept
of
a
use
after
free
as
long
as
you
do
it
through
transcendence,
through
integer,
casts
and
because
remember,
use
after
freeze
were
a
problem
when
we
wanted
our
memberships
to
just
be
a
location.
We
needed
to
add
this
temporal
component
this.
A
The
more
serious
problem
is
for
cherry.
Those
bits
are
important
and
they
can't
be
forged.
Like
cherry
doesn't
the
way
cherry
works,
it
can't
like
reconstitute
that
slice
that
was
stored
inside
the
pointer,
that's
gone.
It
doesn't
know
what
to
put
there.
A
So
this
just
doesn't
work
and
so
cherry
needed
to
find
a
solution,
and
they
came
up
with
a
very
simple
solution,
which
was
just
hey,
find
a
sponsor
when
you
turn
yourself
from
pure
energy,
from
an
integer
back
into
a
pointer
just
find
someone
who's
in
the
in
your
club
and
get
them
to
vouch
for
you
and
when
they
do
vouch
for
you
just
copy
their
membership
copy.
A
Those
bits,
and
the
reason
this
is
better,
is
because
it
kind
of
fundamentally
proves
that
you
knew
where
you
were
supposed
to
be,
because
not
only
did
you
know
the
location
that
you
were
supposed
to
be,
but
you
knew
someone
else
who
is
in
that
club
who
has
that
who
has
access
to
that
allocation,
which
generally
would
not
be
the
case
if
you're
doing
an
actual
use
after
free
and
that
simple
idea
of
finding
sponsorship?
That's
what
strict
provenance
is.
That's
the
whole
idea
with
these
apis.
A
Yeah,
so
the
pretending,
if
everything
was
nicer,
is
just
pretend
that
we
have
to
do
this
operation
that
we
have
to
do
this
sponsorship
operation,
because
it
cleans
up
this
weird
nasty
edge
case
of
going
from
a
pointer
to
an
integer
to
a
pointer
and
losing
information.
A
A
A
Is
the
sponsorship
operation
so
rather
than
saying
some
address,
as
starconst
we'll
just
say:
hey
sponsor
pointer,
make
a
copy
of
yourself
with
this
new
address,
so
we're
turning
this
unary
cast
this
one
operation
cast
to
a
binary
cast.
That's
that's
the
main
thing
with
strict
problems.
Just
this
one
api.
Everything
else
is
things
to
be
more
explicit
or
convenience
apis.
A
In
the
case
of
being
more
explicit,
we
now
have
apis
to
be
explicit
about
whether
you
actually
meant
to
expose
or
not
because
remember,
llvm
doesn't
want
to
make
integer
cast
pointer
to
integer,
be
exposing
because
it'll
pessimize
things,
so
let's
just
make
that
explicit,
so
that
we
can
say
whether
we
really
did
need
the
exposing
or
we
didn't.
So,
if
you're
just
doing
something
like
hey,
I
want
to
cast
a
pointer
to
an
integer,
because
I
want
to
check
if
it's
aligned
you're
not
going
to
turn
that
integer
back
into
the
pointer.
A
So
you
don't
need
to
expose
the
address
you're
not
going
to
let
the
clones
escape
basically,
and
so
you
have
these
two
options
and
the
second
one
dot
adder
is
shorter,
because
that's
the
one
you
usually
want
and
because
that's
what
llvm
is
assuming
today
anyway.
So
even
though
it's
like
technically
more
dangerous,
because
it's
saying
like
assume,
I'm
not
going
to
let
this
escape
and
do
bad
stuff,
that's
just
what
the
compiler's
already
assuming
and
then
we
have
some
api.
We
have
in
a
similar
vein.
A
We
kind
of
have
these
apis
for
doing
an
integer
to
a
pointer
as
a
unary
operation,
but
more
explicit
about
which
thing
you're
trying
to
use.
Are
you
actually
just
creating
an
invalid
pointer,
like
say,
pointer,
dangling
for
those
who
know
about
it?
Or
are
you
actually
relying
on
exposure
as
an
operation?
A
And
when
you
do
that,
we
can
have
our
we
can
either
say
like?
Oh,
your
code
won't
work
on
cherry
or
we
can
try
and
work
out
what
to
do.
This
gives
us
more
flexibility
as
how
to
handle
all
these
other
platforms
or
these
dynamic,
checkers
and
not
strictly
part
of
strict
providence
but
kind
of
a
fallout
of
it.
Is
we
added
a
bunch
of
convenience
apis?
So
now
you
can
check.
Is
this
pointer
aligned
or
is
this
pointer
aligned
to
this?
A
Given
alignment-
or
you
can
say,
hey
offset
this
pointer
by
some
byte
amount
so,
instead
of
like
by
the
stride
just
be
like.
I
want
this
pointer
to
increase
by
three
bytes
and
we
even
added
some
more
operations
to
atomic
pointers
so
that
you
can
stay
in
pointers.
That's
that's
kind
of
one
of
the
big
takeaways
is
treat
things
that
are
pointers
as
pointers
or
things
that
might
be
pointers
as
pointers.
A
One
of
the
mantras
I
had
to
repeat
a
lot
was
just
if
something
is
like
a
pointer
or
an
integer
treat
that
as
a
pointer,
because
in
the
past
a
lot
of
people
said
oh
I'll,
treat
that
as
an
integer
because
that's
more
convenient.
It's
also
saying
the
compiler
and
it's
basically
an
integer.
Don't
worry
about
tracking
it.
Compilers
track
pointers
a
lot
more
carefully
and
we
want
to
stay
in
that
mode,
so
they
track
more
carefully.
A
You
want
to
tell
them
to
track
the
clones
rather
than
this
pure
energy
floating
through
the
ether
and
just
as
a
final
detail.
All
of
this,
even
though
these
are
all
unstable
apis
on
in
the
core
library
or
the
standard
library
right
now,
most
of
them
are
available
in
the
strict
provenance
polyfill
s
pointer
because,
as
I
said,
a
lot
of
this
code
is
really
trivial.
It's
like
a
few
lines
of
code.
It's
like
just
do
a
pointer,
offset
yeah,
so
that's
puzzle
club.
A
Hopefully
now
you
perfectly
understand
memory
models
and
could
write
a
phd
thesis
on
it.
I'm
sure
you
can
this
I
mean
puzzle
club
is
such
such
an
elegant
and
simple
concept.
It's
it's
perfect.
I
don't
know
this.
Talk's
done
have
a
good
lunch.
Peace.