-
Notifications
You must be signed in to change notification settings - Fork 13.7k
WIP: smart pointer (try_)map #144420
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
base: master
Are you sure you want to change the base?
WIP: smart pointer (try_)map #144420
Conversation
This comment has been minimized.
This comment has been minimized.
As far as I can tell, the ICE here is because of the function signature of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no clue about the ICE – perhaps try filing an issue?
d5d5fea
to
929d326
Compare
This comment has been minimized.
This comment has been minimized.
929d326
to
6a69f39
Compare
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
library/alloc/src/boxed.rs
Outdated
if size_of::<T>() == size_of::<U>() && align_of::<T>() == align_of::<U>() { | ||
let ptr = &raw const *this; | ||
unsafe { | ||
let new = f(ptr.read()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If f
panics, this will lead to a double-free.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I think this iteration works. I'm still wrapping my head around working with closures that can panic, so thanks for bearing with me.
6a69f39
to
64b65c1
Compare
This comment has been minimized.
This comment has been minimized.
library/alloc/src/boxed.rs
Outdated
|
||
impl<T> Drop for Guard<T> { | ||
fn drop(&mut self) { | ||
let _box = unsafe { Box::from_raw(self.0) }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will still drop the Box
's contents and hence result in a double-free.
library/alloc/src/boxed.rs
Outdated
let guard = Guard(Box::into_raw(this)); | ||
unsafe { | ||
let new = f(guard.0.read()); | ||
let ptr = guard.0; | ||
mem::forget(guard); | ||
ptr.cast::<U>().write(new); | ||
Box::from_raw(ptr.cast::<U>()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend converting the Box<T>
to a Box<MaybeUninit<U>>
before calling f
. This ensures that the allocation is freed, but won't drop the old value on panic. After reading from that, you can use Box::write
to write the final value back.
let guard = Guard(Box::into_raw(this)); | |
unsafe { | |
let new = f(guard.0.read()); | |
let ptr = guard.0; | |
mem::forget(guard); | |
ptr.cast::<U>().write(new); | |
Box::from_raw(ptr.cast::<U>()) | |
} | |
let (allocation, value) = unsafe { | |
let ptr = Box::into_raw(this); | |
let value = ptr.read(); | |
let allocation = Box::from_raw(ptr.cast::<MaybeUninit<U>()); | |
(allocation, value) | |
}; | |
Box::write(allocation, f(value)) |
64b65c1
to
bfc61d6
Compare
The job Click to see the possible cause of the failure (guessed by this bot)
|
…iler-errors fix ICE when suggesting `::new` fixes rust-lang#146174 This code suggests to write `Foo::new(...)` when the user writes `Foo(...)` or `Foo { ... }` and the constructor is private, where `new` is some associated function that returns `Self`. When checking that the return type of `new` is `Self`, we need to instantiate the parameters of `new` with infer vars, so we don't end up with a type like `Box<$param(0)>` in a context that doesn't have any parameters. But then we can't use `normalize_erasing_late_bound_regions` anymore because that goes though a query that can't deal with infer vars. Since this is diagnostic-only code that is supposed to check for exactly `-> Self`, I think it's fine to just skip normalizing here, especially since The Correct Way<sup>TM</sup> would involve a probe and make this code even more complicated. Also, the code here does almost the same thing, and these suggestions can probably be unified in the future: https://github.com/rust-lang/rust/blob/4ca8078d37c53ee4ff8fb32b4453b915116f25b8/compiler/rustc_hir_typeck/src/method/suggest.rs#L2123-L2129 r? `@compiler-errors` cc `@Qelxiros` -- this should unblock rust-lang#144420
…iler-errors fix ICE when suggesting `::new` fixes rust-lang#146174 This code suggests to write `Foo::new(...)` when the user writes `Foo(...)` or `Foo { ... }` and the constructor is private, where `new` is some associated function that returns `Self`. When checking that the return type of `new` is `Self`, we need to instantiate the parameters of `new` with infer vars, so we don't end up with a type like `Box<$param(0)>` in a context that doesn't have any parameters. But then we can't use `normalize_erasing_late_bound_regions` anymore because that goes though a query that can't deal with infer vars. Since this is diagnostic-only code that is supposed to check for exactly `-> Self`, I think it's fine to just skip normalizing here, especially since The Correct Way<sup>TM</sup> would involve a probe and make this code even more complicated. Also, the code here does almost the same thing, and these suggestions can probably be unified in the future: https://github.com/rust-lang/rust/blob/4ca8078d37c53ee4ff8fb32b4453b915116f25b8/compiler/rustc_hir_typeck/src/method/suggest.rs#L2123-L2129 r? ```@compiler-errors``` cc ```@Qelxiros``` -- this should unblock rust-lang#144420
…iler-errors fix ICE when suggesting `::new` fixes rust-lang#146174 This code suggests to write `Foo::new(...)` when the user writes `Foo(...)` or `Foo { ... }` and the constructor is private, where `new` is some associated function that returns `Self`. When checking that the return type of `new` is `Self`, we need to instantiate the parameters of `new` with infer vars, so we don't end up with a type like `Box<$param(0)>` in a context that doesn't have any parameters. But then we can't use `normalize_erasing_late_bound_regions` anymore because that goes though a query that can't deal with infer vars. Since this is diagnostic-only code that is supposed to check for exactly `-> Self`, I think it's fine to just skip normalizing here, especially since The Correct Way<sup>TM</sup> would involve a probe and make this code even more complicated. Also, the code here does almost the same thing, and these suggestions can probably be unified in the future: https://github.com/rust-lang/rust/blob/4ca8078d37c53ee4ff8fb32b4453b915116f25b8/compiler/rustc_hir_typeck/src/method/suggest.rs#L2123-L2129 r? ````@compiler-errors```` cc ````@Qelxiros```` -- this should unblock rust-lang#144420
Rollup merge of #146217 - lukas-code:suggest-new-ice, r=compiler-errors fix ICE when suggesting `::new` fixes #146174 This code suggests to write `Foo::new(...)` when the user writes `Foo(...)` or `Foo { ... }` and the constructor is private, where `new` is some associated function that returns `Self`. When checking that the return type of `new` is `Self`, we need to instantiate the parameters of `new` with infer vars, so we don't end up with a type like `Box<$param(0)>` in a context that doesn't have any parameters. But then we can't use `normalize_erasing_late_bound_regions` anymore because that goes though a query that can't deal with infer vars. Since this is diagnostic-only code that is supposed to check for exactly `-> Self`, I think it's fine to just skip normalizing here, especially since The Correct Way<sup>TM</sup> would involve a probe and make this code even more complicated. Also, the code here does almost the same thing, and these suggestions can probably be unified in the future: https://github.com/rust-lang/rust/blob/4ca8078d37c53ee4ff8fb32b4453b915116f25b8/compiler/rustc_hir_typeck/src/method/suggest.rs#L2123-L2129 r? ````@compiler-errors```` cc ````@Qelxiros```` -- this should unblock #144420
Tracking issue: #144419