Yes. But *'a const Tdoes change. Otherwise what's the point? You can mem::swap of two variables &'a T and &'a T types, but can not do the same with &'a T and &'b T. That's the whole point of litetimes, they exist specifically for that.
Your “pointers with a lifetime” would need to act in the same fashion.
Yes. But that difference means it's no longer*const. It's now *'a const. A different type. And we would need to decide whether it's lifetime is covariant, contravariant or invariant, how should that lifetime be treated when you use “normal” pointer together with “pointer with a lifetime”, etc.
Can you, please, forget about “result of the compilation”? We have enough “we code for the hardware” C and C++ guys, there are no need to create another such group among Rust developers.
Yes, rules of the Rust language are derived from the need to, eventually, produce machine code – we couldn't rely on properties of generated machine code.
We may discuss semantic of Rust program, we may discuss semantic of Rust program be should never mix them or Rice's theorem would kill our attempts to define rules.
Sometimes it is - not a problem, but a restriction requiring some additional tweaks. Not often though, since due to the borrow checking rules, there are a lot of places where implicit conversions (mainly due to variance) can soundly eliminate this difference.
If it doesn't then that's another “trust me” language. We already have two: C and C++. No need to invent another one.
The interesting part should be:
How that new “pointers with lifetimes” behave in the language
And not interesting part is:
How these new “pointers with lifetimes” are implemented in hardware.
We souldn't say “these things behave like hardware behaves” because “like hardware behaves” describes not the Rust program but result of compilation – and it's not possible to use that to define behavior of a program before compilations… Rice's theorem gets us.
Yes, if you want to assign one to another compiler should (and would!) stop you.
Most of the time it's an advantage (because it stops you from doing mistakes), but sometimes it's a problem (because you are doing something like double-linked list and it becomes impossible to assign lifetimes to pointers). Notably: compiler guarantess safety. Not developer.
That's why we have pointers: they are safe to create, but not safe to use precisely because they don't carry lifetime and one *const T is always assignable to *const T. Now developer and not compiler need to think about when they are safe to use and when they are not safe to use.
And developer may take some *const T, some &'a U and say “hey, I'm sure that we can generate &'a T from these two, lifetime from one, address from another… it's all fine”.
You propose to introduce third category: pointers with a lifetime. Some kind of hybrid that's not reference, but still have a lifetime.
Immediately quesions arise:
What would be the different between '&'a T and *a T? What about &'a mut T?
Who would guarantee safety, when and how?
How would existing *const T and new *'a const T work together?
It's not impossible to answer these questions, but before we have these answers it's hard to saw whethe that complication of the language is worth it. Most likely not.
Yes. And that's a problem. You are proposing another thing, *'a const T that's, somehow different from &'a T – yet don't say how it's different and why you want to have that difference.
IOW: you are describing the least interesting part (how program should look like) while ignoring the most important part (how said program should work).
*const T exist to resolve the issues with lifetimes when they are too complex for the compiler to understand. If you attach lifetime to it then it immediately loses that function.
It's like saying that making the hole in the middle of boat is not a problem since many car have them… sure, that's not a problem for cars that are not supposer to be put in water, but that's very much a problem for boats.
Pointers exist, in Rust, specifically to provide a way to write “trust me” unsafe code. Adding lifetimes to them would make that impossible.
That means that you would have new kind of pointers (in addition to references and normals pointers) and the question arisess: does that complication to the language carry it's weight or not?
To discuss that we need not just define syntax of your new creation, but semantic of it… and you don't even agree to say whether *'a const T and *const T are different types or not.
That's not the case in general, since these implicit conversions can not in general be replicated on pointers the same way they are on references. In some cases, they would be unsound (if we allow the conversion which is actually incorrect - to get an existing example, we can't convert from Cell<&'a T> to Cell<&'b T>, since this would indirectly allow for use-after-free). And if we try to constrain them to remove this unsoundness, they become way too restrictive.
I believe we are not really discussing exactly the same things here.
I believe that there isn't technically a problem of having *'a const if we can have &'a which is exactly the same.
Not OP, but I feel I get what OP wants to do, but failed to express nicely.
In current rust, we have &'a T and *const T. &'a T is a little bit too strong since it forbid you having overlapping &mut T, *const T is a little bit too loose since it allows T "outlives" it.
What we could have is a new kind of pointer type is that, let's call it &'a k#live T, pointed T must be alive for 'a, but doesn't guarantee anything else.
(Well, obviously, I haven't think through how would this affect borrow checker (yet).)
All the little boats I have seen do have a hole in the middle. You have to be able to drain water out of them. As far as I know big boats have hole in the middle too, how else would you scuttle them?
TBF I don't exactly understand what you mean here. (And your edit didn't make it better.) You need to explain why introduce *'a const when it's equivalent to &'a. So I assumed that you need something in between &'a T and *const T. The exact syntax is just bikeshed.
I checked original blogpost, and it's quite clear that why they chose to use the current approach. struct Cipher actually owns an ffi::SSL_CIPHER, not borrowing one. But it's only valid for 'a since it relies on the OpenSSL object that created it being alive.
What I mean here is that when you think about it is that & has exactly the same properties that *'a const have. Meaning, some amongst others:
References/Points to an object of type T. Cannot modifty T. Points to the object for 'a lifetime. Cannot point/reference other object.
Well, if they are exactly the same, why introduce a new feature? There has to be some difference right? I guess the difference is that &'a T is non-owning, but *'a const might be owning?
I don't think you are correct.
But if you find out what are 'real' differencess between & and *'a const please to let me know. I would be really interested to learn that.
It can't be helped then. You claim some other did not interpret you words correctly, and you don't elaborate further. Are you expecting us reading you mind?
Come on now, it's you introduced *'a const. It's your duty to explain the necessity, not us!