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

Refactor libcore out of libstd #13901

Merged
merged 43 commits into from May 7, 2014
Merged

Refactor libcore out of libstd #13901

merged 43 commits into from May 7, 2014

Conversation

alexcrichton
Copy link
Member

This is the second step in implementing #13851. This PR cannot currently land until a snapshot exists with #13892, but I imagine that this review will take longer.

This PR refactors a large amount of functionality outside of the standard library into a new library, libcore. This new library has 0 dependencies (in theory). In practice, this library currently depends on these symbols being available:

  • rust_begin_unwind and rust_fail_bounds_check - These are the two entry points of failure in libcore. The symbols are provided by libstd currently. In the future (see the bullets on Make std a facade #13851) this will be officially supported with nice error mesages. Additionally, there will only be one failure entry point once std::fmt migrates to libcore.
  • memcpy - This is often generated by LLVM. This is also quite trivial to implement for any platform, so I'm not too worried about this.
  • memcmp - This is required for comparing strings. This function is quite common everywhere, so I don't feel to bad about relying on a consumer of libcore to define it.
  • malloc and free - This is quite unfortunate, and is a temporary stopgap until we deal with the ~ situation. More details can be found in the module core::should_not_exist
  • fmod and fmodf - These exist because the Rem trait is defined in libcore, so the Rem implementation for floats must also be defined in libcore. I imagine that any platform using floating-point modulus will have these symbols anyway, and otherwise they will be optimized out.
  • fdim and fdimf - Like fmod, these are from the Signed trait being defined in libcore. I don't expect this to be much of a problem

These dependencies all "Just Work" for now because libcore only exists as an rlib, not as a dylib.

The commits themselves are organized to show that the overall diff of this extraction is not all that large. Most modules were able to be moved with very few modifications. The primary module left out of this iteration is std::fmt. I plan on migrating the fmt module to libcore, but I chose to not do so at this time because it had implications on the Writer trait that I wanted to deal with in isolation. There are a few breaking changes in these commits, but they are fairly minor, and are all labeled with [breaking-change].

The nastiest parts of this movement come up with ~[T] and ~str being language-defined types today. I believe that much of this nastiness will get better over time as we migrate towards Vec<T> and Str (or whatever the types will be named). There will likely always be some extension traits, but the situation won't be as bad as it is today.

Known deficiencies:

I recommend viewing these changes on a commit-by-commit basis. The overall change is likely too overwhelming to take in.

@brson brson mentioned this pull request May 2, 2014
9 tasks
@thestinger
Copy link
Contributor

memcpy - This is often generated by LLVM. This is also quite trivial to implement for any platform, so I'm not too worried about this.
memcmp - This is required for comparing strings. This function is quite common everywhere, so I don't feel to bad about relying on a consumer of libcore to define it.

It would be nice to provide these in a support crate, but it can be added separately from this pull request. The workarounds necessary to define these in Rust are non-obvious.

I imagine that any platform using floating-point modulus will have these symbols anyway, and otherwise they will be optimized out.

Lack of support for unoptimized builds means we'll have no support for debugging on these platforms. I hope there's a plan to fix this.

rustdoc will get worse in terms of readability. This is the next issue I will tackle as part of #13851. If others think that the rustdoc change should happen first, I can also table this to fix rustdoc first.

I don't think this is an issue because it's already split into many crates and the issue needs to be fixed anyway.

@alexcrichton
Copy link
Member Author

I avoided supplying memcmp/memcpy because I would imagine that the system memcmp/memcpy would be significantly faster than anything I could write. It would be nice to have them as optionally available, however! When you say that the workarounds are non-obvious, could you elaborate more?

I'm not too, too worried about the fmodf and fmod symbols. I don't currently have a plan to fix them, and I figure that if your platform doesn't have floating point support then you can just define two dummy symbols with these names that just fail if you call them. The only real solution I can think of is to have a separate crate which owns floats (so you can define libcore traits on floats).

@thestinger
Copy link
Contributor

I avoided supplying memcmp/memcpy because I would imagine that the system memcmp/memcpy would be significantly faster than anything I could write. It would be nice to have them as optionally available, however! When you say that the workarounds are non-obvious, could you elaborate more?

I documented this issue at https://github.com/thestinger/rust-core#freestanding-usage along with filing a bug report about it. Even with the bug fixed, I think these would be best in an optional crate to allow using the system functions. LLVM is surprisingly good at generating code for these via loop-vectorize and out-performed glibc when I last tested, because it wasn't using AVX yet. It's possible things have changed since then.

@brson
Copy link
Contributor

brson commented May 7, 2014

Let's go ahead and leave exect as its own trait in std for now, so we don't break the API, and reconsider ~Any in general later. r=me

@alexcrichton
Copy link
Member Author

Rebased moving Option::expect back to libstd. Waiting on a snapshot now.

@arielb1
Copy link
Contributor

arielb1 commented May 7, 2014

kernel-mode code can't use floating point anyway - so floats should probably be in a different library.

This strips out all string-related functionality from the num module. The
inherited functionality is all that will be implemented in libcore (for now).
Primarily, libcore will not implement the Float trait or any string-related
functionality.

It may be possible to migrate string parsing functionality into libcore in the
future, but for now it will remain in libstd.

All functionality in core::num is reexported in std::num.
This implements all traits inside of core::num for all the primitive types,
removing all the functionality from libstd. The std modules reexport all of the
necessary items from the core modules.
This commit adds a new trait, MutableVectorAllocating, which represents
functions on vectors which can allocate.

This is another extension trait to slices which should be removed once a lang
item exists for the ~ allocation.
The unicode module remains private, but the normalization iterators require an
allocation, so some functionality needs to remain in libstd
This moves as much allocation as possible from teh std::str module into
core::str. This includes essentially all non-allocating functionality, mostly
iterators and slicing and such.

This primarily splits the Str trait into only having the as_slice() method,
adding a new StrAllocating trait to std::str which contains the relevant new
allocation methods. This is a breaking change if any of the methods of "trait
Str" were overriden. The old functionality can be restored by implementing both
the Str and StrAllocating traits.

[breaking-change]
Coherence requires that libcore's traits be implemented in libcore for ~[T] and
~str (due to them being language defined types). These implementations cannot
live in libcore forever, but for now, until Heap/Box/Uniq is a lang item, these
implementations must reside inside of libcore. While not perfect
implementations, these shouldn't reside in libcore for too long.

With some form of lang item these implementations can be in a proper crate
because the lang item will not be present in libcore.
This adds an small of failure to libcore, hamstrung by the fact that std::fmt
hasn't been migrated yet. A few asserts were re-worked to not use std::fmt
features, but these asserts can go back to their original form once std::fmt has
migrated.

The current failure implementation is to just have some symbols exposed by
std::rt::unwind that are linked against by libcore. This is an explicit circular
dependency, unfortunately. This will be officially supported in the future
through compiler support with much nicer failure messages. Additionally, there
are two depended-upon symbols today, but in the future there will only be one
(once std::fmt has migrated).
The prospects of a generic failure function such as this existing in libcore are
bleak, due to monomorphization not working across the crate boundary, and
allocation into a ~Any is not allowed in libcore.

The argument to expect() is now &str instead of <M: Send + Any>

[breaking-change]
The unwrap()/unwrap_err() methods are temporarily removed, and will be added
back in the next commit.
These implementations must live in libstd right now because the fmt module has
not been migrated yet. This will occur in a later PR.

Just to be clear, there are new extension traits, but they are not necessary
once the std::fmt module has migrated to libcore, which is a planned migration
in the future.
This mostly involved frobbing imports between realstd, realcore, and the core
being test. Some of the imports are a little counterintuitive, but it mainly
focuses around libcore's types not implementing Show while libstd's types
implement Show.
This is the first snapshot with support to mix rlib and dylib dependencies.
bors added a commit that referenced this pull request May 7, 2014
This is the second step in implementing #13851. This PR cannot currently land until a snapshot exists with #13892, but I imagine that this review will take longer.

This PR refactors a large amount of functionality outside of the standard library into a new library, libcore. This new library has 0 dependencies (in theory). In practice, this library currently depends on these symbols being available:

* `rust_begin_unwind` and `rust_fail_bounds_check` - These are the two entry points of failure in libcore. The symbols are provided by libstd currently. In the future (see the bullets on #13851) this will be officially supported with nice error mesages. Additionally, there will only be one failure entry point once `std::fmt` migrates to libcore.
* `memcpy` - This is often generated by LLVM. This is also quite trivial to implement for any platform, so I'm not too worried about this.
* `memcmp` - This is required for comparing strings. This function is quite common *everywhere*, so I don't feel to bad about relying on a consumer of libcore to define it.
* `malloc` and `free` - This is quite unfortunate, and is a temporary stopgap until we deal with the `~` situation. More details can be found in the module `core::should_not_exist`
* `fmod` and `fmodf` - These exist because the `Rem` trait is defined in libcore, so the `Rem` implementation for floats must also be defined in libcore. I imagine that any platform using floating-point modulus will have these symbols anyway, and otherwise they will be optimized out.
* `fdim` and `fdimf` - Like `fmod`, these are from the `Signed` trait being defined in libcore. I don't expect this to be much of a problem

These dependencies all "Just Work" for now because libcore only exists as an rlib, not as a dylib.

The commits themselves are organized to show that the overall diff of this extraction is not all that large. Most modules were able to be moved with very few modifications. The primary module left out of this iteration is `std::fmt`. I plan on migrating the `fmt` module to libcore, but I chose to not do so at this time because it had implications on the `Writer` trait that I wanted to deal with in isolation. There are a few breaking changes in these commits, but they are fairly minor, and are all labeled with `[breaking-change]`.

The nastiest parts of this movement come up with `~[T]` and `~str` being language-defined types today. I believe that much of this nastiness will get better over time as we migrate towards `Vec<T>` and `Str` (or whatever the types will be named). There will likely always be some extension traits, but the situation won't be as bad as it is today.

Known deficiencies:

* rustdoc will get worse in terms of readability. This is the next issue I will tackle as part of #13851. If others think that the rustdoc change should happen first, I can also table this to fix rustdoc first.
* The compiler reveals that all these types are reexports via error messages like `core::option::Option`. This is filed as #13065, and I believe that issue would have a higher priority now. I do not currently plan on fixing that as part of #13851. If others believe that this issue should be fixed, I can also place it on the roadmap for #13851.

I recommend viewing these changes on a commit-by-commit basis. The overall change is likely too overwhelming to take in.
@bors bors closed this May 7, 2014
@bors bors merged commit 07caa22 into rust-lang:master May 7, 2014
@alexcrichton alexcrichton deleted the facade branch May 7, 2014 23:37
@emberian
Copy link
Member

Awesome work, thanks!

lnicola pushed a commit to lnicola/rust that referenced this pull request Mar 13, 2023
Support removing nested `dbg!()`s in `remove_dbg`

Closes rust-lang#13901
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.

None yet

6 participants