# Refactoring std for ultimate portability

**URL:** <https://internals.rust-lang.org/t/refactoring-std-for-ultimate-portability/4301>\
**Category:** libs\
**Created:** [November 2, 2016, 5:28pm UTC](https://internals.rust-lang.org/t/refactoring-std-for-ultimate-portability/4301 "2016-11-02T17:28:25Z")\
**Posts on this page:** 1\
**Showing post:** 22

<div class="post-metadata">

**Author:** ![brson](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/brson/32/5197_2.png) [@brson](https://internals.rust-lang.org/u/brson)\
**Post date:** [November 3, 2016, 8:46pm UTC](https://internals.rust-lang.org/t/refactoring-std-for-ultimate-portability/4301/22 "2016-11-03T20:46:48Z")

</div>

> [@jethrogb](#):
>
> One big thing I'm not seeing is a solution for io::Error. You say it's hard and then go on talking about CString. I don't think this is an apt comparison because there the only dependency is a function with a well-known signature, whereas for io::Error there's a dependency on system-specific constants. But maybe I'm overthinking this and all you need is get\_last\_error and decode\_error\_kind.

I expect `Error` can be handled with the inner-type pattern, where `pal_common` defines a common `Error` type with less features than the one in `std`.

> [@jethrogb](#):
>
> Can you just say pub type CString = ::pal::CString\<PalMemchr\>?

I'm not sure, but I suspect there are semantic differences that would be exposed.

> [@jethrogb](#):
>
> I think the compiler or some linter should support some form of "header files" that source files can be checked against. These header files should initially be automatically generated from the publicly reachable items in a crate. This tool is useful here for defining a PAL API, but I imagine it can also be useful to enforce stability guarantees on APIs.

This would be a reasonable approach.

> [@Ericson2314](#):
>
> The solution for io::Error is associated error types on core::io traits:

It's hard to guess whether that is sufficient. `io::Error` is used for many purposes in std that are not associated with those traits.

> [@briansmith](#):
>
> You seem to imply that CString isn't a platform-specific type, but in fact it is platform-specific. If we imagine a pure Rust platform, there'd be no use for CString and such a platform shouldn't have to provide any implementation of CString. In fact, I am interested in creating a port that doesn't have CString and similar at all, so I'd like to find a way to make that work in this framework.

It depends on what you mean by platform-specific. The example here showed that it is platform-specific in that the implementation uses platform-specific features.

Those features are just optimizations of convenience though because libc happens to have efficient implementations of memchr (and one other function I can't recall off-hand). There is nothing about the definition of C strings that is tied to an operating system (though the definition of c\_char is ABI-specific, c\_char is one of the few C types std defines), so one could implement them without calling into libc, and in that sense CStrings are platform-independent.

I'd be interested to know your motivation for not having CString (I inderstand not wanting to link to libc). If it's just because you don't need it that's fine.

There are various ways one could imagine not implementing and/or exposing CStrings. Scenarios are one.

(Looks like CStrings have been well discussed in this thread so I won't comment further).

> [@diwic](#):
>
> While it works to get the first "just up and running" code, how do you know when you found the last panic, i e, when your program is ready to ship (without implementing the entire pal, of which you only use a fraction)?

grep for `panic!` is the simple answer. I'm not sure if there's any particularly better strategy, except where there are useful defaults. One must either stub out functionality or implement everything at once.

> [@diwic](#):
>
> I would much prefer many platform dependent crates, i e, pal\_allocsystem\_unix, pal\_file\_unix, pal\_threads\_unix and so on. It helps with crate interdependencies, and it also helps with not having to implement functions you don't need.

I mentioned this in passing as potential future work. Any appropriate division here will become more clear as the work progresses.

---

_[View the full topic](https://internals.rust-lang.org/t/refactoring-std-for-ultimate-portability/4301)._
