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

initial SPARC support #38314

Merged
merged 4 commits into from
Dec 26, 2016
Merged

Conversation

japaric
Copy link
Member

@japaric japaric commented Dec 12, 2016

UPDATE

Can now compile no_std executables with:

$ cargo new --bin app && cd $_

$ edit Cargo.toml && tail -n2 $_
[dependencies]
core = { path = "/path/to/rust/src/libcore" }

$ edit src/main.rs && cat $_
#![feature(lang_items)]
#![no_std]
#![no_main]

#[no_mangle]
pub fn _start() -> ! {
    loop {}
}

#[lang = "panic_fmt"]
fn panic_fmt() -> ! {
    loop {}
}

$ edit sparc-none-elf.json && cat $_
{
  "arch": "sparc",
  "data-layout": "E-m:e-p:32:32-i64:64-f128:64-n32-S64",
  "executables": true,
  "llvm-target": "sparc",
  "os": "none",
  "panic-strategy": "abort",
  "target-endian": "big",
  "target-pointer-width": "32"
}

$ cargo rustc --target sparc-none-elf -- -C linker=sparc-unknown-elf-gcc -C link-args=-nostartfiles

$ file target/sparc-none-elf/debug/app
app: ELF 32-bit MSB executable, SPARC, version 1 (SYSV), statically linked, not stripped

$ sparc-unknown-elf-readelf -h target/sparc-none-elf/debug/app
ELF Header:
  Magic:   7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Sparc
  Version:                           0x1
  Entry point address:               0x10074
  Start of program headers:          52 (bytes into file)
  Start of section headers:          1188 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         14
  Section header string table index: 11

$ sparc-unknown-elf-objdump -Cd target/sparc-none-elf/debug/app

target/sparc-none-elf/debug/app:     file format elf32-sparc


Disassembly of section .text:

00010074 <_start>:
   10074:       9d e3 bf 98     save  %sp, -104, %sp
   10078:       10 80 00 02     b  10080 <_start+0xc>
   1007c:       01 00 00 00     nop
   10080:       10 80 00 02     b  10088 <_start+0x14>
   10084:       01 00 00 00     nop
   10088:       10 80 00 00     b  10088 <_start+0x14>
   1008c:       01 00 00 00     nop

Someone wants to attempt launching some Rust into space but their platform is based on the SPARCv8 architecture. Let's not block them by enabling LLVM's SPARC backend.

Something very important that they'll also need is the "cabi" stuff as they'll be embedding some Rust code into a bigger C application (i.e. heavy use of extern "C"). The question there is what name(s) should we use for "target_arch" as the "cabi" implementation varies according to that parameter.

AFAICT, SPARCv8 is a 32-bit architecture and SPARCv9 is a 64-bit architecture. And, LLVM uses sparc, sparcv9 and sparcel for the architecture triple so perhaps we should use target_arch = "sparc" (32-bit) and target_arch = "sparcv9" (64-bit) as well.

r? @alexcrichton This PR only enables this LLVM backend when rustbuild is used. Do I also need to implement this for the old Makefile-based build system? Or are all our nightlies now being generated using rustbuild?

cc @brson

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@myrrlyn
Copy link

myrrlyn commented Dec 12, 2016

Yup, I'm the Rust-in-space guy. I hope. I'm currently assigned to writing communications drivers (basically a weird hybrid of IEEE1394 and I2C), and have three or four months before those are due and two or so years before flight, at current schedule.

My work will sit between a VxWorks kernel and a sensor array, so I'll have to expose C-compatible symbols to match the kernel's expectations on top, and read directly from hardware on the bottom. I'll do my best to get any necessary information as I can.

@japaric
Copy link
Member Author

japaric commented Dec 12, 2016

Marking as WIP for now as I'd like to add the cabi stuff and test compiling/linking a no_std binary before merging this.

@japaric japaric changed the title enable LLVM's SPARC backend [WIP] initial SPARC support Dec 12, 2016
@alexcrichton
Copy link
Member

Sounds good to me! I'm fine landing this whenever. And yeah as soon as we have new nightlies they'll all be produced with rustbuild, so I believe there's no longer any need to change the makefiles.

@japaric feel free to just ping me whenever this is ready to go.

@japaric
Copy link
Member Author

japaric commented Dec 12, 2016

Pushed the cabi stuff for 32-bit SPARC. Also added instructions on how to build a no_std executable for 32-bit SPARC to the top comment.

r? @alexcrichton The cabi stuff is the same as cabi_mips, which is also 32 bits.

@japaric japaric changed the title [WIP] initial SPARC support initial SPARC support Dec 12, 2016
@alexcrichton
Copy link
Member

Oh right can you also be sure to touch src/rustllvm/llvm-auto-clean-trigger? We'll want to be sure to rebuild LLVM with this change.

@japaric
Copy link
Member Author

japaric commented Dec 13, 2016

Oh right can you also be sure to touch src/rustllvm/llvm-auto-clean-trigger?

Done.

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Dec 13, 2016

📌 Commit b53d1e9 has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Dec 14, 2016

⌛ Testing commit b53d1e9 with merge c65d510...

@bors
Copy link
Contributor

bors commented Dec 14, 2016

💔 Test failed - auto-win-msvc-32-opt

@sanxiyn
Copy link
Member

sanxiyn commented Dec 14, 2016

Failed tidy for line length...

@japaric
Copy link
Member Author

japaric commented Dec 14, 2016

@bors r=alexcrichton

@bors
Copy link
Contributor

bors commented Dec 14, 2016

📌 Commit 614c533 has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Dec 14, 2016

⌛ Testing commit 614c533 with merge e3937b0...

@bors
Copy link
Contributor

bors commented Dec 14, 2016

💔 Test failed - auto-linux-64-opt

@alexcrichton
Copy link
Member

wut

c++: internal compiler error: Killed (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-5/README.Bugs> for instructions.
make[3]: *** [lib/Target/X86/CMakeFiles/LLVMX86CodeGen.dir/X86ISelLowering.cpp.o] Error 4

@myrrlyn
Copy link

myrrlyn commented Dec 14, 2016

That got weird...

@japaric
Copy link
Member Author

japaric commented Dec 14, 2016

c++: internal compiler error: Killed (program cc1plus)

Achievement unlocked

make[3]: *** [lib/Target/X86/CMakeFiles/LLVMX86CodeGen.dir/X86ISelLowering.cpp.o] Error 4

That's not even SPARC stuff!

FWIW, I tested this stuff in an Ubuntu 16.04 (Docker) container. I also used --enable-ninja and --enable-ccache (I have a cache that I share across all my rust-dev containers); I don't know if that matters at all.

@alexcrichton
Copy link
Member

@japaric the container that bot is using is alexcrichton/rust-slave-linux:2016-11-11 and I believe it's just using standard makefiles. Could you try building in there and see if it reproduces? If it doesn't we can maybe assume it was spurious and send it back to bors.

@japaric
Copy link
Member Author

japaric commented Dec 15, 2016

@alexcrichton Can't repro locally; tested twice with the some configure/make commands. One thing I did notice is that the buildbot calls make -j2 but the -j2 bit is ignored now that rustbuild is the default, so the build used all the available cores/threads. Could that be the problem? Too much parallelism -> too much memory usage -> OOM or something?

@alexcrichton
Copy link
Member

@bors: retry

Ok, let's find out

@bors
Copy link
Contributor

bors commented Dec 15, 2016

⌛ Testing commit 614c533 with merge 35cb0b8...

@bors
Copy link
Contributor

bors commented Dec 15, 2016

💔 Test failed - auto-linux-32-opt

@alexcrichton
Copy link
Member

@japaric #38411 interestingly landed, so... confused

@japaric
Copy link
Member Author

japaric commented Dec 19, 2016

There goes my theory ...

So we could (a) retry to see if anything changed (wishful thinking), (b) reduce the number of LLVM jobs (enabling SPARC may have been the tipping point ...) or (c) upgrade the buildbots' gcc (this could be a gcc bug).

Who wants to roll the dice?

@japaric japaric force-pushed the do-not-delete-enable-llvm-backend branch from 56fb169 to 8581477 Compare December 19, 2016 17:22
@japaric japaric force-pushed the do-not-delete-enable-llvm-backend branch from 8581477 to 3ae912a Compare December 19, 2016 17:24
@myrrlyn
Copy link

myrrlyn commented Dec 19, 2016

Hot dang, a successful build!


Okay so this particular issue is still in the air, but Rust builds in general are back on, which is still exciting.

@alexcrichton
Copy link
Member

@japaric I don't think this'll land as the relevant source file wouldn't have changed, right? The backport didn't touch the failing file?

I still don't think this is OOM as it's failing in deterministically in the same location, which seems pretty unlikely (although not impossible) for OOM. My gut says that the easiest route for fixing this would be to update gcc on the bots.

@japaric when you said you weren't able to reproduce this on the bots, are you sure that you were running the exact same setup, paths and all, as the bots?

@japaric
Copy link
Member Author

japaric commented Dec 19, 2016

@myrrlyn The travis builds don't (re)build LLVM.

@alexcrichton I just tried yet again. This time using the same path (+ same configure & make) as the buildbot but still can't repro. shrugs

I don't think this'll land as the relevant source file wouldn't have changed, right? The backport didn't touch the failing file?

No, it didn't. I did say it was wishful thinking.

@alexcrichton
Copy link
Member

Well we can at least see what happens I supppose!

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Dec 20, 2016

📌 Commit 3ae912a has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Dec 21, 2016

⌛ Testing commit 3ae912a with merge 8c0ea26...

@bors
Copy link
Contributor

bors commented Dec 21, 2016

💔 Test failed - auto-linux-64-nopt-t

@alexcrichton
Copy link
Member

Looks like another PR failed in a very similar way, which in my mind makes OOM far more likely as a cause here.

@glaubitz
Copy link
Contributor

Just as a heads-up: Debian is currently brushing up sparc64 support and Oracle invests heavily on Linux for SPARC (they even have their own Linux distribution for SPARC). So, having SPARC support in Rust wouldn't just profit astronauts :).

@japaric
Copy link
Member Author

japaric commented Dec 23, 2016

@glaubitz Linux on SPARC(v9) is going to need way more work than this but, in any case, this has to land first 😄.

@alexcrichton I see that #38427 landed. Did something change on the build bots? Did they get more RAM or something?

@alexcrichton
Copy link
Member

@bors: retry

@japaric nah nothing changes, but we're gating on Travis/AppVeyor now, so let's see if this gets past them.

@bors
Copy link
Contributor

bors commented Dec 26, 2016

⌛ Testing commit 3ae912a with merge b7e5148...

bors added a commit that referenced this pull request Dec 26, 2016
…lexcrichton

initial SPARC support

### UPDATE

Can now compile `no_std` executables with:

```
$ cargo new --bin app && cd $_

$ edit Cargo.toml && tail -n2 $_
[dependencies]
core = { path = "/path/to/rust/src/libcore" }

$ edit src/main.rs && cat $_
#![feature(lang_items)]
#![no_std]
#![no_main]

#[no_mangle]
pub fn _start() -> ! {
    loop {}
}

#[lang = "panic_fmt"]
fn panic_fmt() -> ! {
    loop {}
}

$ edit sparc-none-elf.json && cat $_
{
  "arch": "sparc",
  "data-layout": "E-m:e-p:32:32-i64:64-f128:64-n32-S64",
  "executables": true,
  "llvm-target": "sparc",
  "os": "none",
  "panic-strategy": "abort",
  "target-endian": "big",
  "target-pointer-width": "32"
}

$ cargo rustc --target sparc-none-elf -- -C linker=sparc-unknown-elf-gcc -C link-args=-nostartfiles

$ file target/sparc-none-elf/debug/app
app: ELF 32-bit MSB executable, SPARC, version 1 (SYSV), statically linked, not stripped

$ sparc-unknown-elf-readelf -h target/sparc-none-elf/debug/app
ELF Header:
  Magic:   7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Sparc
  Version:                           0x1
  Entry point address:               0x10074
  Start of program headers:          52 (bytes into file)
  Start of section headers:          1188 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         14
  Section header string table index: 11

$ sparc-unknown-elf-objdump -Cd target/sparc-none-elf/debug/app

target/sparc-none-elf/debug/app:     file format elf32-sparc

Disassembly of section .text:

00010074 <_start>:
   10074:       9d e3 bf 98     save  %sp, -104, %sp
   10078:       10 80 00 02     b  10080 <_start+0xc>
   1007c:       01 00 00 00     nop
   10080:       10 80 00 02     b  10088 <_start+0x14>
   10084:       01 00 00 00     nop
   10088:       10 80 00 00     b  10088 <_start+0x14>
   1008c:       01 00 00 00     nop
```

---

Someone wants to attempt launching some Rust [into space](https://www.reddit.com/r/rust/comments/5h76oa/c_interop/) but their platform is based on the SPARCv8 architecture. Let's not block them by enabling LLVM's SPARC backend.

Something very important that they'll also need is the "cabi" stuff as they'll be embedding some Rust code into a bigger C application (i.e. heavy use of `extern "C"`). The question there is what name(s) should we use for "target_arch" as the "cabi" implementation [varies according to that parameter](https://github.com/rust-lang/rust/blob/1.13.0/src/librustc_trans/abi.rs#L498-L523).

AFAICT, SPARCv8 is a 32-bit architecture and SPARCv9 is a 64-bit architecture. And, LLVM uses `sparc`, `sparcv9` and `sparcel` for [the architecture triple](https://github.com/rust-lang/llvm/blob/ac1c94226e9fa17005ce7e2dd52dd6d1875f3137/include/llvm/ADT/Triple.h#L67-L69) so perhaps we should use `target_arch = "sparc"` (32-bit) and `target_arch = "sparcv9"` (64-bit) as well.

r? @alexcrichton This PR only enables this LLVM backend when rustbuild is used. Do I also need to implement this for the old Makefile-based build system? Or are all our nightlies now being generated using rustbuild?

cc @brson
@bors
Copy link
Contributor

bors commented Dec 26, 2016

☀️ Test successful - status-appveyor, status-travis
Approved by: alexcrichton
Pushing b7e5148 to master...

@bors bors merged commit 3ae912a into rust-lang:master Dec 26, 2016
@bors bors mentioned this pull request Dec 26, 2016
@japaric japaric deleted the do-not-delete-enable-llvm-backend branch December 27, 2016 01:50
jsonn pushed a commit to jsonn/pkgsrc that referenced this pull request Mar 20, 2017
Version 1.16.0 (2017-03-16)
===========================

Language
--------

* Lifetimes in statics and consts default to `'static`. [RFC 1623]
* [The compiler's `dead_code` lint now accounts for type aliases][38051].
* [Uninhabitable enums (those without any variants) no longer permit wildcard
  match patterns][38069]
* [Clean up semantics of `self` in an import list][38313]
* [`Self` may appear in `impl` headers][38920]
* [`Self` may appear in struct expressions][39282]

Compiler
--------

* [`rustc` now supports `--emit=metadata`, which causes rustc to emit
  a `.rmeta` file containing only crate metadata][38571]. This can be
  used by tools like the Rust Language Service to perform
  metadata-only builds.
* [Levenshtein based typo suggestions now work in most places, while
  previously they worked only for fields and sometimes for local
  variables][38927]. Together with the overhaul of "no
  resolution"/"unexpected resolution" errors (#[38154]) they result in
  large and systematic improvement in resolution diagnostics.
* [Fix `transmute::<T, U>` where `T` requires a bigger alignment than
  `U`][38670]
* [rustc: use -Xlinker when specifying an rpath with ',' in it][38798]
* [`rustc` no longer attempts to provide "consider using an explicit
  lifetime" suggestions][37057]. They were inaccurate.

Stabilized APIs
---------------

* [`VecDeque::truncate`]
* [`VecDeque::resize`]
* [`String::insert_str`]
* [`Duration::checked_add`]
* [`Duration::checked_sub`]
* [`Duration::checked_div`]
* [`Duration::checked_mul`]
* [`str::replacen`]
* [`str::repeat`]
* [`SocketAddr::is_ipv4`]
* [`SocketAddr::is_ipv6`]
* [`IpAddr::is_ipv4`]
* [`IpAddr::is_ipv6`]
* [`Vec::dedup_by`]
* [`Vec::dedup_by_key`]
* [`Result::unwrap_or_default`]
* [`<*const T>::wrapping_offset`]
* [`<*mut T>::wrapping_offset`]
* `CommandExt::creation_flags`
* [`File::set_permissions`]
* [`String::split_off`]

Libraries
---------

* [`[T]::binary_search` and `[T]::binary_search_by_key` now take
  their argument by `Borrow` parameter][37761]
* [All public types in std implement `Debug`][38006]
* [`IpAddr` implements `From<Ipv4Addr>` and `From<Ipv6Addr>`][38327]
* [`Ipv6Addr` implements `From<[u16; 8]>`][38131]
* [Ctrl-Z returns from `Stdin.read()` when reading from the console on
  Windows][38274]
* [std: Fix partial writes in `LineWriter`][38062]
* [std: Clamp max read/write sizes on Unix][38062]
* [Use more specific panic message for `&str` slicing errors][38066]
* [`TcpListener::set_only_v6` is deprecated][38304]. This
  functionality cannot be achieved in std currently.
* [`writeln!`, like `println!`, now accepts a form with no string
  or formatting arguments, to just print a newline][38469]
* [Implement `iter::Sum` and `iter::Product` for `Result`][38580]
* [Reduce the size of static data in `std_unicode::tables`][38781]
* [`char::EscapeDebug`, `EscapeDefault`, `EscapeUnicode`,
  `CaseMappingIter`, `ToLowercase`, `ToUppercase`, implement
  `Display`][38909]
* [`Duration` implements `Sum`][38712]
* [`String` implements `ToSocketAddrs`][39048]

Cargo
-----

* [The `cargo check` command does a type check of a project without
  building it][cargo/3296]
* [crates.io will display CI badges from Travis and AppVeyor, if
  specified in Cargo.toml][cargo/3546]
* [crates.io will display categories listed in Cargo.toml][cargo/3301]
* [Compilation profiles accept integer values for `debug`, in addition
  to `true` and `false`. These are passed to `rustc` as the value to
  `-C debuginfo`][cargo/3534]
* [Implement `cargo --version --verbose`][cargo/3604]
* [All builds now output 'dep-info' build dependencies compatible with
  make and ninja][cargo/3557]
* [Build all workspace members with `build --all`][cargo/3511]
* [Document all workspace members with `doc --all`][cargo/3515]
* [Path deps outside workspace are not members][cargo/3443]

Misc
----

* [`rustdoc` has a `--sysroot` argument that, like `rustc`, specifies
  the path to the Rust implementation][38589]
* [The `armv7-linux-androideabi` target no longer enables NEON
  extensions, per Google's ABI guide][38413]
* [The stock standard library can be compiled for Redox OS][38401]
* [Rust has initial SPARC support][38726]. Tier 3. No builds
  available.
* [Rust has experimental support for Nvidia PTX][38559]. Tier 3. No
  builds available.
* [Fix backtraces on i686-pc-windows-gnu by disabling FPO][39379]

Compatibility Notes
-------------------

* [Uninhabitable enums (those without any variants) no longer permit wildcard
  match patterns][38069]
* In this release, references to uninhabited types can not be
  pattern-matched. This was accidentally allowed in 1.15.
* [The compiler's `dead_code` lint now accounts for type aliases][38051].
* [Ctrl-Z returns from `Stdin.read()` when reading from the console on
  Windows][38274]
* [Clean up semantics of `self` in an import list][38313]

[37057]: rust-lang/rust#37057
[37761]: rust-lang/rust#37761
[38006]: rust-lang/rust#38006
[38051]: rust-lang/rust#38051
[38062]: rust-lang/rust#38062
[38062]: rust-lang/rust#38622
[38066]: rust-lang/rust#38066
[38069]: rust-lang/rust#38069
[38131]: rust-lang/rust#38131
[38154]: rust-lang/rust#38154
[38274]: rust-lang/rust#38274
[38304]: rust-lang/rust#38304
[38313]: rust-lang/rust#38313
[38314]: rust-lang/rust#38314
[38327]: rust-lang/rust#38327
[38401]: rust-lang/rust#38401
[38413]: rust-lang/rust#38413
[38469]: rust-lang/rust#38469
[38559]: rust-lang/rust#38559
[38571]: rust-lang/rust#38571
[38580]: rust-lang/rust#38580
[38589]: rust-lang/rust#38589
[38670]: rust-lang/rust#38670
[38712]: rust-lang/rust#38712
[38726]: rust-lang/rust#38726
[38781]: rust-lang/rust#38781
[38798]: rust-lang/rust#38798
[38909]: rust-lang/rust#38909
[38920]: rust-lang/rust#38920
[38927]: rust-lang/rust#38927
[39048]: rust-lang/rust#39048
[39282]: rust-lang/rust#39282
[39379]: rust-lang/rust#39379
[`<*const T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset
[`<*mut T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset
[`Duration::checked_add`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_add
[`Duration::checked_div`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_div
[`Duration::checked_mul`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_mul
[`Duration::checked_sub`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_sub
[`File::set_permissions`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.set_permissions
[`IpAddr::is_ipv4`]: https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_ipv4
[`IpAddr::is_ipv6`]: https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_ipv6
[`Result::unwrap_or_default`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_default
[`SocketAddr::is_ipv4`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html#method.is_ipv4
[`SocketAddr::is_ipv6`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html#method.is_ipv6
[`String::insert_str`]: https://doc.rust-lang.org/std/string/struct.String.html#method.insert_str
[`String::split_off`]: https://doc.rust-lang.org/std/string/struct.String.html#method.split_off
[`Vec::dedup_by_key`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.dedup_by_key
[`Vec::dedup_by`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.dedup_by
[`VecDeque::resize`]:  https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.resize
[`VecDeque::truncate`]: https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.truncate
[`str::repeat`]: https://doc.rust-lang.org/std/primitive.str.html#method.repeat
[`str::replacen`]: https://doc.rust-lang.org/std/primitive.str.html#method.replacen
[cargo/3296]: rust-lang/cargo#3296
[cargo/3301]: rust-lang/cargo#3301
[cargo/3443]: rust-lang/cargo#3443
[cargo/3511]: rust-lang/cargo#3511
[cargo/3515]: rust-lang/cargo#3515
[cargo/3534]: rust-lang/cargo#3534
[cargo/3546]: rust-lang/cargo#3546
[cargo/3557]: rust-lang/cargo#3557
[cargo/3604]: rust-lang/cargo#3604
[RFC 1623]: https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants