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

libstd::sys, the great libstd refactor #1502

Closed
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
@arcnmx

arcnmx commented Feb 16, 2016

A proposal to refactor the platform-dependent parts of libstd into a form that is better suited for porting to new platforms. The idea is to isolate the functionality we require from the underlying OS (basically, a thin abstraction over libc) into a well-defined interface that can be filled out easily by any platform. Thanks go to @briansmith for helping me draft this up.

See https://internals.rust-lang.org/t/libsystem-or-the-great-libstd-refactor/2765 for previous discussions and context.

Rendered

@Stebalien

This comment has been minimized.

Show comment
Hide comment
@Stebalien

Stebalien Feb 17, 2016

Contributor

How are you planning on re-using code between different unix platforms (or even between e.g. 32bit/64bit linux)? A small example would be very helpful.

Contributor

Stebalien commented Feb 17, 2016

How are you planning on re-using code between different unix platforms (or even between e.g. 32bit/64bit linux)? A small example would be very helpful.

@arcnmx

This comment has been minimized.

Show comment
Hide comment
@arcnmx

arcnmx Feb 17, 2016

@Stebalien sorry if it wasn't clear, I don't actually propose making changes to the current implementations for each platform and how that code is structured; that would be a ton of work, but if someone feels it needs to be done it'll be possible after this change! The goal here is only to define a common interface that libstd uses to talk to the underlying system agnostic to the OS, and move everything under that. It's simply proposing a high-level organizational change.

Any unix-specific code will be moved under sys::unix, Windows goes under sys::windows, etc. Those modules may contain submodules containing common code for variant flavours, or implement anything however they like as long as they conform to the API. Details behind the actual implementations will have a chance to go through review in each incremental PR, though I don't currently plan on changing anything that's already been written.

One of my initial attempts can be found at rust-lang/rust@28806e9

arcnmx commented Feb 17, 2016

@Stebalien sorry if it wasn't clear, I don't actually propose making changes to the current implementations for each platform and how that code is structured; that would be a ton of work, but if someone feels it needs to be done it'll be possible after this change! The goal here is only to define a common interface that libstd uses to talk to the underlying system agnostic to the OS, and move everything under that. It's simply proposing a high-level organizational change.

Any unix-specific code will be moved under sys::unix, Windows goes under sys::windows, etc. Those modules may contain submodules containing common code for variant flavours, or implement anything however they like as long as they conform to the API. Details behind the actual implementations will have a chance to go through review in each incremental PR, though I don't currently plan on changing anything that's already been written.

One of my initial attempts can be found at rust-lang/rust@28806e9

@brson

This comment has been minimized.

Show comment
Hide comment
@brson

brson Feb 17, 2016

Contributor

I agree with the sentiment that the standard library should have a clear portability layer of some kind.

The summary says to move platform specific code to "sys" so it would be easier to port, but this is pretty much how the standard library already is organized. See for example the Unix fs.rs vs. Windows fs.rs. Both modules implement a common interface that the rest of std relies on. It may be that the patterns to create these abstractions in std are not consistent, or complete, or easy to read in one place, but they are there. If we're going to add yet another abstraction layer, or drastically change the one exists, it needs to be clear why.

The major technical detail I see is that what exists now will be encapsulated into traits. Using modules is though listed as an alternative, and I'd suggest that's how std::sys is abstracted now. It's also what the Rust libc bindings do. I can imagine traits being more clear though because they define just the interface in a single place. If there were traits to define the entire portability layer I might expect them to be defined in a new module in sys and implemented in the existing unix and windows modules, and in new sys::_ modules for hypothetical future platforms.

What is the granularity of the trait implementations? If there is one for every triple for example, that's a lot of duplication. An advantage of the current strategy of using modules is that there's not a lot of code duplication. All of Unix is handled in one module.

The greatest benefit of having a clear platform abstraction layer would be to let people implement std out of tree by plugging in their version of std::sys without editing the std source. This RFC does not do that, and it doesn't obviously lead to such a design.

I might suggest that the goal should be to take what exists in std::sys and figuring out how to extract it from std. At that point it doesn't matter whether everything is encapsulated in a trait or not if you can replace the entire crate. And any major refactoring may not be worth the effort if it doesn't lead to std::sys becoming its own crate.

We should get feedback from redox since that is the biggest non-unix, non-windows platform I know of trying to implement std out of tree. Also from others that are trying to port std to non-unix, non-windows platforms. Who else is doing this?

Contributor

brson commented Feb 17, 2016

I agree with the sentiment that the standard library should have a clear portability layer of some kind.

The summary says to move platform specific code to "sys" so it would be easier to port, but this is pretty much how the standard library already is organized. See for example the Unix fs.rs vs. Windows fs.rs. Both modules implement a common interface that the rest of std relies on. It may be that the patterns to create these abstractions in std are not consistent, or complete, or easy to read in one place, but they are there. If we're going to add yet another abstraction layer, or drastically change the one exists, it needs to be clear why.

The major technical detail I see is that what exists now will be encapsulated into traits. Using modules is though listed as an alternative, and I'd suggest that's how std::sys is abstracted now. It's also what the Rust libc bindings do. I can imagine traits being more clear though because they define just the interface in a single place. If there were traits to define the entire portability layer I might expect them to be defined in a new module in sys and implemented in the existing unix and windows modules, and in new sys::_ modules for hypothetical future platforms.

What is the granularity of the trait implementations? If there is one for every triple for example, that's a lot of duplication. An advantage of the current strategy of using modules is that there's not a lot of code duplication. All of Unix is handled in one module.

The greatest benefit of having a clear platform abstraction layer would be to let people implement std out of tree by plugging in their version of std::sys without editing the std source. This RFC does not do that, and it doesn't obviously lead to such a design.

I might suggest that the goal should be to take what exists in std::sys and figuring out how to extract it from std. At that point it doesn't matter whether everything is encapsulated in a trait or not if you can replace the entire crate. And any major refactoring may not be worth the effort if it doesn't lead to std::sys becoming its own crate.

We should get feedback from redox since that is the biggest non-unix, non-windows platform I know of trying to implement std out of tree. Also from others that are trying to port std to non-unix, non-windows platforms. Who else is doing this?

@arcnmx

This comment has been minimized.

Show comment
Hide comment
@arcnmx

arcnmx Feb 17, 2016

@brson

this is pretty much how the standard library already is organized. See for example the Unix fs.rs vs. Windows fs.rs. Both modules implement a common interface that the rest of std relies on. It may be that the patterns to create these abstractions in std are not consistent, or complete, or easy to read in one place, but they are there.

Right, and that's why I suggest repurposing the module. The hope is to reorganize it all into something sane and consistent.

If we're going to add yet another abstraction layer, or drastically change the one exists, it needs to be clear why.

It's more like fixing the one that's sort of supposed to already be there. The "why" is to rid most of libstd of scattered ifdefs so that other platforms may be easily implemented, either in or out of tree, in a single isolated module.

What is the granularity of the trait implementations? If there is one for every triple for example, that's a lot of duplication. An advantage of the current strategy of using modules is that there's not a lot of code duplication. All of Unix is handled in one module.

As I said above, I don't propose deviating much from the current granularity for the initial sweep. One for unix, one for windows. I only wish to better define the abstractions it provides, while leaving things open to more changes down the line if they're deemed necessary.

The greatest benefit of having a clear platform abstraction layer would be to let people implement std out of tree by plugging in their version of std::sys without editing the std source. This RFC does not do that, and it doesn't obviously lead to such a design.

But that's the whole point of these changes... Once done, you can swap out sys with an external crate, or whatever you like, by changing a single use line and all the rest of std just magically works.

I might suggest that the goal should be to take what exists in std::sys and figuring out how to extract it from std. At that point it doesn't matter whether everything is encapsulated in a trait or not if you can replace the entire crate. And any major refactoring may not be worth the effort if it doesn't lead to std::sys becoming its own crate.

This is mentioned under unresolved questions. It is how I originally implemented it and why the original PR/thread/etc. is called libsystem. I later toned it down into a module because the changes would be the least disruptive this way, and provides an interim step that allows for easily moving it all out of std afterward. Splitting the two requires a bit more work mainly because some circular dependencies need to be broken.

While I fully believe it should eventually be its own standalone crate, I'm also a bit wary of the performance implications of inhibiting cross-module inlining optimizations if it's shipped as two separate crates.

Who else is doing this?

One of the big use cases I'm personally interested in is a Linux syscall implementation.


The idea behind the changes I propose are in order to clean up std::sys and provide a clear migration path to a better way of plugging platforms into std. They're intentionally conservative; pulling it out into a crate, making it pluggable, providing a way to build and swap backends out, etc. is a whole other large discussion to be had. I only aim to prepare libstd for such a change. Is your concern that this proposal isn't aggressive enough..?

arcnmx commented Feb 17, 2016

@brson

this is pretty much how the standard library already is organized. See for example the Unix fs.rs vs. Windows fs.rs. Both modules implement a common interface that the rest of std relies on. It may be that the patterns to create these abstractions in std are not consistent, or complete, or easy to read in one place, but they are there.

Right, and that's why I suggest repurposing the module. The hope is to reorganize it all into something sane and consistent.

If we're going to add yet another abstraction layer, or drastically change the one exists, it needs to be clear why.

It's more like fixing the one that's sort of supposed to already be there. The "why" is to rid most of libstd of scattered ifdefs so that other platforms may be easily implemented, either in or out of tree, in a single isolated module.

What is the granularity of the trait implementations? If there is one for every triple for example, that's a lot of duplication. An advantage of the current strategy of using modules is that there's not a lot of code duplication. All of Unix is handled in one module.

As I said above, I don't propose deviating much from the current granularity for the initial sweep. One for unix, one for windows. I only wish to better define the abstractions it provides, while leaving things open to more changes down the line if they're deemed necessary.

The greatest benefit of having a clear platform abstraction layer would be to let people implement std out of tree by plugging in their version of std::sys without editing the std source. This RFC does not do that, and it doesn't obviously lead to such a design.

But that's the whole point of these changes... Once done, you can swap out sys with an external crate, or whatever you like, by changing a single use line and all the rest of std just magically works.

I might suggest that the goal should be to take what exists in std::sys and figuring out how to extract it from std. At that point it doesn't matter whether everything is encapsulated in a trait or not if you can replace the entire crate. And any major refactoring may not be worth the effort if it doesn't lead to std::sys becoming its own crate.

This is mentioned under unresolved questions. It is how I originally implemented it and why the original PR/thread/etc. is called libsystem. I later toned it down into a module because the changes would be the least disruptive this way, and provides an interim step that allows for easily moving it all out of std afterward. Splitting the two requires a bit more work mainly because some circular dependencies need to be broken.

While I fully believe it should eventually be its own standalone crate, I'm also a bit wary of the performance implications of inhibiting cross-module inlining optimizations if it's shipped as two separate crates.

Who else is doing this?

One of the big use cases I'm personally interested in is a Linux syscall implementation.


The idea behind the changes I propose are in order to clean up std::sys and provide a clear migration path to a better way of plugging platforms into std. They're intentionally conservative; pulling it out into a crate, making it pluggable, providing a way to build and swap backends out, etc. is a whole other large discussion to be had. I only aim to prepare libstd for such a change. Is your concern that this proposal isn't aggressive enough..?

@briansmith

This comment has been minimized.

Show comment
Hide comment
@briansmith

briansmith Feb 17, 2016

It may be that the patterns to create these abstractions in std are not consistent, or complete, or easy to read in one place, but they are there.

I think a large part of this work—probably the initial part of the work—is simply making better use of the existing sys pattern. For example, see https://github.com/rust-lang/rust/blob/eac0a8bc3070e45047fff57e7b024a059289a36d/src/libstd/rand/os.rs. All the stuff conditional on [cfg(target_os)] needs to be made to follow the sys pattern. There are lots of instances of this.

The major technical detail I see is that what exists now will be encapsulated into traits. Using modules is though listed as an alternative, and I'd suggest that's how std::sys is abstracted now.

IMO, traits for this kind of abstraction don't make sense because (1) for any given platform, there would usually only be one implementation of the trait and (2) in fact, there is usually only a need for one instance of that one implementation. Traits are more suited for the case where there are multiple implementations of the trait that could be used at once. So, I think the current module-based approach should probably be chosen.

The greatest benefit of having a clear platform abstraction layer would be to let people implement std out of tree by plugging in their version of std::sys without editing the std source. This RFC does not do that, and it doesn't obviously lead to such a design.

I see this as a stepping stone to that, or to something like it. Whether different ports are managed in-tree or out-of-tree is a false dichotomy and also IMO more of a political issue than a technical issue. I don't want those politics to get mixed up with the technical improvements that come with having a clearer and easier-to-maintain porting abstraction.

I might suggest that the goal should be to take what exists in std::sys and figuring out how to extract it from std.

I think that would be a good stretch goal for this project. But, I think that doing less than that—in particular, making more consistent use of the sys module pattern—will still benefit the project. Definitely, I don't want to burden the libstd maintainers by giving them extra work in the long run, where they have to consider "what happens with a custom sys crate?" In the short run, any attempt at a new way of implementing sys differently will probably start out reusing a lot of the current libc-based implementation. In the long run, it might be able to create alternative implementations that don't use any of the current libc-based stuff. But, i think in the long long term, it is likely that a particular approach will win out over the others and the less-good ones (which might very well be newer ones) will die off.

briansmith commented Feb 17, 2016

It may be that the patterns to create these abstractions in std are not consistent, or complete, or easy to read in one place, but they are there.

I think a large part of this work—probably the initial part of the work—is simply making better use of the existing sys pattern. For example, see https://github.com/rust-lang/rust/blob/eac0a8bc3070e45047fff57e7b024a059289a36d/src/libstd/rand/os.rs. All the stuff conditional on [cfg(target_os)] needs to be made to follow the sys pattern. There are lots of instances of this.

The major technical detail I see is that what exists now will be encapsulated into traits. Using modules is though listed as an alternative, and I'd suggest that's how std::sys is abstracted now.

IMO, traits for this kind of abstraction don't make sense because (1) for any given platform, there would usually only be one implementation of the trait and (2) in fact, there is usually only a need for one instance of that one implementation. Traits are more suited for the case where there are multiple implementations of the trait that could be used at once. So, I think the current module-based approach should probably be chosen.

The greatest benefit of having a clear platform abstraction layer would be to let people implement std out of tree by plugging in their version of std::sys without editing the std source. This RFC does not do that, and it doesn't obviously lead to such a design.

I see this as a stepping stone to that, or to something like it. Whether different ports are managed in-tree or out-of-tree is a false dichotomy and also IMO more of a political issue than a technical issue. I don't want those politics to get mixed up with the technical improvements that come with having a clearer and easier-to-maintain porting abstraction.

I might suggest that the goal should be to take what exists in std::sys and figuring out how to extract it from std.

I think that would be a good stretch goal for this project. But, I think that doing less than that—in particular, making more consistent use of the sys module pattern—will still benefit the project. Definitely, I don't want to burden the libstd maintainers by giving them extra work in the long run, where they have to consider "what happens with a custom sys crate?" In the short run, any attempt at a new way of implementing sys differently will probably start out reusing a lot of the current libc-based implementation. In the long run, it might be able to create alternative implementations that don't use any of the current libc-based stuff. But, i think in the long long term, it is likely that a particular approach will win out over the others and the less-good ones (which might very well be newer ones) will die off.

@arcnmx

This comment has been minimized.

Show comment
Hide comment
@arcnmx

arcnmx Feb 17, 2016

At that point it doesn't matter whether everything is encapsulated in a trait or not if you can replace the entire crate

Considering that this is all a static, compile-time abstraction... Whether it's implemented as a crate or module, using traits or not... is all just an implementation detail. The advantage of using traits is to allow the compiler to assert early that you're not breaking the abstractions. The advantage of using crates is to more strictly define the abstraction boundaries. Neither choice has much of an effect on anything besides diagnostics and enforced code structuring.

IMO, traits for this kind of abstraction don't make sense because (1) for any given platform, there would usually only be one implementation of the trait and (2) in fact, there is usually only a need for one instance of that one implementation. Traits are more suited for the case where there are multiple implementations of the trait that could be used at once. So, I think the current module-based approach should probably be chosen.

Mm, and Rust doesn't make it very easy to deal with these static traits in general (the associated type thing kills me tbh). They just improve diagnostics and warn you if a change would accidentally break other platforms without you having to actually compile and test against each one. They also make for good documentation about what exact method signatures and types need to be provided by a platform implementation. A mock impl for the module approach would give you the same guarantees, though would be more awkward to maintain and integrate into the build/test system.

I think that would be a good stretch goal for this project.

The way I see it, this work is a preliminary step toward that. Making std agnostic to what's inside of std::sys is a great way to enable its later extraction as an external crate or other such changes in the future.

arcnmx commented Feb 17, 2016

At that point it doesn't matter whether everything is encapsulated in a trait or not if you can replace the entire crate

Considering that this is all a static, compile-time abstraction... Whether it's implemented as a crate or module, using traits or not... is all just an implementation detail. The advantage of using traits is to allow the compiler to assert early that you're not breaking the abstractions. The advantage of using crates is to more strictly define the abstraction boundaries. Neither choice has much of an effect on anything besides diagnostics and enforced code structuring.

IMO, traits for this kind of abstraction don't make sense because (1) for any given platform, there would usually only be one implementation of the trait and (2) in fact, there is usually only a need for one instance of that one implementation. Traits are more suited for the case where there are multiple implementations of the trait that could be used at once. So, I think the current module-based approach should probably be chosen.

Mm, and Rust doesn't make it very easy to deal with these static traits in general (the associated type thing kills me tbh). They just improve diagnostics and warn you if a change would accidentally break other platforms without you having to actually compile and test against each one. They also make for good documentation about what exact method signatures and types need to be provided by a platform implementation. A mock impl for the module approach would give you the same guarantees, though would be more awkward to maintain and integrate into the build/test system.

I think that would be a good stretch goal for this project.

The way I see it, this work is a preliminary step toward that. Making std agnostic to what's inside of std::sys is a great way to enable its later extraction as an external crate or other such changes in the future.

@briansmith

This comment has been minimized.

Show comment
Hide comment
@briansmith

briansmith Feb 17, 2016

Also, right now, a lot of code lives in libstd that, if a new "bare metal" implementation takes off, should be moved to a new sys::libc module that the sys::<os> modules re-export from. Then the sys:: submodules can mix-and-match what parts of libstd are implemented in terms of libc and which are implemented in another way. For example, imagine a sys::native_networking that implements all the networking parts of the standard library without an intermediate C libraries, but uses libc for implementing CString and file I/O and other stuff. It would consider of a bunch of new networking code plus a lot of re-exports of sys::libc stuff. Once sys::native_networking gets really good, it might become sys::linux in the rust-lang/rust tree and then become the default implementation on Linux, instead of sys::posix. Then, somebody might make a sys::bulletproof_linux_threading that eventually becomes a replacement for pthreads-based threading on Linux. You can see that it is likely that the development of a sys::native_networking and sys::bulletproof_linux_threading would need to happen in a tree other than rust-lang/rust for a long time before a decision could be made about integrating it into rust-lang/rust.

briansmith commented Feb 17, 2016

Also, right now, a lot of code lives in libstd that, if a new "bare metal" implementation takes off, should be moved to a new sys::libc module that the sys::<os> modules re-export from. Then the sys:: submodules can mix-and-match what parts of libstd are implemented in terms of libc and which are implemented in another way. For example, imagine a sys::native_networking that implements all the networking parts of the standard library without an intermediate C libraries, but uses libc for implementing CString and file I/O and other stuff. It would consider of a bunch of new networking code plus a lot of re-exports of sys::libc stuff. Once sys::native_networking gets really good, it might become sys::linux in the rust-lang/rust tree and then become the default implementation on Linux, instead of sys::posix. Then, somebody might make a sys::bulletproof_linux_threading that eventually becomes a replacement for pthreads-based threading on Linux. You can see that it is likely that the development of a sys::native_networking and sys::bulletproof_linux_threading would need to happen in a tree other than rust-lang/rust for a long time before a decision could be made about integrating it into rust-lang/rust.

@lilred

This comment has been minimized.

Show comment
Hide comment
@lilred

lilred Feb 17, 2016

Via @brson:

The greatest benefit of having a clear platform abstraction layer would be to let people implement std out of tree by plugging in their version of std::sys without editing the std source. [...]

We should get feedback from redox since that is the biggest non-unix, non-windows platform I know of trying to implement std out of tree. Also from others that are trying to port std to non-unix, non-windows platforms. Who else is doing this?

Me, @sacooper, and @kanetkarster are working on a Xen unikernel in Rust here. We're very interested in implementing std out-of-tree as soon as it becomes possible.

  • I'm not sure what the best interface would be. Traits might work, or lang_items. In the end, I don't care how it's done as long as it happens.
  • You might be interested in how Newlib handles portability. In order to port Newlib to your OS, all you need to do is implement these 18 functions. (And fiddle with the horrible build system. Agh.)

I don't know whether this RFC is what will lead us there - I need more time to look at it - but the general goal of out-of-tree std ports is something I very strongly support.

lilred commented Feb 17, 2016

Via @brson:

The greatest benefit of having a clear platform abstraction layer would be to let people implement std out of tree by plugging in their version of std::sys without editing the std source. [...]

We should get feedback from redox since that is the biggest non-unix, non-windows platform I know of trying to implement std out of tree. Also from others that are trying to port std to non-unix, non-windows platforms. Who else is doing this?

Me, @sacooper, and @kanetkarster are working on a Xen unikernel in Rust here. We're very interested in implementing std out-of-tree as soon as it becomes possible.

  • I'm not sure what the best interface would be. Traits might work, or lang_items. In the end, I don't care how it's done as long as it happens.
  • You might be interested in how Newlib handles portability. In order to port Newlib to your OS, all you need to do is implement these 18 functions. (And fiddle with the horrible build system. Agh.)

I don't know whether this RFC is what will lead us there - I need more time to look at it - but the general goal of out-of-tree std ports is something I very strongly support.

@nrc nrc added the T-libs label Feb 18, 2016

@Zoxc

This comment has been minimized.

Show comment
Hide comment
@Zoxc

Zoxc Feb 23, 2016

I support this and I'd like it to have the explict goal of moving libstd::sys into an external crate. After that libstd should no longer depend on libc.

Here is a patch that adds another (unix) platform to libstd (with just enough support to compile): AveryOS/rust@d9fb48b
You can see that platform specific stuff leaks out of libstd/sys. There are also some mixed things in libstd/sys/common. The platform specific code should move into some other folders and common should be moved out of sys.

Zoxc commented Feb 23, 2016

I support this and I'd like it to have the explict goal of moving libstd::sys into an external crate. After that libstd should no longer depend on libc.

Here is a patch that adds another (unix) platform to libstd (with just enough support to compile): AveryOS/rust@d9fb48b
You can see that platform specific stuff leaks out of libstd/sys. There are also some mixed things in libstd/sys/common. The platform specific code should move into some other folders and common should be moved out of sys.

@Ericson2314

This comment has been minimized.

Show comment
Hide comment
@Ericson2314

Ericson2314 Feb 24, 2016

Contributor

This was previously discussed here: #185

While I definitely agree the current situation is no good, frankly I don't like trying to shove all OS-specific stuff in one crate. To recap my arguments from that RFC:

This implies that all platforms support the same functionality at the end of the day, and its just a matter of providing the right hooks. I rather see a renewed commitment to splitting functionality until multiple crates below the std facade. That way platforms that e.g. support networking but not filesystems can implement the subset of crates that makes sense. Of course each of {alloc, sync, fs, net} (or whatever the crates beneath the facade are) can be pared with a shim crate to provide the same benefits a libplatform or libsys would.

Contributor

Ericson2314 commented Feb 24, 2016

This was previously discussed here: #185

While I definitely agree the current situation is no good, frankly I don't like trying to shove all OS-specific stuff in one crate. To recap my arguments from that RFC:

This implies that all platforms support the same functionality at the end of the day, and its just a matter of providing the right hooks. I rather see a renewed commitment to splitting functionality until multiple crates below the std facade. That way platforms that e.g. support networking but not filesystems can implement the subset of crates that makes sense. Of course each of {alloc, sync, fs, net} (or whatever the crates beneath the facade are) can be pared with a shim crate to provide the same benefits a libplatform or libsys would.

@Ericson2314

This comment has been minimized.

Show comment
Hide comment
@Ericson2314

Ericson2314 Feb 24, 2016

Contributor

And traits are ill-suited for this for exactly the reasons @briansmith mentions. #1408 is far more appropriate.

Contributor

Ericson2314 commented Feb 24, 2016

And traits are ill-suited for this for exactly the reasons @briansmith mentions. #1408 is far more appropriate.

@arcnmx

This comment has been minimized.

Show comment
Hide comment
@arcnmx

arcnmx Feb 24, 2016

This was previously discussed here: #185

Huh, it's unfortunate that seems to have been abandoned... It could've already been done by now!

frankly I don't like trying to shove all OS-specific stuff in one crate

I agree, and would certainly like to see libstd become more modular in the sense that you can implement only the functionality that makes sense on a given platform. I just really didn't want it to come up here because that in itself is a massive discussion... I'd like to fix libstd first so that we can actually start porting to other platforms, then these changes would be much more straightforward from there (and much less intrusive to the codebase as a whole).

And traits are ill-suited for this for exactly the reasons @briansmith mentions. #1408 is far more appropriate.

But #1408 would require the use of traits..? The only difference is that with #[extern] the actual implementation can be plugged in after the fact rather than needing to be a direct dependency, whether crate or module.

Meh, there's too much of a disconnect of goals in this conversation...

arcnmx commented Feb 24, 2016

This was previously discussed here: #185

Huh, it's unfortunate that seems to have been abandoned... It could've already been done by now!

frankly I don't like trying to shove all OS-specific stuff in one crate

I agree, and would certainly like to see libstd become more modular in the sense that you can implement only the functionality that makes sense on a given platform. I just really didn't want it to come up here because that in itself is a massive discussion... I'd like to fix libstd first so that we can actually start porting to other platforms, then these changes would be much more straightforward from there (and much less intrusive to the codebase as a whole).

And traits are ill-suited for this for exactly the reasons @briansmith mentions. #1408 is far more appropriate.

But #1408 would require the use of traits..? The only difference is that with #[extern] the actual implementation can be plugged in after the fact rather than needing to be a direct dependency, whether crate or module.

Meh, there's too much of a disconnect of goals in this conversation...

@Ericson2314

This comment has been minimized.

Show comment
Hide comment
@Ericson2314

Ericson2314 Feb 25, 2016

Contributor

Huh, it's unfortunate that seems to have been abandoned... It could've already been done by now!

Very true sadly

I just really didn't want it to come up here because that in itself is a massive discussion...

Well the whole point of the facade is to allow experimentation without breaking the stable interface, so I hope it wouldn't be so bad. My hunch is that std and ::sys as it exists may have some circular deps so as a practical matter both these goals might have to be implemented together.

But #1408 would require the use of traits..?

Ok sorry what I said was wrong let me fix it :). Ideally we have some sort of parameterized crates so one can pass in the name of the "sys crate" for the platform in question, rather than hard code a bunch of #[cfg(...)] extern crate ... but nobody has written up such a feature yet. The next best thing is just simple upstream "sys crates". If some cycles are seemingly unavoidable, #1408 can be used to break them (parameterized crates as I mention above probably wouldn't do that in comparison, but that and #1408 are related). #1408 does use traits, but at least it lets us "annoint" a special implementation, and doesn't force statics to become normal values constructed at run time. Finally worst of all is "plain" traits like liblog is (especially before core support was added: dynamic allocation and dynamic dispatch were mandatory, ugh).

Contributor

Ericson2314 commented Feb 25, 2016

Huh, it's unfortunate that seems to have been abandoned... It could've already been done by now!

Very true sadly

I just really didn't want it to come up here because that in itself is a massive discussion...

Well the whole point of the facade is to allow experimentation without breaking the stable interface, so I hope it wouldn't be so bad. My hunch is that std and ::sys as it exists may have some circular deps so as a practical matter both these goals might have to be implemented together.

But #1408 would require the use of traits..?

Ok sorry what I said was wrong let me fix it :). Ideally we have some sort of parameterized crates so one can pass in the name of the "sys crate" for the platform in question, rather than hard code a bunch of #[cfg(...)] extern crate ... but nobody has written up such a feature yet. The next best thing is just simple upstream "sys crates". If some cycles are seemingly unavoidable, #1408 can be used to break them (parameterized crates as I mention above probably wouldn't do that in comparison, but that and #1408 are related). #1408 does use traits, but at least it lets us "annoint" a special implementation, and doesn't force statics to become normal values constructed at run time. Finally worst of all is "plain" traits like liblog is (especially before core support was added: dynamic allocation and dynamic dispatch were mandatory, ugh).

@arcnmx

This comment has been minimized.

Show comment
Hide comment
@arcnmx

arcnmx Feb 25, 2016

Well the whole point of the facade is to allow experimentation without breaking the stable interface, so I hope it wouldn't be so bad.

Well, I'd argue that the two aspects at play here are:

  1. This RFC proposes doing a day or two of work to reorganize libstd in order to serve the goal of reducing maintenance burden on two sides:
    • Move all platform-dependent code to an isolated module so that (for the most part, new functionality and interface requirements aside) changes to libstd don't cause churn in platform code, and that platform code changes don't cause churn in libstd code. It simplifies diffs and merge conflicts while allows us to move the sys code into a crate or facade later on with minimal changes to the platform-agnostic libstd code.
    • Allow others to maintain a port libstd to esoteric or unixy platforms by simply forking libstd and creating a new module for that platform, having to change maybe one use line of existing code. Again, reduces maintenance burden by eliminating churn and merge conflicts; all your platform-specific code is in files that don't even exist upstream, and most conditional compilation is coarse-grained to a single module that exposes the platform interface.
  2. Eventually, we would like a more seamless and integrated way of porting libstd. One that encourages well-defined abstraction boundaries by removing circular dependencies and so forth. Perhaps it will support an out of tree crate, delayed type/dependency resolution, or a well-defined facade of independent functional parts, or whatever else.

The second is a higher level architectural change that I have many opinions on, but am expressly not making a goal of this proposal as it merits a much deeper discussion that I'm not confident I should be leading. The goal of this RFC is to tackle 1. now so that we're prepared to easily migrate code to whatever solution is eventually decided for 2. - and also make it easier for new platforms to work on their ports now, knowing that once we move to the end goal of 2. the migration path will be relatively straightforward.

So yes, it's important to keep in mind that the eventual goal is something larger than what I've proposed, but I'm hoping that we can all come to an agreement on a short-term abstraction that is designed well enough that it works well now and can later be adapted with minimal effort. If it's decided that we should instead go straight to a final solution, then this RFC is not sufficient to cover that and another proposal should be made (may require informal discussion first as there are a number of approaches that could be proposed).

My hunch is that std and ::sys as it exists may have some circular deps so as a practical matter both these goals might have to be implemented together.

I've thus far implemented this RFC twice; first time using trait methods and a separate crate so that libstd didn't depend on libc directly. Second time using the libstd::sys module method. Removing the circular deps isn't incredibly difficult, but it does generate more churn such that I feel it makes sense to take the less-intrusive step first.

Ideally we have some sort of parameterized crates so one can pass in the name of the "sys crate" for the platform in question, rather than hard code a bunch of #[cfg(...)] extern crate ... but nobody has written up such a feature yet. The next best thing is just simple upstream "sys crates".

This may be more of a "nice to have" kind of thing regarding an implementation detail rather than something that would drive the discussion and decisions made regarding the overall architecture.

If some cycles are seemingly unavoidable, #1408 can be used to break them (parameterized crates as I mention above probably wouldn't do that in comparison, but that and #1408 are related).

Cycles should certainly be avoidable, but it may be prudent to reorganize parts of libstd such that its convenient abstractions can still be used by platform-dependent code. Imagine libstd split up into libstd_fs and libstd_net and so on, each defining a trait of the platform-specific functionality they require, and concrete types like fs::File are then parametric over that trait so that these types may still be used by a libsys without actually being a dependency of libstd_fs itself. libstd would then simply re-export everything in a manner similar to pub type File = std_fs::File<sys_imp::Fs> and so on. But again, there are huge discussions to be had in that area... This is where it may make sense to go with the "trait" part of this proposal in order to prepare for an eventual situation like this.

#1408 does use traits, but at least it lets us "annoint" a special implementation, and doesn't force statics to become normal values constructed at run time.

Neither does a trait-approach without using delayed resolution. The only real difference is that delayed resolution necessitates the use of traits while with a crate or module approach it's simply one option. Annointing with #[extern] pub type Imp: T vs use imp::Imp or pub type Imp = imp::Imp isn't much more than a superficial difference.

Finally worst of all is "plain" traits like liblog is (especially before core support was added: dynamic allocation and dynamic dispatch were mandatory, ugh).

"plain"?

arcnmx commented Feb 25, 2016

Well the whole point of the facade is to allow experimentation without breaking the stable interface, so I hope it wouldn't be so bad.

Well, I'd argue that the two aspects at play here are:

  1. This RFC proposes doing a day or two of work to reorganize libstd in order to serve the goal of reducing maintenance burden on two sides:
    • Move all platform-dependent code to an isolated module so that (for the most part, new functionality and interface requirements aside) changes to libstd don't cause churn in platform code, and that platform code changes don't cause churn in libstd code. It simplifies diffs and merge conflicts while allows us to move the sys code into a crate or facade later on with minimal changes to the platform-agnostic libstd code.
    • Allow others to maintain a port libstd to esoteric or unixy platforms by simply forking libstd and creating a new module for that platform, having to change maybe one use line of existing code. Again, reduces maintenance burden by eliminating churn and merge conflicts; all your platform-specific code is in files that don't even exist upstream, and most conditional compilation is coarse-grained to a single module that exposes the platform interface.
  2. Eventually, we would like a more seamless and integrated way of porting libstd. One that encourages well-defined abstraction boundaries by removing circular dependencies and so forth. Perhaps it will support an out of tree crate, delayed type/dependency resolution, or a well-defined facade of independent functional parts, or whatever else.

The second is a higher level architectural change that I have many opinions on, but am expressly not making a goal of this proposal as it merits a much deeper discussion that I'm not confident I should be leading. The goal of this RFC is to tackle 1. now so that we're prepared to easily migrate code to whatever solution is eventually decided for 2. - and also make it easier for new platforms to work on their ports now, knowing that once we move to the end goal of 2. the migration path will be relatively straightforward.

So yes, it's important to keep in mind that the eventual goal is something larger than what I've proposed, but I'm hoping that we can all come to an agreement on a short-term abstraction that is designed well enough that it works well now and can later be adapted with minimal effort. If it's decided that we should instead go straight to a final solution, then this RFC is not sufficient to cover that and another proposal should be made (may require informal discussion first as there are a number of approaches that could be proposed).

My hunch is that std and ::sys as it exists may have some circular deps so as a practical matter both these goals might have to be implemented together.

I've thus far implemented this RFC twice; first time using trait methods and a separate crate so that libstd didn't depend on libc directly. Second time using the libstd::sys module method. Removing the circular deps isn't incredibly difficult, but it does generate more churn such that I feel it makes sense to take the less-intrusive step first.

Ideally we have some sort of parameterized crates so one can pass in the name of the "sys crate" for the platform in question, rather than hard code a bunch of #[cfg(...)] extern crate ... but nobody has written up such a feature yet. The next best thing is just simple upstream "sys crates".

This may be more of a "nice to have" kind of thing regarding an implementation detail rather than something that would drive the discussion and decisions made regarding the overall architecture.

If some cycles are seemingly unavoidable, #1408 can be used to break them (parameterized crates as I mention above probably wouldn't do that in comparison, but that and #1408 are related).

Cycles should certainly be avoidable, but it may be prudent to reorganize parts of libstd such that its convenient abstractions can still be used by platform-dependent code. Imagine libstd split up into libstd_fs and libstd_net and so on, each defining a trait of the platform-specific functionality they require, and concrete types like fs::File are then parametric over that trait so that these types may still be used by a libsys without actually being a dependency of libstd_fs itself. libstd would then simply re-export everything in a manner similar to pub type File = std_fs::File<sys_imp::Fs> and so on. But again, there are huge discussions to be had in that area... This is where it may make sense to go with the "trait" part of this proposal in order to prepare for an eventual situation like this.

#1408 does use traits, but at least it lets us "annoint" a special implementation, and doesn't force statics to become normal values constructed at run time.

Neither does a trait-approach without using delayed resolution. The only real difference is that delayed resolution necessitates the use of traits while with a crate or module approach it's simply one option. Annointing with #[extern] pub type Imp: T vs use imp::Imp or pub type Imp = imp::Imp isn't much more than a superficial difference.

Finally worst of all is "plain" traits like liblog is (especially before core support was added: dynamic allocation and dynamic dispatch were mandatory, ugh).

"plain"?

@jackpot51

This comment has been minimized.

Show comment
Hide comment
@jackpot51

jackpot51 Mar 6, 2016

This would make porting libstd to Redox much, much easier! 👍

jackpot51 commented Mar 6, 2016

This would make porting libstd to Redox much, much easier! 👍

@ticki

This comment has been minimized.

Show comment
Hide comment
@ticki

ticki Mar 8, 2016

Contributor

libstd, internally, is currently a mess. It makes a lot of sense to collect the platform specific functionality into one module. I'm very positive to this RFC, since it allows porting libstd to new platforms easily.

Contributor

ticki commented Mar 8, 2016

libstd, internally, is currently a mess. It makes a lot of sense to collect the platform specific functionality into one module. I'm very positive to this RFC, since it allows porting libstd to new platforms easily.

@brson

This comment has been minimized.

Show comment
Hide comment
@brson

brson Apr 1, 2016

Contributor

I took some time today to try to better understand the porting
abstractions in the current implementation, comparing today's
tree with arcnmx's last PR on the subject.

I was mostly trying to understand the existing sys abstractions
better, and looking at places in std that were doing
platform-specific stuff without going through sys.

My main goal is to identify concretely some simple incremental steps
we can begin to take to make porting std easier. We don't need to have
the whole porting story figured out right now to start making progress
since it's all details internal to std.

Overall organization

The std::sys module is intended to encapsulate platform-specific
implementations and features. The rest of std treats it as a platform
abstraction layer
.

It's organization is difficult to understand because there are a lot
of tangled reexports.

  • The std::sys module is private, and defined conditionally based
    on unix vs. windows. It corresponds to either "sys/unix/mod.rs" or
    "sys/windows/mod.rs".
  • The private std::sys_common module and std::sys have an unclear
    relationship. In general std::sys_common builds on std::sys and
    can be thought of as "the Rust runtime". Most modules in std that
    need platform abstraction call into std::sys_common, which
    encapsulates the platform specific stuff. This is probably the
    starting point for redefining the Rust platform abstraction layer.
  • std::sys_common lives on the file system in sys/common.
  • The std::os modules. These export public platform-specific
    features from std. So presumably there is no hope of putting them
    in an abstraction layer because they break the abstractions. They
    rely on std::sys.

Review of platform-specific code in std, outside of sys.

Here I've just gone through std and looked for platform-specific code,
comparing today's branch with @arcnmx's refactorings. I've definitely
missed stuff, but this gives an idea of the state of things.

std::thread

  • The thread_local! macro contains cfgs.
  • std::thread::local contains platform-specific impl mod. @arcnmx
    moves them to sys::thread_local.
  • std::thread::scope_tls similarly contains an impl mod.

std::rand

Looks fine today. Delegate's to sys::rand.

std::net

Looks fine to me. std::net doesn't contain platform-specific code.
@arcnmx's patch touches a lot of code here but it all looks incidental
to other refactoring.

std::io

There's a bit of cfg in stdio but it's just windows/not-windows.

std::process

The only cfgs are in tests.

std::fs

The only cfgs are in tests.

std::path

There are platform-specific cfgs but only of the unix-or-windows
variety. These should rightfully be sunk into an abstraction layer
because one of the porting painpoints is non-unix-or-windows platforms.

Concrete suggestions

The main reasons this RFC and its preceeding patches have been
hard to evaluate are that 1) the patches are massive, 2) it's
not clear all they do or why.

In order to move forward we need to agree on how we want std's
platform abstractions to be organized, and then refactor in that
direction in small increments.

My main immediate recommendations are focused on clarifying
two abstraction boundaries:

  • The interface between std and the platform. Today this is
    more-or-less std::sys_common, and I'm going to call it
    std::pal (platform abstraction layer).
  • The interface between the 'pal' and its implementation. Today this
    is more-or-less std::sys, and I'm going to keep calling it
    std::sys

Separate std::sys_common from std::sys into std::pal

The way the sys modules don't reflect the file system organization,
nor make obvious what the abstraction boundaries are, is for me is a
source of major confusion.

If we consider sys_common to be the platform abstraction layer and
sys to be its implementation, we can start making a stronger
abstraction boundary between them. The first thing we might do to make
it clear is to not put them in the same sys module, for example move
std::sys_common to std::pal and make sure that std modules outside
of std::sys only call std::pal and never std::sys. Just by
doing this we will enforce that all platform-specific modifications to
std happen in std::sys only.

At this point std::pal defines the interface std expects from
the platform.

std::pal contains no platform-specific code. It's sole
responsibility is gluing together the platform-specific code from
std::sys.

In theory, since std::pal contains no platform-specific code it
could be merged into the rest of std, and std::sys itself could be
std's platform interface, but this body of code exists now, so it
makes sense to me to re-rationalize its responsibilities.

Clarify the interface between std::pal and platform-specifics

Once std is only calling into std::pal and std::pal is only
calling into std::sys then std::sys is the interface
that porters must implement
.

It may not be a good interface, but everything will at least
corralled into std::sys.

We could probably at this point even write some lints that guarantee
that these two abstraction boundaries are never violated, for example
by grepping for inappropriate cfgs.

If we can just get that far, I think it would be a worthwhile
improvement on its own, and then we could take fresh stock of
the porting story and come up with further plans.

Contributor

brson commented Apr 1, 2016

I took some time today to try to better understand the porting
abstractions in the current implementation, comparing today's
tree with arcnmx's last PR on the subject.

I was mostly trying to understand the existing sys abstractions
better, and looking at places in std that were doing
platform-specific stuff without going through sys.

My main goal is to identify concretely some simple incremental steps
we can begin to take to make porting std easier. We don't need to have
the whole porting story figured out right now to start making progress
since it's all details internal to std.

Overall organization

The std::sys module is intended to encapsulate platform-specific
implementations and features. The rest of std treats it as a platform
abstraction layer
.

It's organization is difficult to understand because there are a lot
of tangled reexports.

  • The std::sys module is private, and defined conditionally based
    on unix vs. windows. It corresponds to either "sys/unix/mod.rs" or
    "sys/windows/mod.rs".
  • The private std::sys_common module and std::sys have an unclear
    relationship. In general std::sys_common builds on std::sys and
    can be thought of as "the Rust runtime". Most modules in std that
    need platform abstraction call into std::sys_common, which
    encapsulates the platform specific stuff. This is probably the
    starting point for redefining the Rust platform abstraction layer.
  • std::sys_common lives on the file system in sys/common.
  • The std::os modules. These export public platform-specific
    features from std. So presumably there is no hope of putting them
    in an abstraction layer because they break the abstractions. They
    rely on std::sys.

Review of platform-specific code in std, outside of sys.

Here I've just gone through std and looked for platform-specific code,
comparing today's branch with @arcnmx's refactorings. I've definitely
missed stuff, but this gives an idea of the state of things.

std::thread

  • The thread_local! macro contains cfgs.
  • std::thread::local contains platform-specific impl mod. @arcnmx
    moves them to sys::thread_local.
  • std::thread::scope_tls similarly contains an impl mod.

std::rand

Looks fine today. Delegate's to sys::rand.

std::net

Looks fine to me. std::net doesn't contain platform-specific code.
@arcnmx's patch touches a lot of code here but it all looks incidental
to other refactoring.

std::io

There's a bit of cfg in stdio but it's just windows/not-windows.

std::process

The only cfgs are in tests.

std::fs

The only cfgs are in tests.

std::path

There are platform-specific cfgs but only of the unix-or-windows
variety. These should rightfully be sunk into an abstraction layer
because one of the porting painpoints is non-unix-or-windows platforms.

Concrete suggestions

The main reasons this RFC and its preceeding patches have been
hard to evaluate are that 1) the patches are massive, 2) it's
not clear all they do or why.

In order to move forward we need to agree on how we want std's
platform abstractions to be organized, and then refactor in that
direction in small increments.

My main immediate recommendations are focused on clarifying
two abstraction boundaries:

  • The interface between std and the platform. Today this is
    more-or-less std::sys_common, and I'm going to call it
    std::pal (platform abstraction layer).
  • The interface between the 'pal' and its implementation. Today this
    is more-or-less std::sys, and I'm going to keep calling it
    std::sys

Separate std::sys_common from std::sys into std::pal

The way the sys modules don't reflect the file system organization,
nor make obvious what the abstraction boundaries are, is for me is a
source of major confusion.

If we consider sys_common to be the platform abstraction layer and
sys to be its implementation, we can start making a stronger
abstraction boundary between them. The first thing we might do to make
it clear is to not put them in the same sys module, for example move
std::sys_common to std::pal and make sure that std modules outside
of std::sys only call std::pal and never std::sys. Just by
doing this we will enforce that all platform-specific modifications to
std happen in std::sys only.

At this point std::pal defines the interface std expects from
the platform.

std::pal contains no platform-specific code. It's sole
responsibility is gluing together the platform-specific code from
std::sys.

In theory, since std::pal contains no platform-specific code it
could be merged into the rest of std, and std::sys itself could be
std's platform interface, but this body of code exists now, so it
makes sense to me to re-rationalize its responsibilities.

Clarify the interface between std::pal and platform-specifics

Once std is only calling into std::pal and std::pal is only
calling into std::sys then std::sys is the interface
that porters must implement
.

It may not be a good interface, but everything will at least
corralled into std::sys.

We could probably at this point even write some lints that guarantee
that these two abstraction boundaries are never violated, for example
by grepping for inappropriate cfgs.

If we can just get that far, I think it would be a worthwhile
improvement on its own, and then we could take fresh stock of
the porting story and come up with further plans.

@brson

This comment has been minimized.

Show comment
Hide comment
@brson

brson Apr 1, 2016

Contributor

I suspect that sys::common today actually has two roles:

  • It provides abstractions over sys that std uses.
  • It provides utilities that sys itself uses to implement the platform abstractions.

It may need to be split to reflect that.

Contributor

brson commented Apr 1, 2016

I suspect that sys::common today actually has two roles:

  • It provides abstractions over sys that std uses.
  • It provides utilities that sys itself uses to implement the platform abstractions.

It may need to be split to reflect that.

@brson

This comment has been minimized.

Show comment
Hide comment
@brson

brson Jul 19, 2016

Contributor

It's been a while since this RFC has been touched. As it stands, there is not enough detail in the RFC about the proposed design for somebody to implement it, nor is there agreement on what those details should be. I'd like to move this forward soon, either toward a mergable RFC or toward closing.

A mergable RFC will describe the specifics of the final design, how it's different from today's and how we will get there. I've previously outlined some thoughts on these topics based on cursory research into the issue.

Contributor

brson commented Jul 19, 2016

It's been a while since this RFC has been touched. As it stands, there is not enough detail in the RFC about the proposed design for somebody to implement it, nor is there agreement on what those details should be. I'd like to move this forward soon, either toward a mergable RFC or toward closing.

A mergable RFC will describe the specifics of the final design, how it's different from today's and how we will get there. I've previously outlined some thoughts on these topics based on cursory research into the issue.

@arcnmx

This comment has been minimized.

Show comment
Hide comment
@arcnmx

arcnmx Jul 19, 2016

Yeah, sorry, I've been very short on time lately... I'd certainly like to see it move forward. Your analysis was very helpful, and I like the suggestion for naming the abstraction layer std::pal, as the std::sys module gets a bit crowded and confusing.

I guess a good starting point would be to fill in some more details about what that interface will look like, and continue discussion then...

I suspect that sys::common today actually has two roles

This is definitely part of what needs to be redefined and fixed. Moving std to using the abstraction layer will turn it into just being common utilities.

arcnmx commented Jul 19, 2016

Yeah, sorry, I've been very short on time lately... I'd certainly like to see it move forward. Your analysis was very helpful, and I like the suggestion for naming the abstraction layer std::pal, as the std::sys module gets a bit crowded and confusing.

I guess a good starting point would be to fill in some more details about what that interface will look like, and continue discussion then...

I suspect that sys::common today actually has two roles

This is definitely part of what needs to be redefined and fixed. Moving std to using the abstraction layer will turn it into just being common utilities.

@brson

This comment has been minimized.

Show comment
Hide comment
@brson

brson Jul 21, 2016

Contributor

Thanks for the update @arcnmx.

Contributor

brson commented Jul 21, 2016

Thanks for the update @arcnmx.

@alexcrichton

This comment has been minimized.

Show comment
Hide comment
@alexcrichton

alexcrichton Aug 23, 2016

Member

🔔 This RFC is now entering its final comment period 🔔

The @rust-lang/libs team is inclined to close this RFC, given @brson's previous comments. @rust-lang/libs if you could check off your name below or write a comment below to the contrary:

Member

alexcrichton commented Aug 23, 2016

🔔 This RFC is now entering its final comment period 🔔

The @rust-lang/libs team is inclined to close this RFC, given @brson's previous comments. @rust-lang/libs if you could check off your name below or write a comment below to the contrary:

@jdub

This comment has been minimized.

Show comment
Hide comment
@jdub

jdub Aug 23, 2016

I tend to think ports like pull #1645 will resolve issues within sys if and when required. Perhaps doing the design and implementation before it's necessary is misplaced work.

jdub commented Aug 23, 2016

I tend to think ports like pull #1645 will resolve issues within sys if and when required. Perhaps doing the design and implementation before it's necessary is misplaced work.

@Ericson2314

This comment has been minimized.

Show comment
Hide comment
@Ericson2314

Ericson2314 Aug 23, 2016

Contributor

IIUC we don't really need an RFC for this, since it involves moving around unstable things, but it would nice just to codify a plan that multiple people can work on. I hope things like rust-lang/rust#35021 will get the ball moving organically, and that deprecating the make system will make things easier.

Contributor

Ericson2314 commented Aug 23, 2016

IIUC we don't really need an RFC for this, since it involves moving around unstable things, but it would nice just to codify a plan that multiple people can work on. I hope things like rust-lang/rust#35021 will get the ball moving organically, and that deprecating the make system will make things easier.

@arcnmx

This comment has been minimized.

Show comment
Hide comment
@arcnmx

arcnmx Aug 23, 2016

I think @brson's comments illustrate a proper resolution to the problem and acutely identify what needs changing inside of libstd. While an RFC isn't strictly necessary, it helps to get opinions on a final direction and I'm glad the discussion took place. Maybe it will happen eventually/organically, and this thread at least outlines how some parts around it should be designed. It'd be nice to get consensus on this with the appropriate changes made, but ugh the last time I had any time to do anything was a year ago...

arcnmx commented Aug 23, 2016

I think @brson's comments illustrate a proper resolution to the problem and acutely identify what needs changing inside of libstd. While an RFC isn't strictly necessary, it helps to get opinions on a final direction and I'm glad the discussion took place. Maybe it will happen eventually/organically, and this thread at least outlines how some parts around it should be designed. It'd be nice to get consensus on this with the appropriate changes made, but ugh the last time I had any time to do anything was a year ago...

@briansmith

This comment has been minimized.

Show comment
Hide comment
@briansmith

briansmith Aug 23, 2016

I'm also in favor of closing this. At one point, it looked like this might make it easier to refactor libstd, but it seems to not matter much.

briansmith commented Aug 23, 2016

I'm also in favor of closing this. At one point, it looked like this might make it easier to refactor libstd, but it seems to not matter much.

@jethrogb

This comment has been minimized.

Show comment
Hide comment
@jethrogb

jethrogb Sep 2, 2016

Contributor

I'm surprised I didn't comment in here before.

I support something like this RFC. I very often run into situations where I need parts of std but not others. This results in crates such as core_io, core_collections, core_rustc-serialize. I was hoping the refactoring proposed here would make it easier to have such independent modules.

std currently contains data structures, abstractions and implementations. Generally only the implementations are platform-dependent. I want code that doesn't depend on some implementations to run on systems that don't have those.

Contributor

jethrogb commented Sep 2, 2016

I'm surprised I didn't comment in here before.

I support something like this RFC. I very often run into situations where I need parts of std but not others. This results in crates such as core_io, core_collections, core_rustc-serialize. I was hoping the refactoring proposed here would make it easier to have such independent modules.

std currently contains data structures, abstractions and implementations. Generally only the implementations are platform-dependent. I want code that doesn't depend on some implementations to run on systems that don't have those.

@alexcrichton

This comment has been minimized.

Show comment
Hide comment
@alexcrichton

alexcrichton Sep 12, 2016

Member

Ok, with the libs team weighing in, the decision was to close. Thanks regardless though for the RFC @arcnmx!

Member

alexcrichton commented Sep 12, 2016

Ok, with the libs team weighing in, the decision was to close. Thanks regardless though for the RFC @arcnmx!

@jethrogb

This comment has been minimized.

Show comment
Hide comment
@jethrogb

jethrogb Oct 12, 2016

Contributor

Some people here might be interested in rust-lang/rust#37133

Contributor

jethrogb commented Oct 12, 2016

Some people here might be interested in rust-lang/rust#37133

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment