26

These two traits (std::ops::Add, core::ops::Add) provide the same functionality, and they both use the same example (both utilize std::ops::Add). Their set of implementors differ somewhat.

Should one default to using std::ops::Add? Why do both, as opposed to one, of them exist?

Chris Morgan
  • 86,207
  • 24
  • 208
  • 215
Filip Allberg
  • 3,941
  • 3
  • 20
  • 37

2 Answers2

30

There aren't two traits. There is one trait which is exported under several interchangeable names. This is far from unique. Virtually everything in core is also exported from std, and virtually always under exactly the same path (i.e., you can just replace the "core" prefix with "std").

As for which one you should use: If you have a reason to not link to the standard library (#![no_std]), then the std::* one isn't available so obviously you use core::*. If on the other hand you do use the standard library, you should use the std::* re-export. It is more customary and requires less typing.

  • 1
    What if I'm creating a library that doesn't need to use `std` stuff. Should I always mark it as `#![no_std]` in order for other no-std-crates to use it? What if I don't mark it `#![no_std]` and use `std::ops::Add`: can other no-std-crates use my crate? – Lukas Kalbertodt Mar 11 '16 at 23:40
  • 4
    @LukasKalbertodt The conventions about this are still unclear. You can't use a `std` crate from `no_std` even if it happens to use the subset of `std` that is also in `core`, which would be a reason to apply it liberally. But if a `no_std` crate later finds a reason to start depending on `std`, this would be a breaking change, so some people are wary of being too `no_std`-happy. –  Mar 11 '16 at 23:57
26

They're in fact exactly the same, despite the set of implementors being listed as slightly different.

The core library is designed for bare-metal/low-level tasks, and is thus more barebones than what std can provide by assuming an operating system exists. However, people using std will want the stuff that's in core too (e.g. Add or Option or whatever), and so to avoid having to load both std and core, std reexports everything from core, via pub use. That is, std provides aliases/import paths for the things in core.

There are some unfortunate error messages where the compiler points to the original source of an item, not the reexport, which might not be in a crate you're extern crateing.

huon
  • 94,605
  • 21
  • 231
  • 225