-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DerefPure
impl for Cow
may be too general
#136046
Comments
Backlink: tracking issue #87121 |
You're absolutely right, I had not noticed that |
Might make sense to add a |
The impls suggested in the OP (for |
…Nadrieril Restrict DerefPure for Cow<T> impl to T = impl Clone, [impl Clone], str. Fixes rust-lang#136046 `feature(deref_patterns)` tracking issue: rust-lang#87121 `Cow<'_, T>` should only implement `DerefPure` if its `Deref` impl is pure, which requires `<T::Owned as Borrow<T>>::borrow` to be pure. This PR restricts `impl DerefPure for Cow<'_, T>` to `T: Sized + Clone`, `T = [U: Clone]`, and `T = str` (for all of whom `<T::Owned as Borrow<T>>::borrow` is implemented in the stdlib and is pure). cc `@Nadrieril` ------ An alternate approach would be to introduce a new `unsafe trait BorrowPure<T>` analogous to `DerefPure` that could be implemented for `T: Sized`, `&T`, `&mut T`, `String`, `Vec`, `Box`, `PathBuf`, `OsString`, etc. rust-lang/rust@master...zachs18:borrow-pure-trait
Rollup merge of rust-lang#137105 - zachs18:cow-derefpure-restrict, r=Nadrieril Restrict DerefPure for Cow<T> impl to T = impl Clone, [impl Clone], str. Fixes rust-lang#136046 `feature(deref_patterns)` tracking issue: rust-lang#87121 `Cow<'_, T>` should only implement `DerefPure` if its `Deref` impl is pure, which requires `<T::Owned as Borrow<T>>::borrow` to be pure. This PR restricts `impl DerefPure for Cow<'_, T>` to `T: Sized + Clone`, `T = [U: Clone]`, and `T = str` (for all of whom `<T::Owned as Borrow<T>>::borrow` is implemented in the stdlib and is pure). cc ``@Nadrieril`` ------ An alternate approach would be to introduce a new `unsafe trait BorrowPure<T>` analogous to `DerefPure` that could be implemented for `T: Sized`, `&T`, `&mut T`, `String`, `Vec`, `Box`, `PathBuf`, `OsString`, etc. rust-lang/rust@master...zachs18:borrow-pure-trait
One of
unsafe trait DerefPure
's preconditions is thatSelf
'sDeref
impl is "well-behaved".std::borrow::Cow
currently always implementsDerefPure
, butCow<B>
'sDeref
impl can call arbitrary user code in<B::Owned as Borrow<B>>::borrow
that may not be "well-behaved".I tried this (safe) code:
I expected to see this happen: Either this shouldn't compile (because
Cow<Weird>
'sDeref
impl is not "well-behaved"), or the first match should also print "a".Instead, this happened: Having two separate
deref!
patterns joined by an or-pattern behaves differently than an or-pattern in aderef!
pattern. IIUC currently there is no soundness issue because deref patterns do not interact with exhaustiveness checking, but if the first match didn't require the blanket_
arm and consideredderef!(Weird(false, _)) | deref!(Weird(true, _))
exhaustive, then the exhibited behavior would be a soundness issue.One possible resolution might be to restrict
Cow
'sDerefPure
impls to justCow<T: Sized>
,Cow<str>
,Cow<[T]>
, and other types that the stdlib fully controls theToOwned
/Borrow
/Deref
impls of.incorrect suggestion
Moved this into a hidden block because this would not work with
Cow<T: Sized>
, sinceT::Owned = T
, which probably doesn't implementDeref<Target = T> + DerefPure
.Meta
rustc --version --verbose
:@rustbot label +F-deref-patterns +requires-nightly
The text was updated successfully, but these errors were encountered: