and yeah, if we have memcpy as a primitive, unaligned_read is semi-redundant
except for guaranteeing no copies
but finding the best set of primitives is not something we want to get to
ubsan
The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object
having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.
arielby
ubsan: memcpy does char writes
ubsandroid has quit
and char is TBAA-compatible with anything
ubsan
yeah
just showing what effective type is
arielby
" If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. "
?
that sounds bad
ubsan
yeah
TBAA is awful
arielby
the "write-to-read" variant is OK
I mean, LLVM-style TBAA
and that's what compilers in practice use
ubsan
'kay
I'll trust you there
I have to read about it
anyways, so, the point is
besides all the TBAA stuff
memcpy is, I would argue, a primitive
ptr::copy_nonoverlapping
brson joined the channel
and, secondly, transmute_copy might take DSTs for T
it would make it a heck of a lot more useful
but that's not really what interests me
nmatsakis: casts!
nmatsakis
:)
yes!
Ericson2314 has quit
arielby
ubsan: ok
so we'll write transmute_copy in terms of copy_nonoverlapping
ubsan
yeah
nmatsakis: basically, right now, there are two options for casts which are both hella overloaded
basically, I want to create a rust where there are four cast types: as, transmute, lifetime_cast, and ptr_cast
`as` will be for safe casts, like usize as u32, or fn() as u8
`transmute` will be for bitcasts, like struct X { u32 } -> u32
lifetime_cast will allow for both lifetime shortening *and* lengthening, of any lifetime included
(in the type)
SilverKey has quit
arielby
ubsan: we basically got casts from C++
ubsan
arielby: right, exactly
that's where the inspiration comes from
arielby
because we couldn't be bothered to declare an intrinsic for everything
nmatsakis
ubsan: I like the sound of this, certainly
ubsan
ermm
arielby
if it was up to me, float <-> int would be an intrinsic
not a cast
ubsan
arielby: C++ has their shit together :P
they have all the casts
nmatsakis
I am imagining that you are envisioning things like lifetime_cast<T>(U)
ubsan
we got our casts from C :3
nmatsakis
i.e., a keyword?
ubsan
nmatsakis: well, originally
nmatsakis
since you're citing C++ :)
ubsan
but scott wants it to be an intrinsic
and I'm fine with that
nmatsakis
(the other big factor in our cast story has been constant expressions; we've often tried to remove `as` but run up against that wall)
arielby
ubsan: intrinsic-like-things should be intrinsics
ubsan
arielby: yeah, makes sense
nmatsakis
yeah, an intrinsic seems fine.
ubsan
so, finally
ptr_cast
which is an unsafe cast
nmatsakis
the only reason `as` is not, imo, is the const fn thing I was mentioning
that is, that we didn't have it at the time when we were talking about it, and weren't sure about adding it
I think moving casts -> intrinsics is definitely doubling down on const fn, which is a thing to think about, but I don't see that as esp. controversial these days
arielby
nmatsakis: it is also oddly-typed
ubsan
which turns any pointer into any other, and also turns a usize|isize into a pointer
I remain ... pretty unpersuaded that it is worth distinguishing fn pointers from other pointers. Or, maybe, pretty unsure how to handle portability in cases like these.
but anyway the broad strokes of the idea seem good to me
ubsan
nmatsakis: the issue is that you can't use `as` with fn()
so you end up using transmute
this has you not use transmute for that
nmatsakis
and I think giving intentionality to the purpose of your cast (a la C++) has to be a win
ubsan
yeah :)
nmatsakis
ok maybe I misunderstood what you were saying re: fn
ubsan
yeah, the point is to make them less specialized
and if an impl *can't* convert, well then, it wouldn't allow those conversions
arielby
ubsan: I think that now
the C-enum+char+bool -> int casts
should be discriminant_value
ubsan
arielby: I feel like that's too specialized
arielby
ubsan: we already have discriminant_value
ubsan
I would want something that goes int->int and C-enum+char+bool->int and u8|i8->char
playbot: -1i8 as char
NOTICE: error: only `u8` can be cast as `char`, not `i8`
NOTICE: --> <anon>:10:10
NOTICE: 10 |> -1i8 as char
NOTICE: (output truncated; full output at http://bit.ly/2awgFY9)
huh
okay, well, u8->char
arielby
ubsan: so u8 -> char is the odd one out
ubsan
oh, and flt->int and int->flt and flt->flt
of course
call it something like "prim_cast"
arielby
ubsan: you create chars via transmute anyway
so I say just nix it
or have an unsafe version so you don't need to transmute or w/e