Tracking issue for RFC 1868: A portability lint
This is a tracking issue for the RFC "A portability lint" (rust-lang/rfcs#1868).
Steps:
- [ ] Implement the RFC (cc @rust-lang/compiler -- can anyone write up mentoring instructions?)
- [ ] Adjust documentation (see instructions on forge)
- [ ] Stabilization PR (see instructions on forge)
Unresolved questions:
- [ ] It's not clear what the story should be for a library like
libc, which currently involves intricate uses ofcfg. We should have some idea for how to approach such cases before landing the RFC.
cc #43086
Alex Burka at 2017-07-08 18:30:05
When this is implemented, reconsider
ExactSizeIteratorforRange<_>andRangeInclusive<_>: https://github.com/rust-lang/rust/pull/43086#issuecomment-313872797Simon Sapin at 2017-07-08 18:44:10
Just encountered a relevant research project - their work may have aspects we can reuse: http://fosd.net/TypeChef
TypeChef is a research project with the goal of analyzing ifdef variability in C code with the goal of finding variability-induced bugs in large-scale real-world systems, such as the Linux kernel with several thousand features (or configuration options).
eternaleye at 2018-07-20 08:00:00
[Hopefully this doesn't count as inappropriate advertising!] I'll be 1 half of a 2 person talk at the HIW at ICFP reviewing some of the literature. I was certainly inspired to take this up from this RFC and @eternaleye's comment, and I hope whatever proposal this turns into is equally applicable to Rust / fleshing out the details of this RFC too!
John Ericson at 2019-07-23 19:20:47
Notes from lang team triage: the consensus is that the RFC looks reasonably accurate, but the design concerns not yet known. If there are design issues, the Lang Team expects that the implementor(s) would discover said design issues during implementation.
Additionally, this feature is very much desired by various teams. For instance, the standard library's expansion to platform-specific areas is semi-blocked on this implementation.
David Barsky at 2022-01-26 18:46:46
On the
E-help-wantedfront, it would be great to get some academic involvement with this. Ideally we could have a library that rustc and cargo can use, because https://github.com/rust-lang/cargo/issues/1197 has a very virtuous interaction with this:- Features should be able to depend on (aspects of) targets (e.g.
io_uringbackends on linux) - Targets should be able to depend on features (need to choose one of
select,epoll, orio_uringfor linux) - Information from Cargo on this stuff needs to feed back into checking the source code, basically for additional
target_os = ...axioms.
I feel like there should be some good papers in here :) Even if the core mathematical techniques are not new, there is good empirical work on how the ecosystem would use this stuff, prevalance of platform specific code, ec.
John Ericson at 2022-01-26 23:21:13
- Features should be able to depend on (aspects of) targets (e.g.
It seems like the current consensus among @rust-lang/lang is that this isn't the approach we want to go after all, and we'd like something type-based rather than lint-based. For instance, something based on the various "capabilities" proposals for global impls of a
Trait, together withwhereclauses.@rfcbot close
Josh Triplett at 2023-05-15 15:47:44
Team member @joshtriplett has proposed to close this. The next step is review by the rest of the tagged team members:
- [x] @joshtriplett
- [x] @nikomatsakis
- [ ] @pnkfelix
- [x] @scottmcm
- [ ] @tmandry
No concerns currently listed.
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!
cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. See this document for info about what commands tagged team members can give me.
Rust RFC bot at 2023-05-15 15:47:46
@joshtriplett Is there any sort of writeup that broadly explains how a type-based solution would work? I understand there are some concerns about this RFC as-is, but I haven't seen them clearly articulated.
I probably dislike conditional compilation more than most, but there are situations where I have a hard time seeing how it can be avoided, and it's hard for me to see how a type-based solution could come close to all the use cases and situations that
cfgcovers. It's hard to imagine that everyone will stop usingcfg, so it's not clear to me how something not based oncfgwould be able to answer questions like "what is the compatibility of this crate". There are perhaps other routes, such as https://github.com/rust-lang/cargo/issues/6179 allowing crate authors to declare what they support, but that seems like it would be quite challenging to get adoption.Overall I like the idea of this RFC, as it would provide a mechanism to inform someone what their code might be incompatible with. I can imagine there are some problems (like
cfgdoesn't cover all cases, 3 portability levels might not be the right categorization, etc.), but I'm curious what makes it fundamentally undesired.Eric Huss at 2023-05-15 16:43:23
@rfcbot reviewed -- I agree with the where-clause based approach
Niko Matsakis at 2023-05-16 18:24:57
@rustbot labels -I-lang-nominated
Niko Matsakis at 2023-05-16 18:44:43
IMO type-based vs lint-based is perhaps not the distinction it sounds like it is. I imagine this would use the same logic programming machinery under-girding the trait system regardless.
The question rather of phase separation. A
cfg-like system can be delay/interleaves (symbolic execution of it, basically), or it can be done eagerly. And by choosing a "model" over which do the evaluation (symbolic execution as conventionally understood would be, using the initial model) one can pick very intermediate options in between the two.On one extremely we full
where-clause, and get rid ofcfgentirely, we have great compositionality and error checking, but you need all the code the all the time (think of optional deps for optional platforms). This is probably annoying especially when upstream code is more portable than downstream code.On the other extreme is today's
cfg, which only does a specific combination (single point model), for nice pruning unneeded stuff but terrible error checking.I would like the full spectrum of options, and I would not like something that awkwardly overlaps with
cfgsuch that people are not sure which one to use.
tl;dr new syntax greenfield system :-1: , implementing existing cfg sharing code with the trait system :+1: .
John Ericson at 2023-05-16 19:35:59
:bell: This is now entering its final comment period, as per the review above. :bell:
Rust RFC bot at 2023-06-13 18:38:27
The final comment period, with a disposition to close, as per the review above, is now complete.
As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.
Rust RFC bot at 2023-06-23 18:43:18
I have not checked my box; I agree with wanting a sketch of a solution that covers the use cases of the RFC before closing.
Tyler Mandry at 2023-06-28 01:28:03
@joshtriplett wrote:
It seems like the current consensus among @rust-lang/lang is that this isn't the approach we want to go after all, and we'd like something type-based rather than lint-based. For instance, something based on the various "capabilities" proposals for global impls of a
Trait, together withwhereclauses.Is there a link to these proposals/an elaboration of this approach?
Shea Levy at 2024-02-05 23:23:49
The idea that I brought up several times in meetings (online and in person) but never really wrote down is basically to use where clauses for this. My belief is that
#[cfg]is a terribe tool in many ways. It results in weird parallel worlds where items or entire trait implementations disappear or appear depending on the context, or even resolve to completely different items, making things very hard for clear diagnostics and good documentation.Rust already has a much better designed mechanism for specifying conditions/bounds on items, including the machinism for then assuming those conditions are met within that item: where clauses.
Within a
fn f<T>(x: T)item, you are not allowed to callx.clone(), because while it might be perfectly true that thexyou're actually using can be cloned, the compiler forces you to support all types. If you addwhere T: Clone, you specify that you only supportClonetypes, so then it will let you callx.clone().This is nearly exactly the same as what we need for platform specific items. Here's the same paragraph as the previous one, with only a few words changed:
Within your Rust code, you are not allowed to call
File::read_at, because while it might be perfectly true that the platform you're actually using can do this, the compiler forces you to support all platforms. If you addwhere Platform: Unix, you specify that you only support unix platforms, so then it will let you callFile::read_at.So, imagine if we had something like
where Platform: Unix(or even things likewhere Platform: UsizeIs64Bitorwhere Platform: HasAtomics<64>) and a way to add such a where clause to an entire crate. I think then we get pretty much exactly the behaviour we're looking for, without#[cfg], with much better potential for good documentation, clear diagnostics, and it'd fit cleanly into the rest of the language.This would work not just for functions/methods, but also for trait impls such as
impl From<u64> for usize; basically anything that supports where clauses (which might then include crates or perhaps even modules).Mara Bos at 2024-04-15 13:45:55