Uh oh!
There was an error while loading. Please reload this page.
RFC: Rename *T to *const T - #68
Conversation
alexcrichton
commented
May 5, 2014
vadimcn
commented
May 6, 2014
-1: I think that internal language consistency is more important than compatibility with C. |
dobkeratops
commented
May 6, 2014
is this helpful (or even essential?) for aliasing rules. i think i was told you dont need 'restrict' because safe code does that job (non-aliased mutable pointers). i think it would be confusing to flip mut->const, but then again, unsafe code is going to require special attention anyway. ( i had originally asked if you needed the opposite of 'restrict' or something like that, but this might be a solution ) |
thestinger
commented
May 6, 2014
@dobkeratops: This isn't related to |
dobkeratops
commented
May 6, 2014
ok so either way the rule would be unsafe pointers are assumed to potentially alias , i guess (be it mut/non mut or non const/const). |
thestinger
commented
May 6, 2014
In order to return |
huonw
commented
May 6, 2014
I would prefer to have
I don't think it is possible to lint |
There was a problem hiding this comment.
Is there some motivation for this? &mut T coerces to &T.
There was a problem hiding this comment.
Mostly just to remain the same as today's semantics with *T and *mut T. It doesn't seem like much could go wrong, but too many coercions may push us in the direction of implicit coercions between these two unsafe pointers, which I'd be a little worried about.
I don't have a huge preference one way or another on this (I'm fine amending it into the RFC)
There was a problem hiding this comment.
I think &mut should coerce to *const, and both conversions should be considered to consume the &mut if they don't already.
There was a problem hiding this comment.
Consumption may not work as intended, I believe you can continue to create &mut T pointers via &mut *expr (reborrowing).
There was a problem hiding this comment.
Consumption may not work as intended, I believe you can continue to create &mut T pointers via &mut *expr (reborrowing).
If so, it still requires explicit thought & some actual code, rather than it happening automatically/implicitly.
telotortium
commented
May 6, 2014
If it turns out that trying to reconcile Rust and C semantics on unsafe #[no_mangle]externfnmemcpy(dst:#[cvqual(restrict)]*c_void,
src:#[cvqual(const, restrict)]*c_void,n:size_t) -> *c_void;Of course, the compiler would have to learn how to handle the
|
bharrisau
commented
May 6, 2014
This feels a better way to go than changing what *T currently means. |
anasazi
commented
May 6, 2014
I think I prefer the |
SiegeLord
commented
May 6, 2014
I don't see the evidence for the 'confusion' aspect. The vast majority of FFI code is (or should be) generated by rust-bindgen, which gets the As for the rest of Rust, I think the symmetry with all the other references explains how it's meant to be used. Notably, there's no consideration for the confusion between C++ references and our borrowed pointers which also have a flipped mutability. |
huonw
commented
May 6, 2014
@SiegeLord that approach is actually mentioned under "Alternatives". :) |
SiegeLord
commented
May 6, 2014
I missed that, although I disagree that it's an 'alternative'. |
bstrie
commented
May 6, 2014
Without commenting on the RFC directly, @SiegeLord , I don't know how realistic it is to expect that we will ever arrive at a point where tools will obviate the need to write FFI code. Even today, there are plenty of people willingly avoiding rust-bindgen in favor of rolling their own wrappers by hand. If this RFC is accepted, count me among those who would prefer to have both |
anasazi
commented
May 6, 2014
@bstrie my thoughts exactly. It'd be great if we could automate it all away, but I think that's unlikely. |
thestinger
commented
May 6, 2014
We do need to get to the point where hard-wiring an ABI by hand is not required. Libraries often change the ABI between versions and it's not uncommon for an ABI to vary between platforms or different configurations of the library. At the moment, these changes will lead to silent memory corruption issues or worse. Since the remaining uses of raw pointers are native to Rust rather than for C wrappers, I think @SiegeLord's argument is a good one. |
SiegeLord
commented
May 7, 2014
Assuming you've meant bindings (stuff that goes inside |
huonw
commented
May 7, 2014
BTW, rust-lang/rust#2124 is the issue for autogenerated bindings. |
bstrie
commented
May 7, 2014
@SiegeLord , I'm not the one you need to convince. :) I use bindgen, I love bindgen. It seems to be mostly graphics people who don't trust bindgen to not muck things up, but I'm not going to pretend that I have tons of evidence here. @thestinger , I thought you were campaigning for this change a while ago, before the RFC process existed. Have you reversed your position? Because if you don't think it's an issue, then I'll trust your judgment. |
thestinger
commented
May 7, 2014
@bstrie: I supported changing this before, but I'm less sure now. I don't really like the idea of making changes in I think part of the problem is that |
bill-myers
commented
May 7, 2014
What about replacing the |
thestinger
commented
May 7, 2014
@bill-myers: What would be the name for the mutable one? |
nathanaschbacher
commented
May 15, 2014
@bill-myers I actually sorta like that. Maybe there's some consistency to be gained by following an axiom. Sorta the Smalltalk/Ruby way where "everything is an object". In Rust it could be "everything is an explicit named type" which is essentially true already, but just not expressed consistently. Some things are explicit like Part of me likes the sugar, because it's short-hand, but so much of the sugar has been removed/changed ( The most painful part of development for me is context switching. Following one convention, axiom consistently would make that easier and less all over the map like C++ is. @thestinger, |
alexcrichton
commented
May 28, 2014
I have updated this with |
bharrisau
commented
May 28, 2014
How does this all relate to the issues around " |
pnkfelix
commented
May 29, 2014
@bharrisau I would say that this is a aliasing thing, though maybe not in the way you expected. We are not saying See e.g. http://yarchive.net/comp/const.html This is a crucial distinction between a const-qualified pointer To my mind, the advantage of using |
LeoTestard
commented
Jun 6, 2014
I'm a bit worried about this RFC. |
alexcrichton
commented
Jun 6, 2014
I am wary of dealing with I currently only know of You're right though, All-in-all, I personally feel like first-class language types are still necessary. These are the absolute core building blocks of all other primitives, which seems like they should have first-class support (even though they shouldn't be widely used). |
arcto
commented
Jun 6, 2014
It has to be more important that Rust is consistent than similar to C. The idea of being a systems programming language also means dealing with hardware by itself, not relying on a 40+ year old language. FFI to C is only one use case for raw pointers. |
darnuria
commented
Jun 6, 2014
+1 @LeoTestard, I think in my humble experience of Rust. It's not a good idea to design rust with C in mind. C is well know for its complexity... Also the actual syntax is really good for reading code, it's clear and efficient. And to repond to @pnkfelix
Yes but it add all of the overhead in C about |
pnkfelix
commented
Jun 6, 2014
Sigh. Its not out of love for C that I contend that For example, If I thought that @darnuria I do not know what this:
is trying to say. Are you referring to syntactic overhead? Or are you talking about the fact that in C the declarations |
darnuria
commented
Jun 7, 2014
@pnkfelix: Sorry after reflection I was not clear.
By this statement I expressed the fact that C had a very different idea behind the // 1. In some way you have immutability to a value like in:constcharch='c';
// 2. Imutability to a pointer like:constchar*str="Toto";
// 3. Or a pointer to a pointer to const char:constchar**ptr_to_str=str;
// etc...And in this case 1. and are OK because it's not difficult to reason about them. But in the 3. case it's not clear to reason about it... Other point: Disclaimer: |
pnkfelix
commented
Jun 7, 2014
@darnuria Your example translates directly to types one can describe already today in Rust, like so: fnmain(){#![allow(unused_mut)]// disable warnings to allow faithful transcription.let ch :u8 = 'c'asu8;letmut str1 :*u8 = "Toto".as_bytes().as_ptr();letmut ptr_to_str :*mut*u8 = &mut str1 as*mut_;unsafe{printout(str1, ptr_to_str);// **ptr_to_str = ch; // This would error with "cannot assign to ..."// *str1 = ch; // and this would as well.letmut but = ['U'asu8,'h'asu8,'O'asu8,'h'asu8];*ptr_to_str = but.as_ptr();printout(str1, ptr_to_str);
but[0] = ch;// Accepted; `*str1` changes (`str1` does not, of
but[1] = '?'asu8;// course).`str1` is just like a `*const char` in C.printout(str1, ptr_to_str);}fnprintout(str1:*u8,ptr_to_str:*mut*u8){unsafe{println!("Hello str1[0, 1] {} str1: {:014} ptr_to_str: {}",[*str1 aschar,*str1.offset(1)aschar].as_slice(),
str1,
ptr_to_str);}}}What does this print? Depending on what addresses it allocates, it prints something like this: If you think it is hard to reason about the type of My claim is that reasoning about the two cases is the same. We already support the notion of a |
glaebhoerl
commented
Jun 7, 2014
I would suggest that if the best option on the merits is not obvious, backwards compatibility can be a tie breaker. In that respect, |
*mut T, add *const T*T to *const Talexcrichton
commented
Jun 16, 2014
ping @nikomatsakis, I updated with our discussion on Friday about when it is safe to coerce. I also added a new unresolved question about applying temporary lifetimes to coercions. |
There was a problem hiding this comment.
Caveat: I am not sure if we currently consume during such a coercion. we should test.
There was a problem hiding this comment.
It looks like we don't, this code is accepted today:
extern{fnbar(a:*mutint,b:*mutint);}unsafefnfoo(a:&mutint){bar(a, a)}brson
commented
Jun 24, 2014
Accepted as RFC 32. |
This does not yet change the compiler and libraries from `*T` to `*const T` as it will require a snapshot to do so. cc #7362 --- Note that the corresponding RFC, rust-lang/rfcs#68, has not yet been accepted. It was [discussed at the last meeting](https://github.com/rust-lang/rust/wiki/Meeting-weekly-2014-06-10#rfc-pr-68-unsafe-pointers-rename-t-to-const-t) and decided to be accepted, however. I figured I'd get started on the preliminary work for the RFC that will be required regardless.
This does not yet change the compiler and libraries from `*T` to `*const T` as it will require a snapshot to do so. cc #7362 --- Note that the corresponding RFC, rust-lang/rfcs#68, has not yet been accepted. It was [discussed at the last meeting](https://github.com/rust-lang/rust/wiki/Meeting-weekly-2014-06-10#rfc-pr-68-unsafe-pointers-rename-t-to-const-t) and decided to be accepted, however. I figured I'd get started on the preliminary work for the RFC that will be required regardless.
clarification about Stream::into_future()
No description provided.