Skip to content

Conversation

Qelxiros
Copy link
Contributor

@Qelxiros Qelxiros commented Jul 24, 2025

Tracking issue: #144419

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 24, 2025
@rust-log-analyzer

This comment has been minimized.

@Qelxiros Qelxiros marked this pull request as ready for review July 25, 2025 00:12
@rustbot
Copy link
Collaborator

rustbot commented Jul 25, 2025

r? @thomcc

rustbot has assigned @thomcc.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jul 25, 2025
@Qelxiros
Copy link
Contributor Author

As far as I can tell, the ICE here is because of the function signature of Box::try_map. The return type is equivalent to ChangeOutputType<...> from the ACP, but that definition is in core, so I implemented it manually here. However, when I add the same type alias to alloc, the ICE persists. Is there a workaround here that remains in the spirit of the ACP? Is this a known compiler bug?

Copy link
Member

@joboet joboet left a 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?

View changes since this review

@Qelxiros Qelxiros force-pushed the smart_pointer_try_map branch from d5d5fea to 929d326 Compare September 2, 2025 20:53
@rustbot

This comment has been minimized.

@Qelxiros Qelxiros force-pushed the smart_pointer_try_map branch from 929d326 to 6a69f39 Compare September 2, 2025 20:57
@rustbot
Copy link
Collaborator

rustbot commented Sep 2, 2025

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.

@rust-log-analyzer

This comment has been minimized.

if size_of::<T>() == size_of::<U>() && align_of::<T>() == align_of::<U>() {
let ptr = &raw const *this;
unsafe {
let new = f(ptr.read());
Copy link
Member

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.

Copy link
Contributor Author

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.

@rust-log-analyzer

This comment has been minimized.


impl<T> Drop for Guard<T> {
fn drop(&mut self) {
let _box = unsafe { Box::from_raw(self.0) };
Copy link
Member

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.

Comment on lines 421 to 428
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>())
}
Copy link
Member

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.

Suggested change
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))

@Qelxiros Qelxiros force-pushed the smart_pointer_try_map branch from 64b65c1 to bfc61d6 Compare September 4, 2025 00:21
@rust-log-analyzer
Copy link
Collaborator

The job aarch64-gnu-llvm-19-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
To only update this specific test, also pass `--test-args parallel-rustc/ty-variance-issue-124423.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/parallel-rustc/ty-variance-issue-124423" "-A" "unused" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Z" "threads=16"
stdout: none
--- stderr -------------------------------
error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:8:15
   |
LL | fn elided(_: &impl Copy + 'a) -> _ { x }
   |               ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn elided(_: &(impl Copy + 'a)) -> _ { x }
   |               +              +

error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:13:24
   |
LL | fn explicit<'b>(_: &'a impl Copy + 'a) -> impl 'a { x }
   |                        ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn explicit<'b>(_: &'a (impl Copy + 'a)) -> impl 'a { x }
   |                        +              +

error: expected identifier, found keyword `impl`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:20:13
   |
LL | fn elided2( impl 'b) -> impl 'a + 'a { x }
   |             ^^^^ expected identifier, found keyword

error: expected one of `:` or `|`, found `'b`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:20:18
   |
LL | fn elided2( impl 'b) -> impl 'a + 'a { x }
   |                  ^^ expected one of `:` or `|`

error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:27:25
   |
LL | fn explicit2<'a>(_: &'a impl Copy + 'a) -> impl Copy + 'a { x }
   |                         ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn explicit2<'a>(_: &'a (impl Copy + 'a)) -> impl Copy + 'a { x }
   |                         +              +

error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:30:16
   |
LL | fn foo<'a>(_: &impl Copy + 'a) -> impl 'b + 'a { x }
   |                ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn foo<'a>(_: &(impl Copy + 'a)) -> impl 'b + 'a { x }
   |                +              +

error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:35:16
   |
LL | fn elided3(_: &impl Copy + 'a) -> Box<dyn 'a> { Box::new(x) }
   |                ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn elided3(_: &(impl Copy + 'a)) -> Box<dyn 'a> { Box::new(x) }
   |                +              +

error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:41:17
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |                 ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn x<'b>(_: &'a (impl Copy + 'a)) -> Box<dyn 'b> { Box::u32(x) }
   |                 +              +

error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:48:16
   |
LL | fn elided4(_: &impl Copy + 'a) ->  new  { x(x) }
   |                ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn elided4(_: &(impl Copy + 'a)) ->  new  { x(x) }
   |                +              +

error: at least one trait must be specified
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:13:43
   |
LL | fn explicit<'b>(_: &'a impl Copy + 'a) -> impl 'a { x }
   |                                           ^^^^^^^

error: at least one trait must be specified
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:20:25
   |
LL | fn elided2( impl 'b) -> impl 'a + 'a { x }
   |                         ^^^^^^^^^^^^

error: at least one trait must be specified
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:30:35
   |
LL | fn foo<'a>(_: &impl Copy + 'a) -> impl 'b + 'a { x }
   |                                   ^^^^^^^^^^^^

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:8:27
   |
LL | fn elided(_: &impl Copy + 'a) -> _ { x }
   |                           ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn elided<'a>(_: &impl Copy + 'a) -> _ { x }
   |          ++++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:13:21
   |
LL | fn explicit<'b>(_: &'a impl Copy + 'a) -> impl 'a { x }
   |                     ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn explicit<'a, 'b>(_: &'a impl Copy + 'a) -> impl 'a { x }
   |             +++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:13:36
   |
LL | fn explicit<'b>(_: &'a impl Copy + 'a) -> impl 'a { x }
   |                                    ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn explicit<'a, 'b>(_: &'a impl Copy + 'a) -> impl 'a { x }
   |             +++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:13:48
   |
LL | fn explicit<'b>(_: &'a impl Copy + 'a) -> impl 'a { x }
   |                                                ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn explicit<'a, 'b>(_: &'a impl Copy + 'a) -> impl 'a { x }
   |             +++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:20:30
   |
LL | fn elided2( impl 'b) -> impl 'a + 'a { x }
   |                              ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn elided2<'a>( impl 'b) -> impl 'a + 'a { x }
   |           ++++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:20:35
   |
LL | fn elided2( impl 'b) -> impl 'a + 'a { x }
   |                                   ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn elided2<'a>( impl 'b) -> impl 'a + 'a { x }
   |           ++++

error[E0261]: use of undeclared lifetime name `'b`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:30:40
   |
LL | fn foo<'a>(_: &impl Copy + 'a) -> impl 'b + 'a { x }
   |                                        ^^ undeclared lifetime
   |
help: consider introducing lifetime `'b` here
   |
LL | fn foo<'b, 'a>(_: &impl Copy + 'a) -> impl 'b + 'a { x }
   |        +++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:35:28
   |
LL | fn elided3(_: &impl Copy + 'a) -> Box<dyn 'a> { Box::new(x) }
   |                            ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn elided3<'a>(_: &impl Copy + 'a) -> Box<dyn 'a> { Box::new(x) }
   |           ++++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:35:43
   |
LL | fn elided3(_: &impl Copy + 'a) -> Box<dyn 'a> { Box::new(x) }
   |                                           ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn elided3<'a>(_: &impl Copy + 'a) -> Box<dyn 'a> { Box::new(x) }
   |           ++++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:41:14
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |              ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn x<'a, 'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |      +++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:41:29
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |                             ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn x<'a, 'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |      +++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:48:28
   |
LL | fn elided4(_: &impl Copy + 'a) ->  new  { x(x) }
   |                            ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn elided4<'a>(_: &impl Copy + 'a) ->  new  { x(x) }
   |           ++++

error[E0412]: cannot find type `new` in this scope
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:48:36
   |
LL | fn elided4(_: &impl Copy + 'a) ->  new  { x(x) }
   |                                    ^^^ not found in this scope

error[E0224]: at least one trait is required for an object type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:55:40
   |
LL | impl<'a> LifetimeTrait<'a> for &'a Box<dyn 'a> {}
   |                                        ^^^^^^

error[E0224]: at least one trait is required for an object type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:35:39
   |
LL | fn elided3(_: &impl Copy + 'a) -> Box<dyn 'a> { Box::new(x) }
   |                                       ^^^^^^

error[E0224]: at least one trait is required for an object type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:41:40
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |                                        ^^^^^^

error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:8:34
   |
LL | fn elided(_: &impl Copy + 'a) -> _ { x }
   |                                  ^ not allowed in type signatures

error[E0599]: no function or associated item named `u32` found for struct `Box<_, _>` in the current scope
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-124423.rs:41:55
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |                                                       ^^^ function or associated item not found in `Box<_, _>`
   |
note: if you're trying to build a new `Box<_, _>` consider using one of the following associated functions:
      Box::<T>::new
      Box::<T>::new_uninit
      Box::<T>::new_zeroed
      Box::<T>::try_new
      and 23 others
---
To only update this specific test, also pass `--test-args parallel-rustc/ty-variance-issue-127971.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/parallel-rustc/ty-variance-issue-127971" "-A" "unused" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Z" "threads=16"
stdout: none
--- stderr -------------------------------
error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:8:15
   |
LL | fn elided(_: &impl Copy + 'a) -> _ { x }
   |               ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn elided(_: &(impl Copy + 'a)) -> _ { x }
   |               +              +

error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:13:16
   |
LL | fn foo<'a>(_: &impl Copy + 'a) -> impl 'b + 'a { x }
   |                ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn foo<'a>(_: &(impl Copy + 'a)) -> impl 'b + 'a { x }
   |                +              +

error: ambiguous `+` in a type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:18:17
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |                 ^^^^^^^^^^^^^^
   |
help: try adding parentheses
   |
LL | fn x<'b>(_: &'a (impl Copy + 'a)) -> Box<dyn 'b> { Box::u32(x) }
   |                 +              +

error: at least one trait must be specified
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:13:35
   |
LL | fn foo<'a>(_: &impl Copy + 'a) -> impl 'b + 'a { x }
   |                                   ^^^^^^^^^^^^

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:8:27
   |
LL | fn elided(_: &impl Copy + 'a) -> _ { x }
   |                           ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn elided<'a>(_: &impl Copy + 'a) -> _ { x }
   |          ++++

error[E0261]: use of undeclared lifetime name `'b`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:13:40
   |
LL | fn foo<'a>(_: &impl Copy + 'a) -> impl 'b + 'a { x }
   |                                        ^^ undeclared lifetime
   |
help: consider introducing lifetime `'b` here
   |
LL | fn foo<'b, 'a>(_: &impl Copy + 'a) -> impl 'b + 'a { x }
   |        +++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:18:14
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |              ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn x<'a, 'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |      +++

error[E0261]: use of undeclared lifetime name `'a`
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:18:29
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |                             ^^ undeclared lifetime
   |
help: consider introducing lifetime `'a` here
   |
LL | fn x<'a, 'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |      +++

error[E0224]: at least one trait is required for an object type
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:18:40
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |                                        ^^^^^^

error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:8:34
   |
LL | fn elided(_: &impl Copy + 'a) -> _ { x }
   |                                  ^ not allowed in type signatures

error[E0599]: no function or associated item named `u32` found for struct `Box<_, _>` in the current scope
##[error]  --> /checkout/tests/ui/parallel-rustc/ty-variance-issue-127971.rs:18:55
   |
LL | fn x<'b>(_: &'a impl Copy + 'a) -> Box<dyn 'b> { Box::u32(x) }
   |                                                       ^^^ function or associated item not found in `Box<_, _>`
   |
note: if you're trying to build a new `Box<_, _>` consider using one of the following associated functions:
      Box::<T>::new
      Box::<T>::new_uninit
      Box::<T>::new_zeroed
      Box::<T>::try_new
      and 23 others
---
---- [ui] tests/ui/privacy/suggest-box-new.rs stdout ----

error: Error: expected failure status (Some(1)) but received status Some(101).
status: exit status: 101
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/privacy/suggest-box-new.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/privacy/suggest-box-new" "-A" "unused" "-A" "internal_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers"
stdout: none
--- stderr -------------------------------
error[E0423]: expected function, tuple struct or tuple variant, found struct `std::collections::HashMap`
##[error]  --> /checkout/tests/ui/privacy/suggest-box-new.rs:14:13
   |
---
   |
LL -     let _ = std::collections::HashMap();
LL +     let _ = std::collections::HashMap::with_hasher(_);
   |
LL -     let _ = std::collections::HashMap();
LL +     let _ = std::collections::HashMap::with_capacity_and_hasher(_, _);
   |
help: consider using the `Default` trait
   |
LL |     let _ = <std::collections::HashMap as std::default::Default>::default();
   |             +                          ++++++++++++++++++++++++++++++++++

error[E0423]: cannot initialize a tuple struct which contains private fields
##[error]  --> /checkout/tests/ui/privacy/suggest-box-new.rs:8:19
   |
LL |         wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields
   |                   ^^^
   |
note: constructor is not visible here due to private fields
  --> /rustc/FAKE_PREFIX/library/alloc/src/boxed.rs:234:14
   |
   = note: private field
   |
   = note: private field
help: you might have meant to use an associated function to build this type
   |
LL -         wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields
LL -             wtf: None,
LL -             x: (),
LL -         })),
LL +         wtf: Some(Box::new(_)),
   |
LL -         wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields
LL -             wtf: None,
LL -             x: (),
LL -         })),
LL +         wtf: Some(Box::new_uninit()),
   |
LL -         wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields
LL -             wtf: None,
LL -             x: (),
LL -         })),
LL +         wtf: Some(Box::new_zeroed()),
   |
LL -         wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields
LL -             wtf: None,
LL -             x: (),
LL -         })),
LL +         wtf: Some(Box::new_in(_, _)),
   |
   = and 13 other candidates
help: consider using the `Default` trait
   |
LL -         wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields
LL +         wtf: Some(<Box as std::default::Default>::default()),
   |

error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields
##[error]  --> /checkout/tests/ui/privacy/suggest-box-new.rs:16:13
   |
---
   |
LL -     let _ = std::collections::HashMap {};
LL +     let _ = std::collections::HashMap::with_hasher(_);
   |
LL -     let _ = std::collections::HashMap {};
LL +     let _ = std::collections::HashMap::with_capacity_and_hasher(_, _);
   |
help: consider using the `Default` trait
   |
LL -     let _ = std::collections::HashMap {};
LL +     let _ = <std::collections::HashMap as std::default::Default>::default();

@Qelxiros
Copy link
Contributor Author

Qelxiros commented Sep 4, 2025

I'm not sure how to move forward given the ICE (issue #146174).

@rustbot label +S-blocked

@rustbot rustbot added the S-blocked Status: Blocked on something else such as an RFC or other implementation work. label Sep 4, 2025
tgross35 added a commit to tgross35/rust that referenced this pull request Sep 5, 2025
…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
tgross35 added a commit to tgross35/rust that referenced this pull request Sep 5, 2025
…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
tgross35 added a commit to tgross35/rust that referenced this pull request Sep 5, 2025
…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
rust-timer added a commit that referenced this pull request Sep 5, 2025
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-blocked Status: Blocked on something else such as an RFC or other implementation work. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants