Skip to content
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

Fix #124275: Implemented Default for Arc<str> #124367

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Aityz
Copy link

@Aityz Aityz commented Apr 25, 2024

This implements Default for Arc<str> in library/alloc/src/boxed.rs, fixing #124275

@rustbot
Copy link
Collaborator

rustbot commented Apr 25, 2024

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @jhpratt (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added 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. labels Apr 25, 2024
@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-17 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
#17 exporting to docker image format
#17 sending tarball 29.4s done
#17 DONE 44.7s
##[endgroup]
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-17]
---
sccache: Starting the server...
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-17', '--enable-llvm-link-shared', '--set', 'rust.thin-lto-import-instr-limit=10', '--set', 'change-id=99999999', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--enable-new-symbol-mangling']
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-17/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.thin-lto-import-instr-limit := 10
configure: change-id            := 99999999
---
  Downloaded boml v0.3.1
   Compiling boml v0.3.1
   Compiling y v0.1.0 (/checkout/compiler/rustc_codegen_gcc/build_system)
    Finished `release` profile [optimized] target(s) in 3.41s
     Running `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-codegen/x86_64-unknown-linux-gnu/release/y test --use-system-gcc --use-backend gcc --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_gcc --release --mini-tests --std-tests`
Using system GCC
[BUILD] example
[AOT] mini_core_hello_world
/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_gcc/mini_core_hello_world
abc
---
---- [run-make] tests/run-make/alloc-no-rc stdout ----

error: make failed
status: exit status: 2
command: cd "/checkout/tests/run-make/alloc-no-rc" && env -u CARGO_MAKEFLAGS -u MAKEFLAGS -u MFLAGS -u RUSTFLAGS AR="ar" CC="cc -ffunction-sections -fdata-sections -fPIC -m64" CXX="c++ -ffunction-sections -fdata-sections -fPIC -m64" HOST_RPATH_DIR="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" LD_LIB_PATH_ENVVAR="LD_LIBRARY_PATH" LLVM_BIN_DIR="/usr/lib/llvm-17/bin" LLVM_COMPONENTS="aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils aggressiveinstcombine all all-targets amdgpu amdgpuasmparser amdgpucodegen amdgpudesc amdgpudisassembler amdgpuinfo amdgputargetmca amdgpuutils analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils asmparser asmprinter avr avrasmparser avrcodegen avrdesc avrdisassembler avrinfo binaryformat bitreader bitstreamreader bitwriter bpf bpfasmparser bpfcodegen bpfdesc bpfdisassembler bpfinfo cfguard codegen codegentypes core coroutines coverage debuginfobtf debuginfocodeview debuginfodwarf debuginfogsym debuginfologicalview debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker dwarflinkerparallel dwp engine executionengine extensions filecheck frontendhlsl frontendopenacc frontendopenmp fuzzercli fuzzmutate globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo instcombine instrumentation interfacestub interpreter ipo irprinter irreader jitlink lanai lanaiasmparser lanaicodegen lanaidesc lanaidisassembler lanaiinfo libdriver lineeditor linker loongarch loongarchasmparser loongarchcodegen loongarchdesc loongarchdisassembler loongarchinfo lto m68k m68kasmparser m68kcodegen m68kdesc m68kdisassembler m68kinfo mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts objcopy object objectyaml option orcjit orcshared orctargetprocess passes perfjitevents powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo riscvtargetmca runtimedyld scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target targetparser textapi transformutils ve veasmparser vecodegen vectorize vedesc vedisassembler veinfo webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo webassemblyutils windowsdriver windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86targetmca xcore xcorecodegen xcoredesc xcoredisassembler xcoreinfo xray xtensa xtensaasmparser xtensacodegen xtensadesc xtensadisassembler xtensainfo" LLVM_FILECHECK="/usr/lib/llvm-17/bin/FileCheck" NODE="/usr/bin/node" PYTHON="/usr/bin/python3" RUSTC="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" RUSTDOC="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" RUST_BUILD_STAGE="stage2-x86_64-unknown-linux-gnu" S="/checkout" TARGET="x86_64-unknown-linux-gnu" TARGET_RPATH_DIR="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" TMPDIR="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/alloc-no-rc/alloc-no-rc" "make"
--- stdout -------------------------------
LD_LIBRARY_PATH="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/alloc-no-rc/alloc-no-rc:/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release/deps:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/lib" '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc' --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/alloc-no-rc/alloc-no-rc -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/alloc-no-rc/alloc-no-rc  -Ainternal_features --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_rc
--- stderr -------------------------------
error[E0432]: unresolved import `crate::sync`
##[error]   --> ../../../library/alloc/src/boxed.rs:187:12
    |
---
---- [run-make] tests/run-make/alloc-no-sync stdout ----

