You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
regression: Join impl for OsStr insufficiently generic #99683
This is the only case found in Crater, so probably acceptable breakage, though we might want to consider expanding our impl (not sure if it'll overlap with something).
It would be nice if the slice_concat_ext impl could also be updated to AsRef<OsStr> but as far as the conflicts go, Path implements AsRef<OsStr>, doesn't implement Join, but could probably benefit from this impl (join an array of paths with a / separator?); I think the real question would be String/str which both implement AsRef<OsStr> but we obviously want them using their own Join impls so that might not be possible?
We discussed this in today's @rust-lang/libs-api meeting, and we'd be in favor of trying to generalize the Join trait impl to accept AsRef<OsStr>for the separator. That should, among other things, allow [os_str, os_str_2].join(" "), which seems useful.
We'd need to make sure that didn't cause widespread inference breakage.
We discussed this in the libs-api team meeting today1 and our preliminary consensus was that this is acceptable breakage, though I'm going to run a poll to confirm this because we did this weeks meeting async so I'm not sure everyone who wanted to participate in that discussion has done so already.
@rfcbot poll libs-api Is this breakage acceptable?
Also, we're interested in trying out the suggestion to expand the impl and see if we run into any overlap or inference breakage issues.
Last but not least, I'm curious if anyone knows why the existing bound was chosen to be S: Borrow instead of S: AsRef.
Oh this caused some breakage, I'm sorry. I guess it's legal breakage as per policy, and only one broken crate is not that bad. Still I'm not as happy now as I was when my PR got merged :).
Last but not least, I'm curious if anyone knows why the existing bound was chosen to be S: Borrow instead of S: AsRef.
I just copy pasted one of the existing implementations and then modified it, think it was the one for str. If you check the rustdoc for the Join trait, all of the implementations have Borrow. Why the existing implementations use Borrow, I had not influence on them, but according to git log -S:
e91d810 unified StrVector and VectorVector into SliceConcatExt, with an AsSlice tait bound (the trait doesn't exist any more)
So I guess the reason why the other impls use Borrow can be found by in #25162. I don't know enough whether AsRef or Borrow is better to have an opinion on either.
Based off of #25162 (comment), the underlying reason is the ambiguity of Vec::<String>::new().concat() - does that return a Vec<Vec<u8>> or String? Using Borrow instead of AsRef caused that to become deterministic (returning the way more probably desired outcome of type String).
For OsStr, Vec::<&OsStr>::concat() isn't/wasn't valid as it is, and still doesn't become valid with the recent PR as OsStr doesn't implement AsRef<[u8]> -- although from what I understand there are existing issues about making that valid, so we shouldn't skip past this point. So there's no code in the wild that currently does Vec::<&OsStr>::concat(), but we have to decide if the benefits of making concat generic over AsRef<OsStr> instead of Borrow<OsStr> outweigh the ergonomic cost of having to be explicit about the desired return type, e.g. let _: OsString = Vec::<&OsStr>::new().concat() vs let _: Vec<Vec<u8>> = Vec::<&OsStr>::new().concat() (which is extremely unlikely to ever be what anyone wants?).
So there's no code in the wild that currently does Vec::<&OsStr>::concat(), but we have to decide if the benefits of making concat generic over AsRef<OsStr> instead of Borrow<OsStr> outweigh the ergonomic cost of having to be explicit about the desired return type, e.g. let _: OsString = Vec::<&OsStr>::new().concat() vs let _: Vec<Vec<u8>> = Vec::<&OsStr>::new().concat() (which is extremely unlikely to ever be what anyone wants?).
I wonder if having something like generic type parameter defaults would let us have our cake and eat it too in this case. I'm not familiar enough with the slice_concat_trait APIs to know if it would help here, but I'd be on the lookout for missing language features that could unblock ideal versions of this API.
Activity
mqudsi commentedon Jul 25, 2022
It would be nice if the
slice_concat_extimpl could also be updated toAsRef<OsStr>but as far as the conflicts go,PathimplementsAsRef<OsStr>, doesn't implementJoin, but could probably benefit from this impl (join an array of paths with a/separator?); I think the real question would beString/strwhich both implementAsRef<OsStr>but we obviously want them using their ownJoinimpls so that might not be possible?joshtriplett commentedon Jul 27, 2022
We discussed this in today's @rust-lang/libs-api meeting, and we'd be in favor of trying to generalize the
Jointrait impl to acceptAsRef<OsStr>for the separator. That should, among other things, allow[os_str, os_str_2].join(" "), which seems useful.We'd need to make sure that didn't cause widespread inference breakage.
yaahc commentedon Jul 27, 2022
We discussed this in the libs-api team meeting today1 and our preliminary consensus was that this is acceptable breakage, though I'm going to run a poll to confirm this because we did this weeks meeting async so I'm not sure everyone who wanted to participate in that discussion has done so already.
@rfcbot poll libs-api Is this breakage acceptable?
Also, we're interested in trying out the suggestion to expand the impl and see if we run into any overlap or inference breakage issues.
Last but not least, I'm curious if anyone knows why the existing bound was chosen to be
S: Borrowinstead ofS: AsRef.edit: race condition
Footnotes
https://rust-lang.zulipchat.com/#narrow/stream/259402-t-libs.2Fmeetings/topic/Meetings.202022-07-27/near/291096605 ↩
rfcbot commentedon Jul 27, 2022
Team member @yaahc has asked teams: T-libs-api, for consensus on:
mqudsi commentedon Jul 27, 2022
cc @est31
est31 commentedon Jul 27, 2022
Oh this caused some breakage, I'm sorry. I guess it's legal breakage as per policy, and only one broken crate is not that bad. Still I'm not as happy now as I was when my PR got merged :).
I just copy pasted one of the existing implementations and then modified it, think it was the one for
str. If you check the rustdoc for the Join trait, all of the implementations haveBorrow. Why the existing implementations useBorrow, I had not influence on them, but according togit log -S:impl<T: Clone, V: Borrow<[T]>> Join<&'_ [T]> for [V] {SliceConcatintoConcatandJointraitsSliceConcatExtintroducedSliceConcatAsRefwithBorrowAsSlicewithAsRefStrVectorandVectorVectorintoSliceConcatExt, with anAsSlicetait bound (the trait doesn't exist any more)So I guess the reason why the other impls use
Borrowcan be found by in #25162. I don't know enough whetherAsReforBorrowis better to have an opinion on either.yaahc commentedon Jul 27, 2022
#26780 (comment)
Coherence issues, probably worth reinvestigating to see exactly what the issue was.
mqudsi commentedon Jul 28, 2022
Based off of #25162 (comment), the underlying reason is the ambiguity of
Vec::<String>::new().concat()- does that return aVec<Vec<u8>>orString? UsingBorrowinstead ofAsRefcaused that to become deterministic (returning the way more probably desired outcome of typeString).For
OsStr,Vec::<&OsStr>::concat()isn't/wasn't valid as it is, and still doesn't become valid with the recent PR asOsStrdoesn't implementAsRef<[u8]>-- although from what I understand there are existing issues about making that valid, so we shouldn't skip past this point. So there's no code in the wild that currently doesVec::<&OsStr>::concat(), but we have to decide if the benefits of making concat generic overAsRef<OsStr>instead ofBorrow<OsStr>outweigh the ergonomic cost of having to be explicit about the desired return type, e.g.let _: OsString = Vec::<&OsStr>::new().concat()vslet _: Vec<Vec<u8>> = Vec::<&OsStr>::new().concat()(which is extremely unlikely to ever be what anyone wants?).yaahc commentedon Jul 28, 2022
I wonder if having something like generic type parameter defaults would let us have our cake and eat it too in this case. I'm not familiar enough with the
slice_concat_traitAPIs to know if it would help here, but I'd be on the lookout for missing language features that could unblock ideal versions of this API.Mark-Simulacrum commentedon Aug 7, 2022
Retagging as a stable/stable regression in anticipation that this will slip into 1.63, and likely not be fixed for a good while.
m-ou-se commentedon Aug 17, 2022
Closing this as acceptable.