-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
std-using paths work just fine in 2018 edition #![no_std] #53166
Comments
I'd certainly like to see |
In the "anchored path" model (using terminology from #53130) imports still desugar into absolute paths ( |
In the "uniform path" model #![no_std]
use std::io; // ERROR
use ::std::io; // or `use extern::std::io;`, OK |
Then let me rephrase my original suggestion: how difficult would it be to have |
Not difficult at all, just weird. |
@joshtriplett I also suggested this and discussed the tradeoffs in my post above:
I don't think it's a slam-dunk, and I agree with @petrochenkov that a warning is probably a good solution in this case, since crates could conditionally deny the warning or allow it based on their |
@petrochenkov so, just to be clear: I think that right now if you do I remember finding that somewhat surprising to start. I expected us only to use the crate names that were given explicitly to rustc via I guess though that if we were to try and change it, we would have to make sure we handle core, std, and friends correctly here. |
Yes, right now with 2018 edition enabled These discussions are scattered over several threads, and in one of them a few people, including @eddyb , expressed the desire to disable this directory search, or use it only for crates explicitly passed with |
We discussed this issue in the lang team meeting today, and arrived at a rough consensus which I'll try to lay out here. cc @rust-lang/lang
|
In this new world, how does one achieve the existing pattern that goes like this? |
@SimonSapin |
@joshtriplett the problem with that is you then also need to have #[cfg(feature = "std")]
use std::mem;
#[(cfg(not(feature = "std"))]
use core::mem; everywhere (or some similar sort of pattern). I think that the direct replacement for @SimonSapin’s pattern is #![no_std]
#![cfg_attr(feature = "std", allow(the_lint_aturon_mentions))] Edit: hopefully the long term plan will allow abandoning this and having Edit2: actually, testing 2018 in the playground it allows access to |
Re-nominating because @withoutboats brought up an interesting point:
While @withoutboats would prefer to use a less specific/jargon-y name, potentially an umbrella term for future compilation-related facilities, my interest in this has to do with the whitelist, so specifically:
I was already feeling uneasy about @lqd mentioned "metaprogramming", from which one could derive IIUC, the current migration infrastructure can be easily adjusted to suggest replacing To be clear, I don't mind keeping "proc macro" jargon around (e.g. the crate type and attributes), but having a crate (other than |
Sorry I haven't been following this thread and the last comment seems not entirely related to the OP, but for |
I think we can keep Proc macros is an advanced feature so beginners learning Rust from 2018 edition will unlikely hit the "you don't need |
@alexcrichton I don't want to get rid of If we keep |
We discussed this in the @rust-lang/lang meeting. I forget who was supposed to write up the notes. =) I believe the general feeling was that:
Therefore, what we could do is to (a) reserve the name Personally, I think it would also be ok to permit Thoughts? |
eddyb 😛
I think it's a 👍 idea.
Not super excited about |
@nikomatsakis: as an outsider who prefers robustness/stability, I still think What is the interaction between this change and the use of |
@sanmai-NL We're unsure yet what we'll do to The decision we took is mainly to reserve We might even want an RFC or at least a FCP'd PR adding a As for |
FYI, seems like the meta crate on crates.io is squatted. |
@pietroalbini yup, we took that as a sign from above that we should have the |
@james-darkfox: that works for me too. See #54392. |
visited for triage. @eddyb says "only the lint is missing now." |
assigning to self to see about this lint. |
Wait, could someone remind why adding The original issue was about imports being able to access crates not from extern prelude. What is the problem with the previous "whitelisting" scheme in which cc @eddyb |
#54116 refers to #53166 (comment), but it doesn't list motivation. |
@petrochenkov I think part of the issue here is that some crates use To support this existing pattern, we need some way to make An alternative might be to have another attribute that serves to "cancel out" |
@aturon: I question whether those maintainers are set on keeping that pattern or whether they would understand this needs to be fixed. I expect the latter. Again, some breaking change that is acceptable for the 2018 edition? |
#54658 implements this idea by reusing |
(it looks like I should not assign high-priority to the proposed lint until after the lang team has come to a decision regarding PR #54658.) |
I ran into this because I only test my crate's no-std functionality on rust nightly, and nightly happily accepts Test case: #![no_std]
#[derive(Debug)]
pub struct Xxx;
impl core::fmt::Display for Xxx {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
f.write_str("xxx")
}
}
impl std::error::Error for Xxx {} Playground: https://play.rust-lang.org/?gist=fc27ec823582d16044559c4010a75c7c&version=nightly&mode=debug&edition=2015 Regarding the issue itself, is there any reason we don't just get people to use |
This should rightfully have been caught by the CI in the original PR, but alas it was not. My bad for not seeing it manually. See rust-lang/rust#53166 for issue on this kind of mistake not causing an error like it used to.
This is going to be fixed once #54671 lands. |
resolve: Scale back hard-coded extern prelude additions on 2015 edition #54404 stabilized `feature(extern_prelude)` on 2015 edition, including the hard-coded parts not passed with `--extern`. First of all, I'd want to confirm that this is intended stabilization, rather than a part of the "extended beta" scheme that's going to be reverted before releasing stable. (EDIT: to clarify - this is a question, I'm \*asking\* for confirmation, rather than give it.) Second, on 2015 edition extern prelude is not so fundamentally tied to imports and is a mere convenience, so this PR scales them back to the uncontroversial subset. The "uncontroversial subset" means that if libcore is injected it brings `core` into prelude, if libstd is injected it brings `std` and `core` into prelude. On 2015 edition this can be implemented through the library prelude (rather than hard-coding in the compiler) right now, I'll do it in a follow-up PR. UPDATE: The change is done for both 2015 and 2018 editions now as discussed below. Closes #53166
Add `extern crate` items to extern prelude With this patch each `extern crate orig_name as name` item adds name `name` into the extern prelude, as if it was passed with `--extern`. What changes this causes in practice? Almost none! After all, `--extern` passed from Cargo was supposed to replace `extern crate` items in source, so if some code has `extern crate` item (or had it on 2015 edition), then it most likely uses `--extern` as well... ... with exception of a few important cases. - Crates using `proc_macro`. `proc_macro` is not passed with `--extern` right now and is therefore not in extern prelude. Together with 2018 edition import behavior this causes problems like #54418, e.g. ```rust extern crate proc_macro; use proc_macro::TokenStream; ``` doesn't work. It starts working after this patch. - `#[no_std]` crates using `std` conditionally, like @aturon described in #53166 (comment), and still wanting to write `std` instead of `crate::std`. This PR covers that case as well. This allows us to revert placing `std` into the extern prelude unconditionally, which was, I think, a [bad idea](#53166 (comment)). - Later `extern crate` syntax can be extended to support adding an alias to some local path to extern prelude, as it may be required for resolving #54647. Notes: - Only `extern crate` items from the root module added to the prelude, mostly because this behavior for items from inner modules would look very strange, rather than for technical reasons. This means you can opt out from the prelude additions with something like ```rust mod inner { pub(crate) extern crate foo; } use inner::foo; ``` - I haven't updated logic for 2018 import canaries to work fully correctly with this. The cases where it matters are pretty exotic (the `extern crate` item must be "sufficiently macro expanded") and I'd rather spend the time on eliminating the canaries entirely.
Add `extern crate` items to extern prelude With this patch each `extern crate orig_name as name` item adds name `name` into the extern prelude, as if it was passed with `--extern`. What changes this causes in practice? Almost none! After all, `--extern` passed from Cargo was supposed to replace `extern crate` items in source, so if some code has `extern crate` item (or had it on 2015 edition), then it most likely uses `--extern` as well... ... with exception of a few important cases. - Crates using `proc_macro`. `proc_macro` is not passed with `--extern` right now and is therefore not in extern prelude. Together with 2018 edition import behavior this causes problems like #54418, e.g. ```rust extern crate proc_macro; use proc_macro::TokenStream; ``` doesn't work. It starts working after this patch. - `#[no_std]` crates using `std` conditionally, like @aturon described in #53166 (comment), and still wanting to write `std` instead of `crate::std`. This PR covers that case as well. This allows us to revert placing `std` into the extern prelude unconditionally, which was, I think, a [bad idea](#53166 (comment)). - Later `extern crate` syntax can be extended to support adding an alias to some local path to extern prelude, as it may be required for resolving #54647. Notes: - Only `extern crate` items from the root module added to the prelude, mostly because this behavior for items from inner modules would look very strange, rather than for technical reasons. This means you can opt out from the prelude additions with something like ```rust mod inner { pub(crate) extern crate foo; } use inner::foo; ``` - I haven't updated logic for 2018 import canaries to work fully correctly with this. The cases where it matters are pretty exotic (the `extern crate` item must be "sufficiently macro expanded") and I'd rather spend the time on eliminating the canaries entirely.
Add `extern crate` items to extern prelude With this patch each `extern crate orig_name as name` item adds name `name` into the extern prelude, as if it was passed with `--extern`. What changes this causes in practice? Almost none! After all, `--extern` passed from Cargo was supposed to replace `extern crate` items in source, so if some code has `extern crate` item (or had it on 2015 edition), then it most likely uses `--extern` as well... ... with exception of a few important cases. - Crates using `proc_macro`. `proc_macro` is not passed with `--extern` right now and is therefore not in extern prelude. Together with 2018 edition import behavior this causes problems like #54418, e.g. ```rust extern crate proc_macro; use proc_macro::TokenStream; ``` doesn't work. It starts working after this patch. - `#[no_std]` crates using `std` conditionally, like @aturon described in #53166 (comment), and still wanting to write `std` instead of `crate::std`. This PR covers that case as well. This allows us to revert placing `std` into the extern prelude unconditionally, which was, I think, a [bad idea](#53166 (comment)). - Later `extern crate` syntax can be extended to support adding an alias to some local path to extern prelude, as it may be required for resolving #54647. Notes: - Only `extern crate` items from the root module added to the prelude, mostly because this behavior for items from inner modules would look very strange, rather than for technical reasons. This means you can opt out from the prelude additions with something like ```rust mod inner { pub(crate) extern crate foo; } use inner::foo; ``` - I haven't updated logic for 2018 import canaries to work fully correctly with this. The cases where it matters are pretty exotic (the `extern crate` item must be "sufficiently macro expanded") and I'd rather spend the time on eliminating the canaries entirely.
Example:
rustc happily accepts this when passed
--edition 2018
. This makes sense-- it was always possible to reachstd
in#![no_std]
crates if you wroteextern crate std;
, but now thatextern crate
is redundant, that is no longer necessary. Unfortunately, that also means that projects attempting to test for#![no_std]
compatibility no longer have an easy way to check that they've correctly cut out allstd
-based dependencies.We could special case
std
paths to not work via the "extern prelude". This would work, but would require projects that want to optionally usestd
(who currently use#[cfg(feature = "std")] extern crate std;
) to continue usingextern crate std;
, which is awkward both because (1) it'd be the only place whereextern crate
ever gets used in theRust
of the future and (2) you'd have to write paths likecrate::std::...
in order to refer to your locally-mountedextern crate std
, which is all sorts of strange.Another option could be to make cargo and rustc aware of "no-std-ness" and allow some sort of flag or option which could make
std
un-linkable, perhaps usable by something like this Cargo.toml:However, this seems like a fairly complex addition and begins to interact with the various std-aware-cargo proposals.
Another option: do nothing. This isn't a huge deal, and as @MajorBreakfast pointed out, the issue will often be caught in CI by testing against targets that don't have
std
support. There are also various proposals like the portability lint that could obsolete whatever change we come up with here.The text was updated successfully, but these errors were encountered: