UnsafeAliased: allow aliasing of mutable references

Add a type UnsafeAliased that acts on &mut in a similar way to how UnsafeCell acts on &: it opts-out of the aliasing guarantees.
However, &mut UnsafeAliased can still be mem::swaped, so this is not a free ticket for arbitrary aliasing of mutable references.
Abstractions built on top of UnsafeAliased must ensure proper encapsulation when handing such aliases references to clients (e.g. via pinning).
This type is then used in generator lowering, finally fixing #63818.
Thanks to @rust-lang/opsem for a bunch of useful feedback!
Rendered

That example doesn't even touch on any of the problems discussed in this RFC. For instance, there are no mutable references.

&mut MaybeUninit very much implies weaker validity rules for the pointee than &mut T

Hm, yeah... however the aliasing and dereferenceable rules are still in full effect on &mut MaybeUninit<T> and that's what this RFC is call about.
I tried to clarify this in the RFC text.

So, I definitely feel like UnsafeAliased isn't that great of a name, but for the primary reason that I think that a good unsafe API would have a safe counterpart, which here would just be called Aliased.
And when I think over and over again about what that kind of API would look like, I keep coming back to the same conclusion: isn't that just RefCell? I mean, obviously, they're not the same. But they feel the same in the sense that RefCell is accomplishing the same thing. Here, our data is inside the cell and the pointer is an Option<Ref<T>>. Obviously, it doesn't work this way, but this line of reasoning makes it feel weird to simply refer to the value as "aliased," even though that's the name of the optimisation (or rather, lack thereof) that gets applied.
Like, the confusion, I think, is the fact that "aliased" implies that the issue is someone else having a reference to the value, when the real issue is that the value itself cannot be referenced safely. So, in the first example given, the issue isn't that we've got the reference ptr_to_data, but rather the fact that data thinks it owns its value when it's lent its data to someone else.
I tried a bit to sketch this safe Aliased API, but I couldn't wrap my head around the details. Although the terminology that made sense to me was to consider it a "Slot," since the value could be "moved" out of its slot and has to be "moved" back into it before the slot can be used again. Internally, this would just be accomplished via noalias, but a term like UnsafeSlot to me says something along the lines of, I can take the value out of the slot (get a pointer to it), but in order to use the value again, I must put it back (relinquish borrow). This will solve some of the confusion around UB with multiple aliases (you can't have multiple aliases, it's just that any actions done around the value can't be assumed to be of something other than the value itself, since one of them might be "putting it back in").
I had a rough time properly formulating this since, although noalias is a simple optimisation, the actual way it breaks the borrow mechanics are hard to describe. I probably did a terrible job, but maybe it helps improve the way this is explained.

So, I definitely feel like UnsafeAliased isn't that great of a name, but for the primary reason that I think that a good unsafe API would have a safe counterpart, which here would just be called Aliased.

A safe counterpart would be some Pin-based construction that allows self-referential pointers. That's why UnsafePinned is a proposed alternative. But I don't think that's necessarily a good name since there might be uses of this that do not involve pinning.
I also think UnsafeCell is not a great name, since it says basically nothing about what is actually happening. (That's also why I don't like "slot" at all. "slot" and "cell" aren't even obviously referring to different concepts; UnsafeSlot would be just as good a name for our interior mutability primitive as UnsafeCell.) UnsafeSharedMutable would be a lot better. So then maybe this one here should be UnsafeMutableAliased?

Like, the confusion, I think, is the fact that "aliased" implies that the issue is someone else having a reference to the value, when the real issue is that the value itself cannot be referenced safely.

I don't understand the distinction you are making between a reference existing to the value vs the value being referenced.

the issue isn't that we've got the reference ptr_to_data, but rather the fact that data thinks it owns its value when it's lent its data to someone else

So... UnsafeMaybeBorrowed?

A safe counterpart would be some Pin-based construction that allows self-referential pointers. That's why UnsafePinned is a proposed alternative. But I don't think that's necessarily a good name since there might be uses of this that do not involve pinning.

I mean, even such construction would be incomplete, TBQH. In the second example given, for example, data is accessed without first "dropping" the borrowed pointer, although I feel like such semantics would be desired for a similar unsafe construction. The mutability is precisely what requires this, which is why UnsafeCell doesn't suffice.

I also think UnsafeCell is not a great name, since it says basically nothing about what is actually happening. (That's also why I don't like "slot" at all. "slot" and "cell" aren't even obviously referring to different concepts; UnsafeSlot would be just as good a name for our interior mutability primitive as UnsafeCell.) UnsafeSharedMutable would be a lot better. So then maybe this one here should be UnsafeMutableAliased?

I sympathise with the concept of "cell" being a horrible name, although what I like about it is that it has actually two names: Cell, and "interior mutability." While Cell isn't the safe counterpart for UnsafeCell, it's the simplest one, and without Copy semantics you need to branch into more complicated abstractions like RefCell, Mutex, etc.
In terms of the "second" name here, what we're offering is effectively an alternative to &own references or &move references via an unsafe API. What we're doing is effectively an owning reference, since simple self-referentiality can be accomplished without the need for these unsafe-aliasing features.

I don't understand the distinction you are making between a reference existing to the value vs the value being referenced.
In terms of ownership, ptr_to_data has exclusive control over the value whereas data does not. So, if someone accesses the value via data, they're technically violating those ownership guarantees, since ptr_to_data is in control. So, effectively, obtaining a mutable reference to data has to come with the unsafe assertion that it actually does own its own data, and no mutable references to the data exist elsewhere. This also comes with a compile-time indication that operations on the newly-created reference can't be reordered with respect to other mutations, since any one of them could be the one that actually owned the data beforehand.

So... UnsafeMaybeBorrowed?
One other term I thought of was "disowned" since data is effectively no longer in control of its own ownership. This also closer resembles the other versions of this feature which were proposed, like references which actually move values.

Usage which can be made sound without UnsafeCell semantics are quite rare2

That's wrong. I am not aware of a single usage that needs UnsafeCell semantics. The current implementation of the Unpin hack does not have UnsafeCell semantics, and Miri is perfectly happy with self-referential generators and async fn and all sorts of other pinning shenanigans.

UnsafeAliased<T>  is not a good naming.
AlreadyBorrowed<T> / ConsiderBorrowed<T> is much better name

@clarfonthey

I mean, even such construction would be incomplete, TBQH. In the second example given, for example, data is accessed without first "dropping" the borrowed pointer, and this would be required if there were an actual mutable reference to the data.

ptr_to_data to a raw pointer, not a reference, so it doesn't have to be "dropped". And conceptually even if it was a reference, this example would be fine -- the lifetime of the reference ends after the write(42). Generators (and by extension async fn) will generate code that does exactly that. The example matches the following generator:
let mut data = 0;
let ptr_to_data = &mut data;
yield;
*ptr_to_data = 42;
println!("{}", data);

The mutability is precisely what requires this extra construct; self-referentiality on its own isn't enough.

This is trivially true in the sense that if everything is read-only then there are no aliasing violations. Self-referential webs of shared references can be created in safe code.
But for better or worse, we need self-referential data with mutable references, e.g. to support the Future::poll API.
Maybe you want to say that UnsafeAliased is an incomplete name since "aliased" is fine, we allow aliasing all the time via shared references? I agree. It should be UnsafeAliasedWithMutableReference. That's a bit too long though...

I sympathise with the concept of "cell" being a horrible name, although what I like about it is that it has actually two names: Cell, and "interior mutability." While Cell isn't the safe counterpart for UnsafeCell, it's the simplest one, and without Copy semantics you need to branch into more complicated abstractions like RefCell, Mutex, etc.
In terms of the "second" name here, what we're offering is effectively an alternative to https://github.com/rust-lang/rfcs/issues/998 or https://github.com/rust-lang/rfcs/pull/1646 via an unsafe API. What we're doing is effectively an owning reference, since simple self-referentiality can be accomplished without the need for these unsafe-aliasing features.

Insofar as "interior  mutability" is a (terrible) name for "mutability behind shared references", the corresponding thing for UnsafeAliased would be "sharing despite mutable references". I don't think there is any relation to &own/&move.

In terms of ownership, ptr_to_data has exclusive control over the value whereas data does not. So, if someone accesses the value via data, they're technically violating those ownership guarantees, since ptr_to_data is in control. So, effectively, obtaining a mutable reference to data has to come with the unsafe assertion that it actually does own its own data, and no mutable references to the data exist elsewhere. This also comes with a compile-time indication that operations on the newly-created reference can't be reordered with respect to other mutations, since any one of them could be the one that actually owned the data beforehand.

Nobody is creating a mutable reference to data though. People are creating mutable references to S, of which data is a field, and we somehow have to indicate that this should not be considered as also making the usual "mutable reference promises" for data.

One other term I thought of was "disowned" since data is effectively no longer in control of its own ownership. This also closer resembles the other versions of this feature which were proposed, like references which actually move values.

It would be MaybeDisowned though -- some of the time the field does have all the ownership. In fact when you have a regular &mut S you still get all the ownership for all the fields -- otherwise mem::swap would be unsound. Pin<&mut S> indeed does not have ownership of the data field when the state is currently 1.

The other potential name which I'm partial to is UnsafePinCell. This leans more into naming based on usage instead of effect, as well as leaning on PhantomPinned (which could be potentially defined as UnsafePinCell<()>). This becomes more interesting of a naming direction if a) we commit to infectious cell semantics and b) provide a PhantomMut as UnsafeCell<()> / Freeze optout.

I think we should avoid "cell", but I like UnsafePinned and it is an alternative mentioned in the RFC. If we impl !Unpin for UnsafePinned, we could define PhantomPinned as UnsafePinCell and that would be backwards compatible. We could add a new unsafe trait that detects UnsafePinned the way Freeze detects UnsafeCell (called Unique in the RFC but I hope there are better names), and switch codegen over to using that to opt-out of noalias for &mut, and that would be backwards compatible except for code that does impl !Unpin (which is unstable).
Without infectious cell semantics, switching Miri over to Unique would not be backwards compatible, but that's okay.
So yeah I really like the idea of re-defining PhantomPinned as UnsafePinned<()> (no matter the name we end up picking).

SO something I don't like about this RFC is that it requires tracking the provenance of a reference through all code you control, in case that reference somehow aliases.
My guess is that it's only a matter of time until someone uses this wrong internally, but in a important crate like arc_swap (as an example--they don't need it I think), and that relies on the current optimization behavior of the compiler at whatever time this happens.  If you consider one person writing unsafe code in one sitting it's possible to get this right, but if given to a team or maintained over a long period of time, I feel like this asymptotically approaches very hard to spot problems.
Unfortunately I absolutely don't have a better suggestion here.  I'd offer one if I could.  The drawbacks section does acknowledge this, but the core crate concern makes me flinch a bit.  I don't want to be the one who finds miscompilation because of something that's a 5-times dependency and we decided to upgrade Rust.  I'm not sure how we'd even track that back to the problem.  Unfortunately something like this is probably necessary.  I just don't like what appears to me to be a major incident waiting to happen.  Imagine if this took out tokio.

Imagine if this took out tokio.

It's interesting that you mention Tokio. I'm one of the maintainers of Tokio. Tokio does have unsafe code that relies on the so-called Unpin hack to write custom self-referential futures (well, mostly futures with intrusive linked lists). In fact, I suspect that Tokio is the single largest user of the Unpin hack on crates.io.
We justify this because it lets us eliminate a bunch of allocations, and I have been monitoring the state of these issues for a very long time, and I have always been ready to replace the Unpin hack with a proper solution once one is stabilized. For example, see this gist that I wrote back in Jan 2021 advocating for pretty much the solution proposed here.

@Darksonn
I'm not saying Tokio itself will get this wrong.  Tokio also has much less dependencies than I expected.  I used it as the example because it is a core, popular crate that would be disastrous to many people if it broke.  In terms of me trusting Tokio itself, I do.
For the sake of not conflating me picking on a specific crate, let's just say that there is some popular crate x with many dependencies.  Consider:

T+0: big team incorporated or whatever depends on x.
whenever this rfc is stable: some dependency of x uses this rfc wrong.
6 months or more down the line: Rustc starts getting more aggressive in a way that breaks the broken dependency of x.  In the meantime, x has done a major release and no longer supports the version we started with, and none of their devs are interested in trying to refactor the older version.
1 year after this rfc: big team just upgrades the Rust compiler.  Their software now crashes in weird "wait is this actually C++" heisenbug ways.

We have team members who do reverse engineering of pdbs and the like even, all of whom know Rust at this point.  I suppose Miri can in some cases help track this back.  I will admit that I am not up to date on the formal verification tooling, so maybe this is easy.  But getting as far as "it's a miscompilation" would take days with my current knowledge and getting as far as "from this dependency" would take...infinite time?  I'm not sure how we would take that last step even if we figured out the first one.
Maybe I'm being too paranoid.  I expect this to land anyway because clearly the current state of affairs is worse than this hypothetical scenario.  But I did at least want to come out of my cave to represent this as someone who has done and code reviewed unsafe, taught Rust to others, etc. in the context of a medium-sized corp who isn't interested in Rust because Rust.  Our Rust upgrades have gone 100% smoothly even over a year ago when we had to use nightly (we no longer use nightly; long story, tldr rocket for initial POC of adoption).  I don't want to lose that, at least in so much as current Rust unsafe hasn't lead to a catastrophe for the ecosystem yet.

@ahicks92 I think your concerns are very valid, but this might be the wrong RFC to express them on. You seem to be concerned about having (more or less) strict aliasing rules in general. As in, rejecting this RFC won't help with your concern at all -- it will only make it worse since some code (like self-referential generators) becomes even harder to write!
Eventually we'll have to RFC an aliasing model, and decide what exactly the rules are that &mut and & follow throughout the program. That is where your concern applies. But right now, Rust had an informal idea of "we have aliasing restrictions" since 1.0, and self-referential generators have violated those rules since they exist (even the fairly lax LLVM noalias rules, let alone the much more strict Stacked Borrows rules), and this RFC provides a way to fix that.

Our Rust upgrades have gone 100% smoothly even over a year ago when we had to use nightly (we no longer use nightly; long story, tldr rocket for initial POC of adoption). I don't want to lose that, at least in so much as current Rust unsafe hasn't lead to a catastrophe for the ecosystem yet.

That sounds like you are concerned about the upgrade path if this lands. I have recently edited that section -- I think we have an upgrade plan that ensures that code which is LVM-UB-free today will remain LLVM-UB-free. In other words, people running Miri might see failures where there were none before, but this change itself will not introduce any new chances of miscompilation. In fact it will remove the potential miscompilations that currently come with an entirely safe impl Unpin.

I was trying to make a more specific point, but now I am re-learning that Rust aliasing even in unsafe is currently somewhat ill-defined, and I suppose that you're right that what I'm saying is isomorphic to discussing whether Rust should allow aliasing everywhere.  Looking at this again I do see that there are other foot-guns I just haven't encountered.  That wasn't my goal, and in fact I think Rust probably should disallow aliasing.  Given that we were apparently having different conversations, carry on; apparently I didn't understand things I thought I understood.

What is the difference between this and UnsafeCell without UnsafeCell::get_mut?

The RFC talks a lot about how this is different from UnsafeCell, from the initial paragraph to the overview here.

Attention:

UnsafeCell without UnsafeCell::get_mut

I am not asking if there is a semantic difference between the two.

That's entirely analogous to how UnsafeCell lets the compiler know that shared references to this field might undergo mutation.

What I mean is, is UnsafeCell::get_mut the only difference in implementation between the two.

What I mean is, is UnsafeCell::get_mut the only difference in implementation between the two.

maybe in the library but not in the compiler.

@823984418 They differ in their lang attributes:

UnsafeAliased uses #[lang = "unsafe_aliased"]
UnsafeCell uses #[lang = "unsafe_cell"]

This will make the computer treat them differently in the ways described in the rfc.

Of course, using language item is one way to implement it, but what I want to ask is whether encapsulating UnsafeCell and remove UnsafeCell::get_mut is another way.
Just like:
use std::cell::UnsafeCell;

struct UnsafeAliased<T: ?Sized> {
    value: UnsafeCell<T>,
}

impl<T: ?Sized> UnsafeAliased<T> {

    // all others

    // delete it
    // pub fn get_mut(&mut self) -> &mut T {
    //     self.value.get_mut()
    // }
}

@823984418
It may be helpful to think of these types as weird syntax for attributes, as an analogy (emphasis analogy, though).  For one thing the type lets the attribute "follow" the value around, which is why it's not just an attribute.
Like, Arc<UnsafeCell<T>> is Arc<#[unsafe_cell]T>.
The methods are relevant in so much as you get an API to drive it correctly, which is one reason it can't ever be an attribute, but the methods aren't the point of having either.

(NOT A CONTRIBUTION)
I think this is a great and sensible solution to the problem that self-referential future bodies raised, and in retrospect an obviously missing API addition. I'm curious what other library improvements might be enabled by it in the future - e.g. maybe using this instead of raw pointers for intrusive data structures will have some benefit.
As to the name, I think the current name is fine. If anything, it reveals that UnsafeCell was sort of misnamed, and should maybe have been called something like UnsafeMutable instead. C'est la vie.

"borrowed" is somewhat ambiguous here, since borrowing usually refers to references in Rust, but generally speaking with UnsafeAliased, the aliasing pointers will be raw pointers.
I think UnsafePinned expresses well the idea that "there are other pointers pointing here" and points to Pin as a potential way to achieve a safe abstraction, which is why I increasingly gravitate to that name. Just to get a read of the room -- can we get a quick vote? :+1: for UnsafePinned, :-1: for UnsafeAliased. (I don't plan to do language design by vote/committee, but I am curious how people generally feel about these two names.)

Wait, for a struct T that includes UnsafeXXX, is it sufficient to remove no_alias  for Pin<&mut T>?

Wait, for a struct T that includes UnsafeXXX, is it sufficient to remove no_alias for Pin<&mut T>?

No it is not, because get_mut_unchecked is commonly used by unsafe code implementing pinned types, and pinned-projections even safely wrap map_unchecked into a safe function. Both of these expose the underlying &mut T

because get_mut_unchecked is commonly used by unsafe code implementing pinned types,

I believe it has no impact because no_alias is only added during parameter passing, so even if &mut T obtained internally within the function, it will not affect alias calculate.

Basically, even an &mut T may be pinned -- inside unsafe code that carefully ensures that the pinning invariant is not violated.

If someone doesn't need the semantics of Pin, then they probably won't violate the alias rules as a result.

In fact, Rust left out so many no_alias that the only way to get them was to pass them again as parameters.
And this will only take effect within the called function, so it will not generate no_alias out of thin air due to map_unchecked_mut.

Perhaps it does have a certain impact, and some unsafe code writers may believe that Pin is only an external requirement and directly passes &mut T internally, or is passed in unintentional closure usage. Therefore, strengthening this requirement may indeed have a negative impact.

I believe it has no impact because no_alias is only added during parameter passing, so even if &mut T obtained internally within the function, it will not affect alias calculate.

In the aliasing models proposed for Rust so far (Stacked Borrows and Tree Borrows), reference arguments have consequences even after the callee returns. Remember that LLVM noalias is not our aliasing model, it is a lower bound for the restrictions we put on code -- we almost certainly want tighter rules than that, to allow more Rust-specific optimizations.

As a supplement:
impl <T: ?Sized> UnsafePinned<T> {
    pub fn get_pinned_mut(self: Pin<Self>) -> *mut T {

    }
}

In this way, unsafe code writers can work completely under the package of Pin, and we can completely bypass &mut T.

Under those models, even map_unchecked_mut is a problem.

As for the acquisition of members, I believe in addr_of/addr_of_mut can bypass it (if we ignore the cost).

That would have worked if the closure map_unchecked_mut was declared to take *mut T (and return *mut U). Alas, it takes &mut T, so this is not an option any more. addr_of_mut only helps when there is never a reference anywhere, but the closure's signature requires reference types.

If we could redesign Pin, I think it would be a good idea, but too many people have already written code based on the current way...

One possible solution is to mark map_unchecked_mut as deprecated and launch a pair of macros specifically designed to retrieve members, giving users optional switches to enable all remove no_alias rules and considering the default activation in the next version. However, the destructive nature of doing so still needs to be discussed.

I believe that using the Rust alias rule can be explained, while using the LLVM alias rule is currently feasible. All we need to do is evaluate the impact of this change on downstream.

This RFC is designed to resolve alias conflicts, so the restriction of the Rust alias rule on map_unchecked_mut  is part of our discussion, not the restriction.

PhantomPinned can keep the current alias rules, that is, remove no_alias  for all references, and it can continue to work. We independently add the Pin - UnsafePined interface to provide new and more restrictive interfaces to gradually move existing implementations.

My design is:

Add a auto trait NoAnyPinned  to replace the current effect of Unpin.
Retain current Unpin but only remove no_alias in Pin.
Impl !Unpin for UnsafePined.
Remove no_alias of &T where T: !NoAnyPinned , &mut T where T: !NoAnyPinned , and Pin<&mut T> where T: !Unpin.

I'm not sure I like UnsafePinned better.  Being pinned is sort of an implicit requirement that you will likely always have with such structs but not the core of it.
In C it's easy to explain the strict aliasing rules.  Don't make these kinds of pointer casts or else.  Rust doesn't have something that can be understood quickly, or code reviewed, or anything like that.  I am not saying let's debate removing aliasing, just that I see this as a doc problem.  There's nothing I can run quickly in my head when looking at code that might alias other than the quite formal model of stacked/tree borrows.  Until that's resolved I don't think naming matters.  To go back to my "on a team" philosophy, I've been doing Rust for a very long time and don't fully have mental tools for this as it turns out.  There's nothing I could teach a coworker in an hour like I could with C strict aliasing.  Whether it's UnsafeAliased or UnsafePinned or whatever doesn't matter to that problem.  Until that problem is resolved these kinds of RFCs will probably have contributions like mine where the reader thinks they understand but doesn't, and so will code.

From the perspective of someone who writes unsafe, self ref code, but not in the space that Pin is useful in, I don't think using the Pin naming here would be great.
A perennial source of confusion around Pin is that it sounds like Pin has special language behavior (and there are additional subtle safety invariants that Pin upholds for you that you can't on your own), but that's not actually the case: Pin is basically just a library type whose safety derives from its API shape. And as such, it's only useful in some cases of self-ref things. "Pin is not a language level magical type[^1]" is a very useful thing to be able to explain, and reusing the terminology muddies that IMO.
"You don't have to do Pin things if you don't need a Pin-like API" is a rather clean bit of advice, and the low level type can be kept separate from the Pin universe of types.
[^1]: Currently Unpin kind of is due to the hack being fixed by this RFC, but that's something that we shouldn't model this after.

Rust's alias rules are very simple:

In the aliasing models proposed for Rust so far (Stacked Borrows and Tree Borrows)

It is self-evident that the former must be followed during runtime.
Now we are only discussing the latter, which is ”Is my borrowing the borrowing of my members?”.

Generally said, my borrowing is my member's borrowing.
UnsafeCell said, my shared borrowing is not my member's shared borrowing.
UnsafeAliased said, my borrowing is not my member's borrowing.

But I think UnsafeAliased is too loose, so I think UnsafePinned may be a more suitable choice.

UnsafePinned said, my pinned borrowing is not my member's borrowing.

Consider that your reply is written once but read by many people; if you can spend 15min to make it more clear and that saves 100 readers 1min each, you performed a great timesave overall!

I heard Rust claim that the community is open, but I doubt this now. If you think I'm wrong, you can directly call me a clown, but you shouldn't accuse me of wasting others' time.

I think your types don't need UnsafeAliased though? E.g. yoke needs MaybeDangling, and I think that is all it needs. Maybe you have other unsafe code in mind though. :)

I think there's some open stuff about whether we need it if we expose cart access. But yeah, it's not clear. Either way, the Pin universe is somewhat complicated and I'm not sure if tying a low level "annotation" type like this to a complex library is the best call; I think this type is very well motivated by Pin but it would be nice if it stood apart from it in presentation and documentation (with examples that build on Pin, of course)

@Manishearth
If we disregard self-referential types, why is this even necessary?  Isn't it pretty much always possible to obey the aliasing rules in the other cases, given that the pointers (mostly) live on the stack?  I suppose you could hand one out to C and get it back async but I'd think in that case you'd require the type to be pinned.
(I'm sure there's a good use case, I just can't think what it is)

If we disregard self-referential types, why is this even necessary?

Not all self-referential types care about Pin. Pin is but one way to do self-references; I maintain a self-referential crate that works differently (I'm not 100% sure if it would need this abstraction, but I think it highly depends on the exact APIs I expose).

Do you mean yoke? Yoke isn't self-referential in the same sense as self-referential generators. It's more an instance of existential lifetimes: one field borrows from something stored behind a pointer indirection in another field. No pointer actually points to inside its own struct. Right?

Yes, that is correct. Yoke is probably fine here. But I think there are other non-pin-using use cases in the space, I could be wrong.

@Manishearth
Been thinking on and off since yesterday.  I can think of two use cases for this:

Rust types which wish to be self-referential for whatever reason.  If these aren't pinned by the time they reach safe code, they're probably unsound.
Rust types which are talking to a C library.  If these aren't pinned by the time they reach safe code, they're probably also unsound since the C library presumably owns a pointer.

The third use case that comes to mind is some sort of C self-referential struct that only ever exists in unsafe code (for which the author may just not bother pinning) but in that case I'd think just doing everything with raw pointers would be enough.
Or put another way: in purely unsafe code I can't figure out why you'd need this, and if it's passed to safe code and not pinned then you can move it around and the world explodes.

If these aren't pinned by the time they reach safe code, they're probably unsound.

This displays exactly the kind of conflation I'd like to avoid: pinning is not the only way to do self references, and the stdlib pin type is not special (but this trait is).
People can make Pin-like APIs that don't use Pin, or use things like StableDeref (though that strategy generally avoids the problems this rfc is attempting to solve). There is an ecosystem of self referential crates outside the Pin universe. Many have soundness issues but it's usually because of nuanced UB stuff that Pin doesn't help with.

StableDeref is exceedingly dangerous because its impls presuppose the answer to https://github.com/rust-lang/unsafe-code-guidelines/issues/326 and I would prefer to factor that discussion out of this issue because you do not need &mut to cause problems.
UB in spite of a safety comment justified by StableDeref
fn main() {
    let t = Thing::new();
    oof(t);
}

struct Thing {
    owner: Box<u8>,
    // The type guarantees that this pointer aliases with owner
    sharer: *const u8,
}

impl Thing {
    fn new() -> Thing {
        let b = Box::new(0u8);
        Thing {
            sharer: &*b,
            owner: b,
        }
    }

    fn get(&self) -> u8 {
        // SAFETY: This deref is safe according to the type invariant and Box<T>: StableDeref
        unsafe {
            *self.sharer
        }
    }
}

fn oof(x: Thing) {
    // Field retagging applies LLVM noalias to owner, making it UB to do the read through sharer
    let _ = x.get();
}

StableDeref is exceedingly dangerous because its impls presuppose the answer to rust-lang/unsafe-code-guidelines#326 and I would prefer to factor that discussion out of this issue because you do not need &mut to cause problems.

Yes, however that discussion is not helped by throwing Pin into the mix.
As much as you want StableDeref of this discussion, I also want Pin out of those discussions; which is why I'm arguing against conflating "self referential types" with "pinning" and having this type be clear about what it does without invoking pinning, which is a term of art in Rust for a specific self-ref strategy. I mentioned StableDeref as an example but one can potentially have other ways of achieving these things.

Or put another way: in purely unsafe code I can't figure out why you'd need [UnsafeAliased]

In short: because unsafe code doesn't get to just "opt out" of the safe rules. You can suspend any safety invariants (cannot[^v] validity invariants), but doing so is fraught with subtle unsafety (potential UB) because how eagerly safety invariants get relied on. This is extra true for invariants imposed by the language, such as the borrow rules[^r].
[^v]: Um, actually, because the proposed rules are operational, you could "just" avoid any operations which assert validity. Simplifying, an axiomatic invariant just must always be true, whereas an operational "invariant" is "only" required to be true during specific operations. But, see the main point.
[^r]: With the normal split of validity/safety, "borrow validity" actually imho falls somewhere in-between, especially once you include unstable hacks like the dropck eyepatch. Things like dereferencability fall more on the validity side, but not cleanly (e.g. r as *const _ currently asserts such, but addr_of!(*r) soon won't), whereas aliasing falls more on the safety side, but not cleanly (e.g. lifetime validity may be implicitly cut short non-lexically by some conflicting access, except if the reference carrying the lifetime was a function argument, in which case the protector makes attempting such UB).

in that case I'd think just doing everything with raw pointers would be enough.

The problem with such is in two parts:

Even in pervasively unsafe Rust (e.g. C with Rust syntax), encapsulating portions of unsafety is still desirable, in order to manage the amount of active unsafety as well as mitigate the additional avenues for unsafety introduced by using Rust; and
Just doing everything with raw pointers is extremely limiting and effectively nontenable because of the eager implicit introduction of references by Rust syntax. Even with addr_of!, you can't guarantee that addr_of!((*ptr).field)` doesn't involve a deref coercion (creation of a reference), and there's no (reasonable[^ext]) way to get method syntax with raw pointers.

[^ext]: Um, actually: you could use extension traits to add self-taking methods onto pointer types.
Overly reductive: many people want it to be possible to write "C with traits" in Rust (c.f. how you can write "C with classes" in C++), which requires exposure to (implicit) references (and retags thereof). (And IMHO is necessary to actually write "C with Rust syntax," otherwise you're just getting "C with Rust pitfalls" if you can't ever use references/methods/traits for CRust types.)
Keep in mind that C-like Rust isn't restricted to FFI to other languages (i.e. over a C-compatible API[^c]), it also includes authoring C-like patterns exclusively within Rust, both as part of authoring an unsafe C-like API and/or a safe Rust API. Doing so is both far more difficult and requires introducing more indirection than would be strictly necessary; addition RFCs like this one (or MaybeDangling or extern type) are about addressing this need. Yes, you can do anything (including extending what safe Rust can express) with alloc/dealloc, raw pointers, and manual layout calculations. It shouldn't be necessary to go through such, though.
[^c]: Even if not C-typical (e.g. autogenerated by a tool such as cxx, diplomat, or abi_stable) the API that crosses the FFI boundary better be C-compatible if it is to have any hope of being ABI-compatible.

If these aren't pinned by the time they reach safe code, they're probably unsound.

This displays exactly the kind of conflation I'd like to avoid: pinning is not the only way to do self references, and the stdlib pin type is not special (but this trait is).

So while Pin isn't special, the concept of pinning is. This is the safety reasoning concept which the library type Pin introduced. Without pinning as a concept, moving a type in memory is always sound, and a take_mut-for-pointers would only need a prerequisite of read/write provenance. With pinning as a concept, take_mut-for-pointers additionally needs a prerequisite that the pointee is not in a pinned typestate.
While I agree entirely both that pinning as a concept de-facto existed before Pin and that that the concept and the type are somewhat unfortunately conflated despite being separate concepts, the fact that it's possible to achieve the concept of pinning without Pin does not mean that doing so does not utilize pinning.
To wit:

If you duplicate the API of Pin exactly but don't call it Pin, the pointee may still soundly enter a pinned typestate.
If you yoke to a Cart: StableDeref + Deref[^yoke], the Cart::Target is put into a pinned typestate[^ts] (even if the type normally doesn't have one, i.e. could soundly be  Unpin).

Pin isn't magic. But Unpin is still special — even with Unique taking on the language validity magic[^unique] — because it captures the concept of "(potentially) has a (safely reachable) pinned typestate."
[^yoke]: I use yoke here as a stand-in for any stable-deref-based self-referentiallity.
[^ts]: Um, actually: while calling this a pinned typestate is one way of viewing the effects of yoking, a less extreme way might be to talk about the borrow state being still tagged below the tag of the stable-deref pointer, the same way that happens with normal well-nested borrowing without mentioning any sort of pinned typestate... but this is essentially exactly what the pinned typestate captures — that there exist extant borrows outside of the normal well-nested borrow paradigm. You could even describe the difference between a unique Rc and a shared Rc as whether the reference counts are pinned — and relevantly, this pinning relevant to aliasing UnsafeCell, not MaybeAliased.
[^unique]: Unpin is an autotrait, and autotraits are built-in magic, at least until user code is permitted to define autotraits.
It doesn't particularly matter whether you're using Pin or some other construction; if you nominally have write access to some instance but to mem::swap it with another instance would cause a soundness issue, that instance is effectively pinned. Pin is sufficient for describing an API working with such an instance, but is not necessary; it can't be, as a purely library type, since its API can be replicated.

The [StableDeref] trait doesn't do anything, it's just a declaration of assumptions.

The same as any marker trait; it captures/refines behavior exposed by other traits. But yes, StableDeref for Box<_> is relying on a currently nonprovided property that "the result of calling deref() is valid for the lifetime of the object, not just the lifetime of the borrow, and that the deref is valid even if the object is moved."
StableDeref is relevant w.r.t. the MaybeDangling RFC, as StableDeref replacing mentions of "moved" with "relocated" would then make it (tenuously) sound and capture the property it intends to, since moving MaybeDangling<P<T>> (or otherwise doing an untyped copy of P<T>) relocates the stable-deref object without potentially retagging it, thus without potentially invalidating any derived references.
StableDeref and thusly derived self-borrowing patterns are not relevant w.r.t. this RFC for MaybeAliased (except maybe w.r.t. naming).
What we need IMHO is some common agreed upon way to differentiate between "self-referentiallity before indirection" (i.e. async/generators/(semi)coroutines, usually requires UnsafeAliased) and "self-referentiallity after indirection" (i.e. StableDeref-based, usually requires MaybeDangling). I've typically seen "self-referencing" used for the former, more specific set, and "self-borrowing" for the latter, more inclusive superset, but the difference between the two terms is at best terribly subtle and not well recognized. (Referencing and borrowing are generally used interchangeably.)

TL;DR of below: new color option: UnsafeCell as UnsafeMutable, this RFC's type as UnsafeAliasable, and autotrait as FreezeMut.
Potential paint for the bikeshed
Also, -1 on MaybeBorrowed variants on naming: existing Rust naming sets the precedent that "borrow" without "mut" means shared-borrow (&), whereas MaybeAliased is about unique-borrow (&mut).
I'm actually somewhat partial to the idea to rename UnsafeCell to get matching names between it and MaybeAliased, e.g. to MaybeMutable. But I don't know how well the maybe fits here; while MaybeUninit and MaybeAliased are clearly maybe uninit/aliased based on the consumer, UnsafeCell is mutable, even if the consumer doesn't mutate it... it's saying "maybe capability" instead of "maybe state".
(Aside: if we wanted, that could permit MaybeMutable to not have the deallocable effects that UnsafeCell does, but this would of course have the same pitfalls that led UnsafeCell to grow that semantic.)
Another alternative name is to use Unsafe instead of Maybe, e.g. UnsafeMutable and UnsafeAliasable. I think that sufficiently communicates that the field may be mutated/aliased with the use of unsafe code, with the unsafe author on the hook for making the API doing so sound (but the type for making so valid).
It does not particularly help for naming these types that the exact impact of what they do depends on the open question to how precise/infectious their ospem effects are. But to reiterate, those effects are at their core (caveat: not using a specific definition for what the retags mean):

UnsafeCell turns a shared-immutable retag over T (T: Freeze) into a shared-mutable retag (T: ?Freeze).
MaybeAliased turns a unique-mutable retag over T (T: Unique) into a shared-mutable retag (T: ?Unique).

This also makes me somewhat partial to FreezeMut as the name for the unsafe autotrait detecting MaybeAliased: T: Freeze corresponds to the property that &T assumes that the bytes of T can't be mutated by anyone else, and T: FreezeMut to that &mut T assumes the bytes of T can't be mutated by anyone else. Though as internal/private implementation details of rustc, it's not particularly important. (But I do think these names could reasonably be exposed.)

(NOT A CONTRIBUTION)
At first, I was unsure that it's really true that any object needs to be in the pinned typestate to have valid aliased mutable references: are they really identical? There's really no other type state that any aliased mutable reference could use to be valid? But I thought about it, and I think it's true: the pinned type state is exactly that you can't invalidate the memory, which is exactly what you can't do if the memory is aliased.
@CAD97 is right that the name UnsafeCell and "pinned typestate" both reflect their design history: we invented Cell and Pin for practical reasons and then evolved APIs and formalisms to deal with them in the memory mode, rather than starting with relaxing our constraints in our memory model from first principles. So in that sense UnsafePinned is more consistent with UnsafeCell, in continuing to reflect that design origin.
The question of the name then is whether you want to keep that approach that UnsafeCell has used for consistency or whether you think it was a mistake. One nice thing about continuing that approach is that (especially if Freeze is exposed) there's a symmetry between UnsafeCell/Freeze/Cell-types and UnsafePinned/Unpin/Pin-pointers. One problem is that the Pin API already feels overwhelming for many users, and adding a new type that is by-name "part of the Pin API" may add to the confusion. As I wrote in my last comment, I sort of just think UnsafeMutable would have been a better name for UnsafeCell, and having these two emphasize their symmetry more than their connection to the safe APIs built on them may be more appealing.

The relationship with MaybeDangling, yoke and stable-de ref has me a bit more confounded. It seems wrong neither MaybeDangling nor UnsafeAliased are strictly more powerful than the other. MaybeDangling removes both dereferenceable and noalias, but only to 1 level of pointers, whereas UnsafeAliased removed noalias to arbitrary depth. It seems to me that stablederef actually only wants to remove noalias to a depth of 1, and doesn't actually need the value to dangle? I may be confused, but it seems like there's something wrong in the taxonomy here.

So while Pin isn't special, the concept of pinning is

Ah, this does convince me, I think if we're set on using "pinning" for this via the same kind of backformation @withoutboats talks about, I think that's fine, but I would say that we really really need to make sure we have good docs on this. But that kinda goes without saying.

I like the adjective pinned and we need an adjective for the concept.  I'm not sure that arguing that there are other ways is valuable, in the sense that they all presumably involve that concept.  The nouns seem less relevant; you can say that insert-noun provides/applies/adds-typestate/etc pinned.
@withoutboats
At the theoretical level you could do something like this, right?:
fn restore_alias(&mut self) -> {
    // Point a field at UnsafeAliased.
    // Stuff, being careful not to move the object.
}

I have no idea why anyone ever would and maybe it's UB to do that, but I think the actual statement at a theoretical level is that a type must be in the pinned typestate if safe code not under the author's control is going to touch it because the author could be careful that their safe code never moves it (maybe call this "dynamically unpinned"?).
@RalfJung
Is there an argument for UnsafeAliased to be !Unpin, and to require users to implement Unpin on their structs if they really do want to get around it?  This discussion so far implies that 99% of the time structs will need to be pinned.

There's really no other type state that any aliased mutable reference could use to be valid?

There's actually one difference between Pin and the "pinned typestate" worth calling out — Pin is only discharged by (being Unpin or) dropping the object, whereas a "pinned typestate" can be exited whenever. But this doesn't particularly matter; Pin describes the bound sufficient for working with any arbitrary pinned object, but specific objects may of course refine that bound tighter and discharge the "pinned typestate" sooner.
A TryUnpin providing fn(Pin<&mut self>) -> Option<&mut Self> would make that potential more self-evident, though not every object is able to easily determine if it is pinned.

I think the actual statement at a theoretical level is that a type must be in the pinned typestate if safe code not under the author's control is going to touch it because the author could be careful that their safe code never moves it

Typestate is shadow, "imaginary" state. If you as the author are required to be careful to never move the object (on pain of unsoundness), then the object is in a pinned typestate while that is true. The only difference w.r.t. safety is whether that change in typestate is captured into Rust's static type system or not.
You can make the distinction between "dynamic typestate" and "static typestate" based on whether the typestate gets reified into the static type system, but the typestate still exists either way. As far as terms go, I prefer distinguishing between "pinned" and "statically known to be pinned" instead of "dynamically pinned" and "pinned".

One nice thing [...] symmetry between UnsafeCell/Freeze/Cell-types and UnsafePinned/Unpin/Pin-pointers.

Except that this symmetry is already broken, because pinning has two autotraits, Unpin (safe, controls API) and Unique (unsafe, controls validity), whereas shared mutability only has the one (Freeze, unsafe, controls validity).

MaybeDangling removes both dereferenceable and noalias, but only to 1 level of pointers, whereas UnsafeAliased removed noalias to arbitrary depth. It seems to me that stablederef actually only wants to remove noalias to a depth of 1, and doesn't actually need the value to dangle?

on MaybeDangling
I'm not particularly fond of the name MaybeDangling either, since most uses of the type don't have the inner pointer dangle (until dropped); it's more like ManuallyDrop than MaybeUninit. Personally I'm fond of Inactive, Inert, or something along those lines.
But MaybeDangling and UnsafeAliased are both field-recursive in the same manner, just in different directions. MaybeDangling<P> removes dereferencable/noalias annotation from any fields of P (recursively) that would otherwise have them. UnsafeAliased<T> removes dereferencable/noalias annotation from any &mut U where any field of U (recursively) is UnsafeAliased<T>.
(Note: rustc+LLVM only puts dereferencable/noalias annotation on scalar or scalar pair function arguments, but Miri's model does so for all fields; the semantics shouldn't rely on unspecified layout/abi details.)
They achieve similar purposes, but their directionality is inverted between the two of them. You could in theory replace the need for UnsafeAliased<T> with using MaybeDangling<&mut T> (or even just *mut T) in Pin's API instead, but that's an impossibility because existing stable safe Pin<P<T>> APIs (e.g. as_mut) go through &mut T.
Given { cart: MaybeDangling<Box<T>>, yoke: MaybeDangling<&'static mut T> }, both parts need to maybe-dangle. The yoke needs to maybe-dangle because otherwise (passing the pair as a function argument and) dropping it would be UB (dereferencable on the yoke). The cart needs to maybe-dangle because otherwise (passing the pair as a function argument and) mutating through the yoke would be UB (noalias on the cart).

Further discussion w.r.t. MaybeDangling should live on that RFC rather than this one. But it certainly should be considered here that MaybeAliased<&mut T> does look like it would be saying the &mut T may alias other &mut, but that's not what's being said; what that actually says is that there might be aliasing extant &mut MaybeAliased<&mut T>.

Is there an argument for UnsafeAliased to be !Unpin

I fully expect that this would be the case, but it seems to be implicit in the current RFC. Namely, in the potential plan to make PhantomPinned = UnsafeAliased<()>, of course that would require UnsafeAliased to be !Unpin. But tbf I don't see that outright said anywhere in the RFC.

@Manishearth

People can make Pin-like APIs that don't use Pin, or use things like StableDeref (though that strategy generally avoids the problems this rfc is attempting to solve). There is an ecosystem of self referential crates outside the Pin universe. Many have soundness issues but it's usually because of nuanced UB stuff that Pin doesn't help with.

I don't now of a case where StableDeref is used where UnsafeAliased would be necessary. You are using "self-referential" in a more liberal way than me: to me, "self-referential" is a struct S where one field of S points to another field of S -- as in, directly to the field, not "to memory the field also points to". Such types are clearly non-movable, and that's why they pretty much always use Pin. yoke is not self-referential in this sense. yoke doesn't actually have any cycles in the pointer graph. So it's a fundamentally different situation.
@withoutboats

The question of the name then is whether you want to keep that approach that UnsafeCell has used for consistency or whether you think it was a mistake. One nice thing about continuing that approach is that (especially if Freeze is exposed) there's a symmetry between UnsafeCell/Freeze/Cell-types and UnsafePinned/Unpin/Pin-pointers.

Note that we can't use Unpin as the Freeze equivalent since Unpin is a safe trait. Also even if we expose Freeze we will do it in a way where unsafe impl Freeze for T is impossible -- we only want users to query the trait, not to "hide" UnsafeCell from the compiler.
But it looks like more and more people are becoming comfortable with the idea of calling this UnsafePinned.  Any good suggestions for how to call the trait that reflects "does not contain any UnsafePinned"?

You are using "self-referential" in a more liberal way than me: to me, "self-referential" is a struct S where one field of S points to another field of S -- as in, directly to the field, not "to memory the field also points to". Such types are clearly non-movable, and that's why they pretty much always use Pin. yoke is not self-referential in this sense. yoke doesn't actually have any cycles in the pointer graph. So it's a fundamentally different situation.

Tangent: This ‘not self-referential’ situation is still a very common case to need to discuss (with Rust beginners that try to use it, often in the form like struct S { foo: String, bar: &'foo str }), and as far as the borrow checker cares, it's identical to the ‘actually self-referential’ case (that is: it will fail with identical errors). I think it would be good for Rust discussions if there was a precise and unambiguous name for this case, if we're going to avoid using ‘self-referential’ to refer to it.

@kpreid I like the "self-borrowed" that @CAD97 suggested above. If Rust had existential lifetimes, such a pattern could even be written entirely in safe code.

On the rust internals forums, there is a discussion thread about UnsafeAlias that is not linked in the Prior Art section: https://internals.rust-lang.org/t/an-alternative-to-the-current-unpin-hack-unsafealias/18810 .

Oh yeah there's been tons of prior discussion of this, the idea has been floating around for years. I don't have an exhaustive list, but I can add links to the document for things that we find. Thanks for the reference!

Is there a reason there is no way to get a shared reference to the inside of the UnsafeAlias eg a method of the form get_ref(&self)->&T. I don't think this would impose any additional safety requirements because creating a shared reference already requires the value to be immutable.
Also, are there any plans for safe alias types in core/std? The only usable type I can think of is AliasCell but that requires a function with a signature like split<'a,T,U>(source:&mut &'a mut U,offset:impl FnOnce(&U)->&AliasCell<T>)->&'a AliasCell<T> , which seems unusable.

get_ref(&self)->&T is almost never what you want. It would be UB if anybody performed mutation while that &T exists!

Quick AliasCell api sketch:
impl<T> AliasCell<T>{
    pub fn new(value:T)->Self;
    pub fn into_inner(self)->T;
    pub fn split<'a,Owner>(this:&mut &'a mut Owner,offset:impl FnOnce(&mut Owner)->&mut this)->&'a Self
}
impl<T> Deref<Target=Cell<T>> for AliasCell<T>;

What does that have to do with this RFC?

After thinking a bit more about UnsafeAliased in the context of this question, I'm thinking more and more that we want to call it UnsafePinned. If you have other incoming pointers, then you better be pinned, since moving this value around would invalidate those pointers!
I'll try to sketch the API for that when I have some time.

I'm thinking more and more that we want to call it UnsafePinned.

I disagree, since pinning is how you ensure the value in a particular piece of memory doesn't move, whereas UnsafeAliased is how you ensure that particular piece of memory is valid to access through a different pointer, regardless of if the value has been replaced or not. basically, UnsafeAliased lets you run mem::replace on the value in memory, pinning does not.

UnsafeAliased leads people to think they can have aliasing &mut. It's s huge footgun which makes that name inacceptable IMO.
Whether you can run replace on an UnsafeAliased depends heavily on the context, and same for Pin, so there's really no difference here.

I'm part of the discussion in which there were some confusion (and probably part of why). So I'd like to tell what I understood about this RFC to help improve it and to clear up any missunderstandings :)
Here are the points that I belive hold true:

Mutably aliasing UnsafeAlias<T> would not imply mutably aliasing T [^1].
Other aliasing rules still hold for UnsafeAlias<T> [^2].
All aliasing rules still hold for T [^3].
Pointers and raw memory operations will work either way [^4].
Regularly, when aliasing a struct, all its fields are also aliased.
UnsafeAlias<T> could be used to break this infered aliasing.
This would allow self-referencing pointers [^5].

Also, the RFC says nothing about immutible aliasing. How would the rules for that work?
[^1]: But it doesn't forbid it to do so.
[^2]: E.g. no multiple mutable aliases of UnsafeAlias<T>.
[^3]: This seems to be part of the consfusion. You can still not have multiple &mut T. You can have multiple *mut T, though (since the aliasing is not aplied until accessed).
[^4]: Is it because they work on a lower level?
[^5]: Because the implied aliasing no longer exists, aquiring a mutable reference would be valid.

@mangelats
Immutable references alias with themselves.  One mutable access (via a raw pointer) aliases with immutable references via UnsafeCell.
Point 4 is inaccurate.  If (today) one has an immutable reference and a mutable pointer through which the referenced data is modified without involving UnsafeCell, that's UB.  I think you just need more formal wording.
A good introductory way to think about aliasing is as single-threaded race conditions: when aliasing is violated, the compiler will likely use old values.  Another good way to think about it is that every time you read something the compiler copies it to an imaginary variable, then removes all reads that it can prove don't modify anything (but note the results can be weirder; this is just a useful model). So, broadly:

&T (without interior mutability) must only be read once for the lifetime of the reference.  It may be read more often, but that's a compiler detail.
&T (with interior mutability) must be read once every time the interior mutability is invoked; sometimes the compiler can prove that didn't happen, so this doesn't mean always, but e.g. with a mutex it mostly means always because we don't know what other threads are doing (for example, atomics are almost never optimized out in practice).  Many of the special cases like mutexes are handled by library code though, just in ways the compiler can't see through (e.g. man pthread_lock).
&mut T without interior mutability must be read to get the value if and only if the compiler wrote a value previously, and if and only if the compiler decides not to just keep the value it wrote around in a register.  This means that other &mut T might as well literally be race conditions/other threads/whatever: the compiler might or might not see the change, but is only contractually bound to assuming reads are required after writes to the individual references.
&mut T must not also be modified by a *mut T because the compiler is only contractually obligated to treat writes to the reference as changing memory.
&mut T with interior mutability of the form UnsafeCell is &mut T: you can get a raw pointer, but there's no point usually.
&mut T can be reborrowed as a &T. This is how, e.g., mutexes work: it reborrows as &T, then invokes the interior mutability.

Essentially, what this RFC is doing is saying that UnsafeAliased as a wrapper means "yes this is &mut T, but really actually it can change at any time", in the same way UnsafeCell says "Yes this is &T but really it can change at any time" (the marker is limited only to the byte range of the wrapped field though).
Not sure if this helps.

Mutably aliasing UnsafeAlias<T> would not imply mutably aliasing T

I don't know what you mean by that. Aliasing occurs whenever the pointers overlap. The question of whether aliasing is allowed depends on the type, but the question of whether there is aliasing is completely type-independent.

Also, the RFC says nothing about immutible aliasing. How would the rules for that work?

Aliasing is only a problem when there is mutation. Maybe you mean that the RFC doesn't say anything about &UnsafeAlias, i.e. aliasing of UnsafeAlias behind shared ("immutable") references? However, the RFC does cover that case:
/// Further note that this does *not* lift the requirement that shared references
/// must be read-only! Use `UnsafeCell` for that.

After the discussion over yonder I concluded that we really have to pick a different name. When you have an API that involves shared mutable state, it is not the case that you can freely pick between &UnsafeCell and &mut UnsafeAliased. Wrappers around UnsafeCell that provide mutability behind shared references are possible, and we have plenty of them. Wrappers around UnsafeAliased that provide sharing behind mutable references are not possible. One has to use pinning.
So, I updated the RFC to call the type UnsafePinned. This hopefully makes it less likely that people mistaken the type for a general mechanism for aliasing mutable references. (There can be no such mechanism.)

@RalfJung You should probably also update the PR name and description to use the name UnsafePinned.

I can't update the branch name... but yeah I can update the PR title, true. I'll update the filename and feature name when/if FCP starts.

Currently the rfc states that "it is not possible to write wrappers around UnsafeAliased such that we can have mutation behind &mut MyType." ,when it is possible to write at lease one such struct.

How does UnsafePinned interact with niches? I would assume it has to disable them for the same reasons as UnsafeCell, but I couldn't see anything related in the RFC text.
Why I believe disabling niches is necessary:
type Foo = UnsafePinned<NonZeroU32>;

fn should_be_sound(p: Pin<&mut Option<Foo>>) -> Option<Pin<&mut Foo>> {
  // SAFETY: we don't access the pinned Foo...
  unsafe {
    // ...or do we? if Option<Foo> is niched reading the discriminant
    // involves reading Foo, and this function is unsound.
    match Pin::get_unchecked_mut(p) {
      Some(p) => Some(Pin::new_unchecked(p)),
      None => None,
    }
  }
}

Sure, this code cannot be written without unsafe, but not being able to soundly project pinned enums would be a huge footgun.

Currently the rfc states that "it is not possible to write wrappers around UnsafeAliased such that we can have mutation behind &mut MyType." ,when it is possible to write at lease one such struct.

Sorry, this should have said "aliasing", not "mutation".
I'm not sure if that answers your question though. When you claim you have an example, then please always give the example.

How does UnsafePinned interact with niches? I would assume it has to disable them for the same reasons as UnsafeCell, but I couldn't see anything related in the RFC text.

Yeah good point.

impl AliasCell{
pub fn new(value:T)->Self;
pub fn into_inner(self)->T;
pub fn split<'a,Owner>(this:&mut &'a mut Owner,offset:impl FnOnce(&mut Owner)->&mut this)->&'a Self
}
impl Deref<Target=Cell> for AliasCell;

I don't know what that is supposed to demonstrate, sorry. You're not explaining anything and you're not even showing the definition of AliasCell, which obviously is highly relevant.

Sorry for being unclear. The principle behind it is that both &mut and &Cell offer the same functionality, with the only difference being that &muts are guaranteed to be unique. Therefore, if the target of the &mut is wrapped in an UnsafeAlias, it is sound to hand out &Cells pointing to memory also used by a &mut UnsafeAlias. The rest of the API is just making sure the lifetimes are correct. The definition would simply be UnsafeCell<UnsafeAlias<T>>.

both &mut and &Cell offer the same functionality, with the only difference being that &muts are guaranteed to be unique

That's not true at all. &mut allow reborrowing of fields, whereas &Cell only allows reading and writing but doesn't allow references into the contents. That's in fact an absolutely crucial part of why Cell is sound.

Therefore, if the target of the &mut is wrapped in an UnsafeAlias, it is sound to hand out &Cells pointing to memory also used by a &mut UnsafeAlias. The rest of the API is just making sure the lifetimes are correct. The definition would simply be UnsafeCell<UnsafeAlias>.

It's not sound to expose &mut UnsafePinned aliasing with other types. This includes aliasing with &Cell. You need to use pinning to expose aliased UnsafePinned to safe code.
I still have no clue at all what point you are even trying to make. I also can;'t parse your API, your code isn't valid Rust. (There's an &mut this type somewhere.) If you want to make an example, please paste a link to a snippet on the playground that actually builds. At the very least, add doc comments to your API so that the reader has a change of understanding what these functions do. Just dumping some names and types isn't helpful.  Don't expect the reader to do the work of expressing your arguments for you.
What does split even do? How does it split an AliasCell?

That's not true at all. &mut allows reborrowing of fields, whereas &Cell only allows reading and writing but doesn't allow references into the contents. That's in fact an absolutely crucial part of why Cell is sound.

You can get references to the inside of a Cell, the reference type is &Cell. Also the reason you can take a shared reference to data behind a &mut is because of the uniqueness guarantee; if you know a &Cell is unique, you can take a shared reference to the interior soundly.

It's not sound to expose &mut UnsafePinned aliasing with other types. This includes aliasing with &Cell. You need to use pinning to expose aliased UnsafePinned to safe code.

Why?

There's an &mut this type somewhere but no this type declared.

this is an argument of type &mut &mut Owner(Owner is introduced as an generic).

What does split even do? How does it split an AliasCell? Or split anything else?

It 'splits' and &mut into a &mut and a &Cell(I don't it's anymore unclear than understanding what UnsafeCell::get does).

If you want to make an example, please paste a link to a snippet on the playground that actually builds.

OK
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=580b9b036a22c1e22af6aeb0f916001c

That's not true at all. &mut allows reborrowing of fields, whereas &Cell only allows reading and writing but doesn't allow references into the contents. That's in fact an absolutely crucial part of why Cell is sound.

But you can project fields of a cell which is very akin to reborrowing of fields, i.e. the following should be sound, as far as I know:
fn project(ty: &Cell<(u8, u32)>) -> (&Cell<u8>, &Cell<u32>) {
    let offset_0 = offset_of!((u8, u32), 0);
    let offset_1 = offset_of!((u8, u32), 1);

    let ptr = ty.as_ptr();

    unsafe {
        // Safety:
        // `offset_{0,1}` are offsets to tuples fields, `Cell` is
        // `repr(transparent)`, so those are in-bounds.
        let ptr_0 = ptr.byte_add(offset_0).cast::<Cell<u8>>();
        let ptr_1 = ptr.byte_add(offset_1).cast::<Cell<u32>>();

        // Safety:
        // `ptr_{0,1}` are pointing to the fields, and the types are
        // cell-wrapped (so we keep interior mutability).
        //
        // This is basically the same as using `as_slice_of_cells`.
        (&*ptr_0, &*ptr_1)
    }
}

(play)

I don't see why projecting fields of a Cell would be sound because the guarantees we have don't say that we can do that anywhere, not that I've ever seen.
I do see why projecting the fields of a Cell would compile correctly, and that one could argue it's sound, but that's not quite the same thing and in this specific case splitting that hair is important.
If it were to be declared sound based on whether or not things overlap (which imo is probably the only reasonable thing), repr(transparent) is probably unimportant; no functional layout algorithm can overlap two fields of a struct or tuple.

projecting fields of a Cell

To be fair, Cell::as_slice_of_cells (and as_array_of_cells) exists.
This all seems very off topic from UnsafePinned though. It seems like there is generally consensus about the RFC itself - is anything stopping it from entering FCP?

I don't see why projecting fields of a Cell would be sound because the guarantees we have don't say that we can do that anywhere, not that I've ever seen.
I do see why projecting the fields of a Cell would compile correctly, and that one could argue it's sound, but that's not quite the same thing and in this specific case splitting that hair is important.
If it were to be declared sound based on whether or not things overlap (which imo is probably the only reasonable thing), repr(transparent) is probably unimportant; no functional layout algorithm can overlap two fields of a struct or tuple.

If you allow a function of the form fn from_ptr<T>(ptr:*mut T)->&Cell<T>, then it must be sound, because @WaffleLapkin 's example can be rewritten as:
fn project<T,U)(ty: &Cell<(T, U)>) -> (&Cell<T>, &Cell<U>) {
    let ptr = ty.as_ptr();

    unsafe {
        // Safety:
        // `offset_{0,1}` are offsets to tuples fields, `Cell` is
        // `repr(transparent)`, so those are in-bounds.
        let ptr_0 = addr_of_mut!((*ptr).0)
        let ptr_1 = addr_of_mut!((*ptr).1);

        // Safety:
        // `ptr_{0,1}` are pointing to the fields, and the types are
        // cell-wrapped (so we keep interior mutability).
        //
        // This is basically the same as using `as_slice_of_cells`.
        (Cell::from_ptr(ptr_0),Cell::from_ptr(ptr_1))
    }
}

Also, I just realised the API I proposed is unsound because of take_mut(). This is the 3rd API I've seen that is unsound because of take_mut().

I do agree that getting way into this is off topic, so I will simply stop by pointing out that an API implying soundness is a strong argument to specify that something is sound, but not actually a guarantee that it is.  There is a difference between Rust as a practical language, and Rust as a formal construct; what we are now discussing probably is sound from a practical perspective, but (as this RFC itself shows, since we could otherwise say that what the compiler does must be sound) what matters for language design is the formal construct.

You can get references to the inside of a Cell, the reference type is &Cell.

That's not a reference to the inside of a Cell, that's a reference to the Cell, i.e., the outside.
It is crucial that e.g. with &Cell<Option<T>>, there is no way to get a reference to the T. With &mut this is possible. This shows a very deep, fundamental difference between &mut and interior-mutable shared references.

It 'splits' and &mut into a &mut and a &Cell(I don't it's anymore unclear than understanding what UnsafeCell::get does).

I can only tell you it's very unclear to me. :shrug:
I don't see any splitting here. "Splitting" operations always return (at least) two things, namely the two parts that they split their argument into. Do you mean reborrowing?
Why does split first read orig from this and then write back the exact same value into this?
Your original claim was that this claim from the RFC is wrong: "it is not possible to write wrappers around UnsafeAliased such that we can have aliasing behind &mut MyType". I still don't see how your type supports your claim.
Trying to extract the argument from your code, I think what your code is doing is provide an API to set up something self-referential? At least that's what your example main does. Usually that needs pinning.
Your API tried to do this without pinning, but it is unsound. The last line is a use-after-free, the box that data.1 points to has been deallocated. (And this doesn't need take_mut.)

Just read this through and the "It is more like the core primitive behind pinning" line made me curious if there is a way to rewrite the Pin safety guarantees in terms of UnsafePinned<T>.
Currently there feels like there is this strange asymmetry where even though UnsafePinned<T> is !Unpin, technically if you have an UnsafePinned<u32>, you could mem::replace that and it wouldn't actually have any problems (besides the aliasing issues that this fixes) I believe. Obviously, the !Unpin bound is there simply because any type containing it is going to need to be !Unpin.
This is mostly just something that comes out of over analyzing it of course, at an intuitive level it makes perfect sense - "an UnsafePinned<T> inside a type is the reason why that type will need to be !Unpin".
Still, I think it would make sense if this type is advertised as "the core pinning primitive" to have somewhere (first in this RFC then in the pin docs I guess) that describes in a more sort-of-formal way of which operations are usually not ok to be done on this type through a Pin. I assume this would probably have to do with "invalidating memory" or something along this lines, relating to the Drop guarantee on Pin as well.

Currently there feels like there is this strange asymmetry where even though UnsafePinned is !Unpin, technically if you have an UnsafePinned, you could mem::replace that and it wouldn't actually have any problems (besides the aliasing issues that this fixes) I believe. Obviously, the !Unpin bound is there simply because any type containing it is going to need to be !Unpin.

How do you define "have"?
If you have a Pin<&mut UnsafePinned<u32>>, swapping/replacing that can cause UB. You don't know which invariants are imposed by whoeever pinned this integer.
If you have a fully owned UnsafePinned<u32> you can do with it whatever you want of course, but that's expected -- the same is true for UnsafeCell.
So I don't understand which asymmetry you are referring to here.

Still, I think it would make sense if this type is advertised as "the core pinning primitive" to have somewhere (first in this RFC then in the pin docs I guess) that describes in a more sort-of-formal way of which operations are usually not ok to be done on this type through a Pin. I assume this would probably have to do with "invalidating memory" or something along those lines, relating to the Drop guarantee on Pin as well.

I think this is something we can explore after the RFC gets accepted. It's not entirely clear to me whether all of pinning can be sourced to some use of this type.

How do you define "have"?

If you have a Pin<&mut UnsafePinned>, swapping/replacing that UnsafePinned can cause UB. You don't know which
invariants are imposed by whoever pinned this integer.

Ah sorry, so what I mean is the fact that there isn't any real way to use this Pin<&mut UnsafePinned<u32>> that isn't just either &mut u32 or &u32. Its not entirely clear what invariants Pin<&mut UnsafePinned<u32>> can actually uphold over &mut UnsafePinned<u32> that &UnsafePinned<u32> cannot.
So the "asymmetry" here is the semantic difference between the requirements of Pin<&mut SelfReferentialStruct> and Pin<&mut UnsafePinned<u32>>. In fact, I could probably even go as far to say I don't think you would ever necessarily need Pin<&mut UnsafePinned<u32>>, because just a mutable reference guarantees that the memory behind it won't ever be invalidated, and "swapping it" is merely changing the value because u32: Unpin.
Again, not a real problem but probably a beginner trap? Pinning is definitely one of the more hard to understand parts of std so I could see this potentially being a confusion people have.
Either way, I think the side-effect of this type hopefully making it easier to reason about the invariants of pinned data is a really big plus because it would definitely make pinning easier to learn/understand.

Ah sorry, so what I mean is the fact that there isn't any real way to use this Pin<&mut UnsafePinned> that isn't just the same as &mut UnsafePinned. Its not entirely clear what invariants Pin<&mut UnsafePinned> can actually uphold over &mut UnsafePinned that &UnsafePinned cannot.

It's the usual pinning invariants. UnsafePinned is obviously a low-level building block so it doesn't provide a safe API itself, very much like UnsafeCell. But both can be used to then build safe abstractions.
If you have UnsafePinned in your public API, something went wrong -- just like UnsafeCell doesn't show up in public APIs either.

It's the usual pinning invariants.

This is sort of what I find sort of strange i guess? I'm not quite sure what the actual pinning invariants of UnsafePinned<u32> should even be.
UnsafePinned<u32> doesn't need to be dropped, and if I called mem::swap on two different Pin<&mut UnsafePinned<u32>> (after unsafely getting the mutable references), I don't think any actual invariants would be broken, because it has the same effect as simply swapping the two u32s (which is safe because they are Unpin).

&UnsafePinned is immutable so now I think you are confusing entirely unrelated concepts.

My point here was that there doesn't seem to be a way to truly add any invariants to an &mut UnsafePinned<u32> without getting something pretty much equivalent to an immutable reference.
With a self-referential struct, the legal things you can do are going to be for example modifying fields (often through a non-structural projection), while you can't do things that would invalidate the internal pointer to cause UB in later, safe operations.
The only way to modify an UnsafePinned<u32> is to edit the internal value, and because it is just a wrapper with additional aliasing information for the compiler, it would imply that editing an UnsafePinned<u32> is the same as just calling mem::swap or whatever other traditionally pinning-invariant-breaking operations.
But yeah sorry this is probably a really small detail that i assume is probably off-topic/more relevant for when the RFC actually happens.

UnsafePinned doesn't need to be dropped, and if I called mem::swap on two different Pin<&mut UnsafePinned> (after unsafely getting the mutable references), I don't think any actual invariants would be broken, because it has the same effect as simply swapping the two u32s (which is safe because they are Unpin).

I think in your hypothetical scenario there is an API that has UnsafePinned somewhere in its publicly visible types? That should never happen.
If that's not the case you need to give more details, I still can't follow what you are saying.

I think in your hypothetical scenario there is an API that has UnsafePinned somewhere in its publicly visible types? That should never happen, as described above. Therefore the rest of this discussion makes little sense.

Ok so the docs for get_mut_unchecked say

Exposing an &mut UnsafePinned that aliases other pointers to code outside your crate is unsound. Only Pin<&mut UnsafePinned> can be exposed soundly. Use get_mut_pinned instead whenever possible.

And this is what is confusing me because I assumed that yeah, UnsafePinned is usually not going to ever be exposed.
Therefore, its not immediately clear to me:

When you would ever use get_mut_pinned, or does it ever makes sense to obtain a Pin<&mut UnsafePinned<T>>.
If you do want to create/expose a Pin<&mut UnsafePinned<u32>>, what are the contracts you want to be upheld that the Pin allows?
Relating to the above, Why would you be creating this pinned reference when UnsafePinned<u32> doesn't actually care about its location in memory. Yes a custom invariant might be invalidated, but that isn't within the scope of Pin (and it can be invalidated with Pin::set, not just mem::swap/whatever).

Some code to (hopefully) demonstrate what I mean: https://gist.github.com/Yurihaia/f56b0e039aa473ae34a9642cfc3062aa
Obviously as I said before, this is like, an incredibly small detail that was mostly just some idle thought, and from an intuitive level it all does make complete sense.

Ok so the docs for get_mut_unchecked say

Ah, that's fair, those docs don't quite make sense. I'll see what I can do.

You don't need our permission to publish any crate, but I don't have the capacity to be involved in that in any form.

@rfcbot fcp merge
We discussed this RFC in today's lang team meeting (notes) and I think we should move forward with the RFC.
Teaching
One concern I had is around how to teach proper use of UnsafePinned. In particular, it would still be UB to create a mutable reference accessible by unknown code to any type transitively containing UnsafePinned, if that reference is aliased. Pointers to any type which has aliasing references (including self-references) should instead all be wrapped in Pin.
This is somewhat different from UnsafeCell, which neatly contains all the unsafety directly in its API by only handing out raw pointers, and requires a user to directly use unsafe to do anything which might violate its invariants. That said, I think this weirdness is inherent in the Pin API itself, and we are just giving users tools they need to express the patterns it is designed to enable.
@RalfJung used a framing of "capabilities" that I thought was insightful. Generic code which has &T for some unknown, unbounded T is not capable of doing anything with that reference (even dereferencing it would require Copy). On the other hand, &mut T does come with inherent capabilities, like the ability to call std::mem::swap, which assumes its arguments do not alias. The need to restrict such capabilities subsequently results in the restrictions around handing out mutable references.
Naming
I raised an eyebrow at the name UnsafePinned, having been used to seeing UnsafeAliased before. However, this section of the RFC convinced me:

An earlier proposal suggested to call the type UnsafeAliased, since the type is not inherently tied to pinning.
However, it is not possible to write sound wrappers around UnsafeAliased such that we can have aliasing &mut MyType. One has to use pinning for that: Pin<&mut MyType>.
Because of that, the RFC proposes that we suggestively put pinning into the name of the type, so that people don't confuse it with a general mechanism for aliasing mutable references.
It is more like the core primitive behind pinning, where whenever a type is pinned that is caused by an UnsafePinned field somewhere inside it.
For instance, it may be tempting to use an UnsafeAliased type to mark a single field in some struct as "separately aliased", and then a Mutex<Struct> would acquire ownership of the entire struct except for that field.
However, due to mem::swap, that would not be sound.
One cannot hand out an &mut to such aliased memory as part of a safe-to-use abstraction -- except by using pinning.

The fact that the use of Pin goes hand-in-hand with the use of UnsafePinned, in both directions – to the point where we would implement the existing PhantomPinned in terms of it and potentially even deprecate that type – convinces me that this is the right name. I also think it improves the story around teaching to have them paired.
That said, @joshtriplett also raised concerns about the name and I believe he would like to have it included as an open question in the RFC.

For clarity, no objection to the introduction of this in nightly. I'd like to add an unresolved question about naming that we resolve before stabilization, but that's not a blocker for experimentation in nightly.

I added the name to the Unresolved questions.

@rfcbot reviewed

The name UnsafePinned doesn't really "speak to me" -- it feels like the name could better convey that it is the target of raw pointers. Perhaps UnsafePinPointee or something, I'm not sure. But since the name is unresolved I'm happy to go forward for now.

The teams have accepted this RFC, and we've now merged it.
Thanks to @RalfJung for pushing this high quality work forward, and thanks to those who reviewed this work and provided helpful feedback.
For further updates, follow the tracking issue:

https://github.com/rust-lang/rust/issues/125735


feat(actions): add redeem and claim bid actions

added action to redeem bid
added action to claim bid
tested redeem and claim bid transaction instructions in metaplex-foundation repo

:tada: This PR is included in version 3.5.0 :tada:
The release is available on:

npm package (@latest dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

Where are the automated tests that will cover these changes? Separate PR?


Add Lualine support to nord-vim

Adds support for Lualine, a Neovim statusline plugin written in Lua. While the theme tries to stay as close as possible to the existing Lightline theme, the filename section uses nord3 as the background rather than nord1 due to that section also determining the color of the background.
Screenshots are attached of the theme in action:

Can we move this to the Neovim port once it starts taking shape?

Hi @lokesh-krishna :wave:, thanks for your contribution :+1:
A Lua counterpart for lightline/airline is definitely something that will be added to the new port. I'll try to review this PR as soon as possible and maybe merge it until the port is available. Afterwards this project will be "cleaned" anyway like described in https://github.com/arcticicestudio/nord/issues/157#issuecomment-924312218 and https://github.com/arcticicestudio/nord/issues/157#issuecomment-927262345.

I have decided not to include support for Lualine in this repository but only for the upcoming Nord Neovim port. I leave this PR open to use it as reference and allow you (if you want) to reopen it in the new repository later on.

@lokesh-krishna Thank you (again!) for your patience! 🙏🏼
It‘s been a while since I had free time to focus more on Nord, and my open source projects in general, and invest time in this issue due to work-life balance.
I recently published the first “Northern Post — The state and roadmap of Nord“ announcement which includes all details about the plans and future of the Nord project, including the goal of catching up with the backlog. This issue is part of the backlog and therefore I want to triage and process it to get one step closer to a “clean state“. Read the announcement about reaching the “clean“ contribution triage state in Nord‘s discussions for more details about the goal.
Therefore it has been added to the icebox in the central and single-source-of-truth project board that is also described in more detail in the roadmap announcement.

@lokesh-krishna Thanks (again!) for your contribution 🚀
The pull request has been added to the icebox and will be adapted to the new and upcoming Neovim port.


Buf BSR support

Hi.
We are working on an LSP for the Buf BSR (https://buf.build/product/bsr), which supports depending on shared remote protobuf definitions. I was wondering if there is interest in adding BSR support to this plugin, using some of the feature that we are adding to the Buf CLI to support other LSPs. For example, the Buf CLI can resolve the contents of all files from remote dependencies.
Thanks,
Alfred

I would be very happy to cooperate with you and ask what functions the plug-in needs to provide to support BSR.

Great. Can you contact me via https://buf.build/links/slack?

Plz ping me with HIGAN

@Alfus


"Integrate" doesn't work

This code :
const expr = ce.parse('x^2').json
ce.box(['Integrate', expr, ['Element', 'x', ['Interval', 0, 1]]]).latex
console.log(calculintegrale)

returns
\mathrm{Integrate}(x^{2}, x\in )

+1 - Also hoping this feature could be added.
I would love to be able to work on this myself, but it's way beyond my skill level .

const expr = ce.parse('x^2').json;
const calculintegrale = ce.box([
    'Integrate',
    expr,
    ['Tuple', 'x', 0, 1],
  ]).latex;
console.log(calculintegrale);
// -> \int^{1}_{0}\!x^2\,\mathrm{d}x

Works now. Note that the second argument of "Integrate" is a Tuple of the index variable, the lower bound and the upper bound.


Travis Integration

Based off of #1662, but in one of our branches so I can mess with it ;)

Now that I look at it it looks like Travis will build the branch without a PR, so that's pretty handily-dandily handy-dandy…

Maybe it is a reason why: "Travis CI builds a pull request when it's first opened and when commits are added to the pull request throughout its lifetime.". I see that #1666 and #1603 is checked agains build. Because of #1661 they are failed. However discussion about TimeSpan problem fix doesn't involve too many persons on mailing list.

Yeah, we'll see. I'm going to follow up on the TimeSpan discussion today if I get a chance.

Okay okay okay, these now seem to be passing; cleaned up history a bit, will merge it in once travis gives the green light.


Cannot change the Unit of Measurement

Hello, I want to report a bug:
My Battery default measurement unit is Watt, and I want to use kW instead. But when I change the Unit of Measurement in settings (see screenshot) nothing changes and stays on W. The entity is battery_1_charge_discharge_power
Screenshot

@LPirro could you apply the changes in https://github.com/tijsverkoyen/HomeAssistant-FusionSolar/pull/111 and let me know if it works.
I don't have a battery in my setup so I can't test it for all devices.
Be aware that this could cause backwards compatibility. As some of the entities have been changed.

Thanks for the reply! ❤
I will create another home assistant instance for testing and I will let you know, I don't want to break my current setup.
Happy to help testing this! 🙏🏻

@LPirro have you tried with these changes?

@tijsverkoyen I just tested the changes, and they are working!
Thanks!

Thx. I have created a new release: https://github.com/tijsverkoyen/HomeAssistant-FusionSolar/releases/tag/v3.0.0


Add completion ("IntelliSense") support to language server

Fix #56

@timotheeguerin Any ideas about https://dev.azure.com/azure-sdk/public/_build/results?buildId=1189152&view=logs&j=69944193-f126-526b-b021-abb6fb4b38ee&t=0a25231a-5099-578e-5217-6d785d9657f7&l=184
I can't figure out how I broke this, but main is green and I'm not, lol.

@timotheeguerin Any ideas about https://dev.azure.com/azure-sdk/public/_build/results?buildId=1189152&view=logs&j=69944193-f126-526b-b021-abb6fb4b38ee&t=0a25231a-5099-578e-5217-6d785d9657f7&l=184
I can't figure out how I broke this, but main is green and I'm not, lol.

Wonder if its because node-fetch gets imported through something else getting imported and node-fetch needs special config in rollup.js


Compression value is empty

im getting this error in the image compressor

these are the args i pass to the compress function:
      const res = await ImageCompress.compress(img.path, {
        compressionMethod: 'auto',
      });
      setCompressed(res);

what is the "Compression value" that i need to input? where?

just paseed invalid image path


feat: separate ci workflows for cli/www

✅ Checklist

[ ] I have followed every step in the contributing guide (updated 2022-08-15).
[x] The PR title follows the convention we established conventional-commit
[ ] I performed a functional test on my final commit

Changelog
It's annoying that we have to run the cli CI when updating the docs and vice versa.
Keeping this as a draft for now because it probably needs a lot more work.
💯

easier thing is just adding a if check on the matrix job

build-t3-app:
  if: |
    github.repository_owner == 't3-oss' &&
    ( contains(github.event.pull_request.labels.*.name, 'area: t3-app') || contains(github.event.pull_request.labels.*.name, 'area: cli') )
  ...

The tag seems to get added too late for the CI to notice it? Need to head out now but will try to get it working tomorrow :)


Deleted nodes doesn't update connected inputs on other nodes

Deleting a node doesn't update inputs it was connected to
Like a String Property into String input, then delete the String Property.

Okay, I'm working on it, should be easy to fix

Fixed in 65dc0acf05c5e77bf59a1631848ed0cf072b7e96


16 column grid based width size

Hi,
Can anyone of you suggest me the size for 16 Col Grid, I mean what would be the size for width starting from 1 column to 16 columns
Thanks and Regards,
Manu

Hi,
You can using css to define the column first, then let cellW as a function to make it done.
Pleas take a look on this:
https://github.com/kombai/freewall/issues/212


[Event Request] Codeunit 1005 Job Calculate Batches - OnPostDiffBufferOnAfterAssignFilters

Hello. Could you please add the following "OnPostDiffBufferOnAfterAssignFilters" event to Codeunit 1005 "Job Calculate Batches" into the procedure PostDiffBuffer?
if JobDiffBuffer[1].Find('-') then
            repeat
                JobLedgEntry.SetCurrentKey("Job No.", "Job Task No.");
                JobLedgEntry.SetRange("Job No.", JobDiffBuffer[1]."Job No.");
                JobLedgEntry.SetRange("Job Task No.", JobDiffBuffer[1]."Job Task No.");
                JobLedgEntry.SetRange("Entry Type", JobLedgEntry."Entry Type"::Usage);
                JobLedgEntry.SetRange(Type, JobDiffBuffer[1].Type);
                JobLedgEntry.SetRange("No.", JobDiffBuffer[1]."No.");
                JobLedgEntry.SetRange("Location Code", JobDiffBuffer[1]."Location Code");
                JobLedgEntry.SetRange("Variant Code", JobDiffBuffer[1]."Variant Code");
                JobLedgEntry.SetRange("Unit of Measure Code", JobDiffBuffer[1]."Unit of Measure code");
                JobLedgEntry.SetRange("Work Type Code", JobDiffBuffer[1]."Work Type Code");
                // NEW CODE
                //
                OnPostDiffBufferOnAfterAssignFilters(JobLedgEntry, JobDiffBuffer[1]);
                //
                // NEW CODE
                if JobLedgEntry.Find('-') then
                    repeat
                        JobDiffBuffer[1].Quantity := JobDiffBuffer[1].Quantity - JobLedgEntry.Quantity;
                    until JobLedgEntry.Next() = 0;
                OnPostDiffBufferOnBeforeModify(JobLedgEntry, JobDiffBuffer[1]);
                JobDiffBuffer[1].Modify();
            until JobDiffBuffer[1].Next() = 0;

    [IntegrationEvent(false, false)]
    local procedure OnPostDiffBufferOnAfterAssignFilters(var JobLedgEntry: Record "Job Ledger Entry"; var JobDiffBuffer: Record "Job Difference Buffer" temporary)
    begin
    end;

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. Please do not reply to this, as we do not monitor closed issues. If you have follow-up questions or requests, please create a new issue where you reference this one.
Build ID: 10392.


test_000036 decoded wave is not trimmed at the end

In test_000036, samples_to_trim_at_end is 149, but the decoded wave is not trimmed.
Is it correct that the decoded wave has the same samples with the input wave?

It is correct. The samples_to_trim_at_end is acting as a loaded term. First it is applied to pad the frame. That wav file needs 149 samples to pad the final frame.
If it was greater than the amount to pad the frame it would act to shorten the wav file.


Sync /Refresh issue :The note icon does not appear on the app as soon as a note is created on the website

Issue description : When a note is created for a verse via the website, it takes a while for the note icon to reflect on the app.
Steps:
Create a note for a verse on the website
Now open the app and navigate to the same verse.
Observation:
The note icon does not display alongside the verse in the App. This seems to be a refresh issue.
Work Around: Select the Note option from the bottom bar of the app. The  notes would be listed here
Also, since the window is refreshed by the above step, there are chances for the note icon to reflect beside the
verse.
Expected Result:
The note icon should be displayed beside the verse as in the website.

Fixed This notes sync issue and pushed code to branch 'version_1.0.1_fixes'

Verified the fix
Verification comments:
Observation : The moment a note is created on the website, it reflects immediately on the App.
Wrt the note content sync, tested a few times for which the sync times are as follows
Iteration 1:  Network speed: 20Mbps  ,sync time -few seconds,
Iteration 2: Network speed: 3.49 Mbps, sync time:  1 min
The note sync time is dependent on the network speed.


fix(tags): fix disappearing popup while updating tags on new website

Goal
Fix #65: popup closes while typing tags
Root cause
The root cause seems to be that upon tag input the cancel close request is not being called so once the timeout reaches the popup is closed even while the user is typing a tag.
Todos:

[x] Reproduce issue ( steps outlined in #65 )
[x] add a tag input focus action whenever input receives focus
[x] trigger cancel close request when input receives focus

Implementation Decisions
Approach
I decided to add a tag input focus action and saga that ensures cancel close request is explicitly triggered whenever the tag input receives focus.
All Submissions:

[x] Have you followed the guidelines in our Contributing document?
[x] Have you checked to ensure there aren't other open Pull Requests for the same update/change?

When I have the remote dev server running I cannot reproduce the issue, if I turn off the remote dev server I get the issue when using the steps to reproduce in #65

so what about this fix? the problem still exists.

This issue has existed the last 2 - 3 years I've been using pocket (and the chrome extension on MacOS). The lack of any updates to this extension (and this PR sitting open) for almost a year makes me doubt the future of pocket and consider jumping ship to a competitor like raindrop.

Closed in favor of rectifying some outdated code.   This has been captured in #214 and will be addressed there.

@collectedmind Thanks for finally getting to this. Any idea why it took so long?