error: make failed
status: exit status: 2
command: cd "/checkout/tests/run-make/alloc-no-sync" && env -u CARGO_MAKEFLAGS -u MAKEFLAGS -u MFLAGS -u RUSTFLAGS AR="ar" CC="cc -ffunction-sections -fdata-sections -fPIC -m64" CXX="c++ -ffunction-sections -fdata-sections -fPIC -m64" HOST_RPATH_DIR="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" LD_LIB_PATH_ENVVAR="LD_LIBRARY_PATH" LLVM_BIN_DIR="/usr/lib/llvm-17/bin" LLVM_COMPONENTS="aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils aggressiveinstcombine all all-targets amdgpu amdgpuasmparser amdgpucodegen amdgpudesc amdgpudisassembler amdgpuinfo amdgputargetmca amdgpuutils analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils asmparser asmprinter avr avrasmparser avrcodegen avrdesc avrdisassembler avrinfo binaryformat bitreader bitstreamreader bitwriter bpf bpfasmparser bpfcodegen bpfdesc bpfdisassembler bpfinfo cfguard codegen codegentypes core coroutines coverage debuginfobtf debuginfocodeview debuginfodwarf debuginfogsym debuginfologicalview debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker dwarflinkerparallel dwp engine executionengine extensions filecheck frontendhlsl frontendopenacc frontendopenmp fuzzercli fuzzmutate globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo instcombine instrumentation interfacestub interpreter ipo irprinter irreader jitlink lanai lanaiasmparser lanaicodegen lanaidesc lanaidisassembler lanaiinfo libdriver lineeditor linker loongarch loongarchasmparser loongarchcodegen loongarchdesc loongarchdisassembler loongarchinfo lto m68k m68kasmparser m68kcodegen m68kdesc m68kdisassembler m68kinfo mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts objcopy object objectyaml option orcjit orcshared orctargetprocess passes perfjitevents powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo riscvtargetmca runtimedyld scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target targetparser textapi transformutils ve veasmparser vecodegen vectorize vedesc vedisassembler veinfo webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo webassemblyutils windowsdriver windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86targetmca xcore xcorecodegen xcoredesc xcoredisassembler xcoreinfo xray xtensa xtensaasmparser xtensacodegen xtensadesc xtensadisassembler xtensainfo" LLVM_FILECHECK="/usr/lib/llvm-17/bin/FileCheck" NODE="/usr/bin/node" PYTHON="/usr/bin/python3" RUSTC="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" RUSTDOC="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" RUST_BUILD_STAGE="stage2-x86_64-unknown-linux-gnu" S="/checkout" TARGET="x86_64-unknown-linux-gnu" TARGET_RPATH_DIR="/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" TMPDIR="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/alloc-no-sync/alloc-no-sync" "make"
--- stdout -------------------------------
LD_LIBRARY_PATH="/checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/alloc-no-sync/alloc-no-sync:/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-bootstrap-tools/x86_64-unknown-linux-gnu/release/deps:/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/lib" '/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc' --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/alloc-no-sync/alloc-no-sync -L /checkout/obj/build/x86_64-unknown-linux-gnu/test/run-make/alloc-no-sync/alloc-no-sync  -Ainternal_features --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_sync
--- stderr -------------------------------
error[E0432]: unresolved import `crate::sync`
##[error]   --> ../../../library/alloc/src/boxed.rs:187:12
    |

@clubby789 clubby789 linked an issue Apr 25, 2024 that may be closed by this pull request
@@ -1284,6 +1287,15 @@ impl Default for Box<str> {
}
}

#[cfg(not(no_global_oom_handling))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[cfg(not(no_global_oom_handling))]
#[cfg(all(not(no_global_oom_handling), not(no_rc)))]

@zachs18
Copy link
Contributor

zachs18 commented Apr 25, 2024

Is there a particular reason this is done in library/alloc/src/boxed.rs and not library/alloc/src/sync.rs where Arc itself is defined? Implementing it there would make the cfg(not(no_rc)) not necessary, since alloc::sync itself doesn't exist under --cfg no_rc.

It might also make sense to implement Default for other Arc<U> for dynamically-sized types with a default Box<U> implementation, such as [T], CStr, OsStr, though that doesn't have to happen in this PR. Similarly, Rc<U> could have default impls for those types, in library/alloc/src/rc.rs.

@Aityz
Copy link
Author

Aityz commented Apr 25, 2024

Is there a particular reason this is done in library/alloc/src/boxed.rs and not library/alloc/src/sync.rs where Arc itself is defined? Implementing it there would make the cfg(not(no_rc)) not necessary, since alloc::sync itself doesn't exist under --cfg no_rc.

It might also make sense to implement Default for other Arc<U> for dynamically-sized types with a default Box<U> implementation, such as [T], CStr, OsStr, though that doesn't have to happen in this PR. Similarly, Rc<U> could have default impls for those types, in library/alloc/src/rc.rs.

boxed.rs has implementations for Box<str> while library/alloc/src/sync.rs has no implementations like that whatsoever. However, I believe your solution makes more sense.

@jhpratt jhpratt added the I-libs-api-nominated The issue / PR has been nominated for discussion during a libs-api team meeting. label Apr 25, 2024
@m-ou-se m-ou-se added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. needs-fcp This change is insta-stable, so needs a completed FCP to proceed. and removed T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 30, 2024
@joshtriplett
Copy link
Member

We discussed this in today's libs-api meeting and it seems reasonable.

We would like to see the additional impls for:

  • Arc<CStr>
  • Arc<OsStr>
  • Rc<str>
  • Rc<CStr>
  • Rc<OsStr>

Starting a libs-api FCP to confirm that we want to approve these six impls:

@rfcbot merge

@rfcbot
Copy link

rfcbot commented Apr 30, 2024

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Apr 30, 2024
@rfcbot
Copy link

rfcbot commented Apr 30, 2024

🔔 This is now entering its final comment period, as per the review above. 🔔

@rfcbot rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Apr 30, 2024
@Amanieu
Copy link
Member

Amanieu commented Apr 30, 2024

We would like to see the additional impls for:

Also Rc<[T]> and Arc<[T]>, for symmetry with Box<[T]>.

@Billy-Sheppard
Copy link

Billy-Sheppard commented May 3, 2024

We discussed this in today's libs-api meeting and it seems reasonable.

We would like to see the additional impls for:

  • Arc<CStr>
  • Arc<OsStr>
  • Rc<str>
  • Rc<CStr>
  • Rc<OsStr>

Starting a libs-api FCP to confirm that we want to approve these six impls:

Also Rc<[T]> and Arc<[T]>, for symmetry with Box<[T]>.

I've implemented these on my branch here https://github.com/Billy-Sheppard/rust/tree/81b0331cc7a298f79ced7aec395510379df8fa1b

I've had a guess at the best locations/feature attrs for them but they might not be correct.
Should these changes come in, in a separate PR?

However I'm unclear how to get the OsStr impl to compile, which file should they go in to avoid the error below? Is it possible, perhaps with some special std rust lib magic?

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
    --> library/std/src/ffi/os_str.rs:1350:1
     |
1350 | impl Default for Arc<OsStr> {
     | ^^^^^^^^^^^^^^^^^----------
     | |                |
     | |                `Arc` is not defined in the current crate
     | impl doesn't use only types from inside the current crate
     |
     = note: define and implement a trait or new type instead

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
    --> library/std/src/ffi/os_str.rs:1360:1
     |
1360 | impl Default for Rc<OsStr> {
     | ^^^^^^^^^^^^^^^^^---------
     | |                |
     | |                `Rc` is not defined in the current crate
     | impl doesn't use only types from inside the current crate
     |
     = note: define and implement a trait or new type instead

For more information about this error, try `rustc --explain E0117`.

@Aityz
Copy link
Author

Aityz commented May 3, 2024

Import the struct, or implement where it's defined?

@zachs18
Copy link
Contributor

zachs18 commented May 3, 2024

impl Default for Arc<OsStr> (or Rc<OsStr>) will run into the orphan rules since OsStr is in std, but Arc is from alloc and is not #[fundamental] like Box is. I don't know if there's a rustc magic attribute to ignore impl coherence rules. It could probably be worked around with an (unstable) DefaultInArc trait (described below). It might make sense to skip Arc<OsStr> and Rc<OsStr> for now to not block the other ones.

DefaultInArc
// alloc::sync
pub trait DefaultInArc {
    fn default_arc() -> Arc<Self>;
}
impl<T: Default> DefaultInArc for T { /* call T::default() */ }
impl<T> DefaultInArc for [T] { /* empty slice */
impl DefaultInArc for str { /* empty string */ }
impl DefaultInArc for CStr { /* single NUL byte */ }

impl<T: DefaultInArc + ?Sized> Default for Arc<T>;

// std::sync (or maybe std::ffi)
impl DefaultInArc for OsStr { /* empty slice */ }

(similar for DefaultInRc, or perhaps they could be in the same trait)

This is the same coherence workaround that bytemuck::PodInOption uses to allow downstream crates to implement bytemuck::Pod for core::Option<downstream_crate::LocalType>, which would be disallowed as a direct impl in downstream_crate.

Edit: Alternately, we could just have a blanket impl<T: ?Sized> Default for Arc<T> where Box<T>: Default { /* use Arc::from(Box::default()) */ }, perhaps using specialization to make Arc<T: Sized>/Arc<CStr> not do two allocations.

@Billy-Sheppard
Copy link

Billy-Sheppard commented May 3, 2024

impl Default for Arc<OsStr> (or Rc<OsStr>) will run into the orphan rules since OsStr is in std, but Arc is from alloc and is not #[fundamental] like Box is. I don't know if there's a rustc magic attribute to ignore impl coherence rules. It could probably be worked around with an (unstable) DefaultInArc trait (described below). It might make sense to skip Arc<OsStr> and Rc<OsStr> for now to not block the other ones.

DefaultInArc

This is what I assumed was going on. I'll let some others from the libs-api team chime in. I'm happy to put my code in a separate PR for this discussion but didn't want to clobber the OPs work.

(Edit: I drafted one JIC, but happy to dismiss pending others thoughts.)

@joshtriplett
Copy link
Member

I would propose we skip the OsStr impls for now due to this issue, and merge the rest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. I-libs-api-nominated The issue / PR has been nominated for discussion during a libs-api team meeting. needs-fcp This change is insta-stable, so needs a completed FCP to proceed. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Arc<str> does not have a Default impl