Stream: t-lang/wg-unsafe-code-guidelines

Topic: meeting-2019-02-21


RalfJ (Feb 21 2019 at 16:17, on Zulip):

So, we should have a meeting now, right?

Alan Jeffrey (Feb 21 2019 at 16:17, on Zulip):

:wave:

gnzlbg (Feb 21 2019 at 16:17, on Zulip):

i think so

RalfJ (Feb 21 2019 at 16:19, on Zulip):

so, do we have an agenda? /me looks at PRs

RalfJ (Feb 21 2019 at 16:19, on Zulip):

@nikomatsakis I think we still don't have an mdBook deployed, do we?

RalfJ (Feb 21 2019 at 16:20, on Zulip):

other than that, we have https://github.com/rust-rfcs/unsafe-code-guidelines/pull/83

RalfJ (Feb 21 2019 at 16:20, on Zulip):

I think I resolved all of @gnzlbg 's comments

gnzlbg (Feb 21 2019 at 16:20, on Zulip):

i think so too, looks good to merge

nikomatsakis (Feb 21 2019 at 16:20, on Zulip):

argh, y'all, sorry, I am trying to jump on a time-sensitive bug

nikomatsakis (Feb 21 2019 at 16:20, on Zulip):

so I can't really follow meeting just now

RalfJ (Feb 21 2019 at 16:20, on Zulip):

i think so too, looks good to merge

all right, merging then

nikomatsakis (Feb 21 2019 at 16:20, on Zulip):

but I think I creatd a GH_TOKEN

nikomatsakis (Feb 21 2019 at 16:20, on Zulip):

in the travis setup

nikomatsakis (Feb 21 2019 at 16:20, on Zulip):

so maybe in theory things will work

nikomatsakis (Feb 21 2019 at 16:20, on Zulip):

if not, I can try to debug that later

nikomatsakis (Feb 21 2019 at 16:21, on Zulip):

or give one of you admin access and you can do it :)

RalfJ (Feb 21 2019 at 16:21, on Zulip):

I nominate @gnzlbg :P

RalfJ (Feb 21 2019 at 16:21, on Zulip):

/me has never done any of this before

gnzlbg (Feb 21 2019 at 16:22, on Zulip):

ah, I had to update the book PR, damn

gnzlbg (Feb 21 2019 at 16:22, on Zulip):

completely forgot about that

RalfJ (Feb 21 2019 at 16:22, on Zulip):

in terms of discussions, no that much seems to happen any more

RalfJ (Feb 21 2019 at 16:23, on Zulip):

we hit some hard questions in some cases, and it seems we mostly have consensus for the rest?

RalfJ (Feb 21 2019 at 16:23, on Zulip):

we haven't talked at all about references to unsized types, but maybe just nobody wants to touch that^^

RalfJ (Feb 21 2019 at 16:24, on Zulip):

I wonder if it is worth starting to write up some of the simple, uncontroversial cases (I am thinking structs, enums and the like)

gnzlbg (Feb 21 2019 at 16:26, on Zulip):

sounds good to me
I also think that it might be worth writing down the cases in which representation and validity are "entangled" (where we need to fix both at the same time and can't fully split the discussion)

RalfJ (Feb 21 2019 at 16:26, on Zulip):

which cases are you thinking of?

gnzlbg (Feb 21 2019 at 16:26, on Zulip):

i think one case was unions, whether the fields should be at offset 0 or not, depended somehow on validity

RalfJ (Feb 21 2019 at 16:27, on Zulip):

also, is anyone volunteering for the writeup? I will likely end up doing many of the hard cases, so maybe someone else could do the easy ones?^^

gnzlbg (Feb 21 2019 at 16:27, on Zulip):

which ones do you have in mind?

RalfJ (Feb 21 2019 at 16:28, on Zulip):

structs, arrays, ... (you know, all the types laid out side-by-side), and enums

gnzlbg (Feb 21 2019 at 16:28, on Zulip):

the ones where validity depends on the validity of fields ?

RalfJ (Feb 21 2019 at 16:28, on Zulip):

i think one case was unions, whether the fields should be at offset 0 or not, depended somehow on validity

hm, I see. In my head we first define validity and then the rest follows, but of course defining a stricter validity is motivated by doing layout optimizations.

gnzlbg (Feb 21 2019 at 16:29, on Zulip):

so for structs, enums, arrays, tuples, vectors, (am I missing any?), I can just write a small document stating that

RalfJ (Feb 21 2019 at 16:29, on Zulip):

for unions in particular, from all I can tell there's a fairly binary choice we can make here, with different trade-offs, and it might be worth just "documenting the controversy". I dont see data helping here.

RalfJ (Feb 21 2019 at 16:30, on Zulip):

the issue lists structs, tuples, arrays, slices, closures, generators, SIMD vectors

RalfJ (Feb 21 2019 at 16:30, on Zulip):

but generators are special

RalfJ (Feb 21 2019 at 16:30, on Zulip):

I can add the part about generators to your document, if you dont feel confident explaining that

RalfJ (Feb 21 2019 at 16:30, on Zulip):

(and we might give out an advisory to change them so they are no longer special)

gnzlbg (Feb 21 2019 at 16:31, on Zulip):

i don't feel very comfortable doing closure and generators and not doing function types there.

gnzlbg (Feb 21 2019 at 16:32, on Zulip):

but for the rest, i can word it up, and ping @RalfJ on it

gnzlbg (Feb 21 2019 at 16:32, on Zulip):

we don't have to do all of that in the same PR

RalfJ (Feb 21 2019 at 16:34, on Zulip):

closures are just a struct and have nothing to do with function types

RalfJ (Feb 21 2019 at 16:34, on Zulip):

and there is nothing weird about them, unlike generators

RalfJ (Feb 21 2019 at 16:35, on Zulip):

by closure type above I mean ty::Closure, which is the type of the environment of a closure

gnzlbg (Feb 21 2019 at 16:35, on Zulip):

I thought an empty closure coerces into a function type, so that there might be some relationship, but if we can just treat them as just structs

RalfJ (Feb 21 2019 at 16:35, on Zulip):

the type that the Fn traits are implemented for

RalfJ (Feb 21 2019 at 16:35, on Zulip):

yes it does, but empty closures are a ZST, their ty::Closure is like a struct with no field. validity is boring for these.

gnzlbg (Feb 21 2019 at 16:36, on Zulip):

ah, I thought the closure would be both the environment and the fn type, if its just the environment, then that's the same as for structs

gnzlbg (Feb 21 2019 at 16:36, on Zulip):

(as in, the environment, and the function that's called with that environment)

RalfJ (Feb 21 2019 at 16:36, on Zulip):

the function that's called with that environment is in the vtable

RalfJ (Feb 21 2019 at 16:37, on Zulip):

as part of the fat pointer (when using dyn Fn)

RalfJ (Feb 21 2019 at 16:37, on Zulip):

or for fn foo(x: impl Fn), it is handled completely statically

gnzlbg (Feb 21 2019 at 16:37, on Zulip):

can one manually modify that ?
that is, create a closure, and then write a different function there ?

RalfJ (Feb 21 2019 at 16:38, on Zulip):

no it's all generated

RalfJ (Feb 21 2019 at 16:38, on Zulip):

with enough unstable features you can impl Fn for your own type though :P

RalfJ (Feb 21 2019 at 16:38, on Zulip):

and then you "modify" that function pointer -- it'll point to the function you write as part of that impl

gnzlbg (Feb 21 2019 at 16:38, on Zulip):

i mean, if its in the trait object vtable, then whether the closure is valid would depend on whether the vtable would be valid

RalfJ (Feb 21 2019 at 16:39, on Zulip):

that's part of the validity of the &dyn Fn reference

RalfJ (Feb 21 2019 at 16:39, on Zulip):

but the environment (the ty::Closure) doesn't care

gnzlbg (Feb 21 2019 at 16:40, on Zulip):

i did not meant to suggest that the function is modified statically, but like, at run-time:

let c: i32;
let mut d = | x, y | { x + y + c };
fn bar(_env: *const (), x: i32, y: i32) -> i32 { x - y  }
d.__fn_ptr = bar;
d(0, 3);
gnzlbg (Feb 21 2019 at 16:42, on Zulip):

That's what I had in mind when I thought that the validity of a closure might depend not only on the environment being valid, but also on the function that it invokes being valid - supposing that this all could be modified at run-time.

RalfJ (Feb 21 2019 at 16:43, on Zulip):

well first of all, not all these mismatches must be detected by the validity invariant

RalfJ (Feb 21 2019 at 16:43, on Zulip):

d.__fn_ptr makes no sense

RalfJ (Feb 21 2019 at 16:43, on Zulip):

there is no function pointer there

RalfJ (Feb 21 2019 at 16:44, on Zulip):

d has type ty::Closure[something], which is basically (i32,)

gnzlbg (Feb 21 2019 at 16:44, on Zulip):

and the function is just a method on the closure ?

RalfJ (Feb 21 2019 at 16:44, on Zulip):

and then there is a impl Fn for [d's type] { fn __call(self, x, y) { x + y + self.0 } }

RalfJ (Feb 21 2019 at 16:45, on Zulip):

but just like Vec's dont contain a function pointer for the impl Debug for Vec, d will not contain a fn ptr for this impl Fn

RalfJ (Feb 21 2019 at 16:46, on Zulip):

when you do let d: &dyn Fn = &d, then the same thing happens as when you do let v: &dyn Debug = vec![0]

gnzlbg (Feb 21 2019 at 16:46, on Zulip):

that makes sense, i though this was implemented differently:

fn __closure_fn(...) -> ... {}
type Closure = (i32, fn(...) -> ...)
let c = Closure(c, __closure_fn);
RalfJ (Feb 21 2019 at 16:46, on Zulip):

a vtable gets created, with fn ptr to the functions implementing that trait for the given type, and the vtable ptr gets paired up with the ptr to the element of the type implementing the trait

RalfJ (Feb 21 2019 at 16:47, on Zulip):

well that fhn ptr would be useless if we end up using static dispatch

gnzlbg (Feb 21 2019 at 16:47, on Zulip):

gotcha, i was confused

RalfJ (Feb 21 2019 at 16:47, on Zulip):

also this is much nicer becuase there dynamically dispatched closures basically are just an instance of the general dyn Trait mechanism :D

RalfJ (Feb 21 2019 at 16:47, on Zulip):

(I love this)

gnzlbg (Feb 21 2019 at 16:47, on Zulip):

yes, i though that it wouldn't matter much because llvm could eliminate it, but that is more elegant

RalfJ (Feb 21 2019 at 16:47, on Zulip):

we dont rely on LLVM if we can help it :D

gnzlbg (Feb 21 2019 at 16:48, on Zulip):

well that simplifies validity of closures, its just the same as for structs

RalfJ (Feb 21 2019 at 16:48, on Zulip):

exactly

gnzlbg (Feb 21 2019 at 16:48, on Zulip):

so I can draft that

RalfJ (Feb 21 2019 at 16:48, on Zulip):

awesome :)

RalfJ (Feb 21 2019 at 16:48, on Zulip):

and with that, I have to leave... thanks all!

Last update: Nov 20 2019 at 11:40UTC