Skip to content

Commit 88204f0

Browse files
authored
Merge pull request #2077 from Voultapher/explicitly-export-core-and-std-macros
Reflect explicit macro import in reference
2 parents 28b5a54 + d3b02a9 commit 88204f0

File tree

2 files changed

+75
-4
lines changed

2 files changed

+75
-4
lines changed

src/names/name-resolution.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,38 @@ const _: () = {
229229
r[names.resolution.expansion.imports.ambiguity.glob-vs-outer]
230230
Names in imports and macro invocations may not be resolved through glob imports when there is another candidate available in an [outer scope].
231231

232+
r[names.resolution.expansion.imports.ambiguity.panic-hack]
233+
> [!NOTE]
234+
> When one of [`core::panic!`] or [`std::panic!`] is brought into scope due to the [standard library prelude], and a user-written [glob import] brings the other into scope, `rustc` currently allows use of `panic!`, even though it is ambiguous. The user-written glob import takes precedence to resolve this ambiguity.
235+
>
236+
> In Rust 2021 and later, [`core::panic!`] and [`std::panic!`] operate identically. But in earlier editions, they differ; only [`std::panic!`] accepts a [`String`] as the format argument.
237+
>
238+
> E.g., this is an error:
239+
>
240+
> ```rust,edition2018,compile_fail,E0308
241+
> extern crate core;
242+
> use ::core::prelude::v1::*;
243+
> fn main() {
244+
> panic!(std::string::String::new()); // ERROR.
245+
> }
246+
> ```
247+
>
248+
> And this is accepted:
249+
>
250+
> <!-- ignore: Can't test with `no_std`. -->
251+
> ```rust,edition2018,ignore
252+
> #![no_std]
253+
> extern crate std;
254+
> use ::std::prelude::v1::*;
255+
> fn main() {
256+
> panic!(std::string::String::new()); // OK.
257+
> }
258+
> ```
259+
>
260+
> Don't rely on this behavior; the plan is to remove it.
261+
>
262+
> For details, see [Rust issue #147319](https://github.com/rust-lang/rust/issues/147319).
263+
232264
```rust,compile_fail,E0659
233265
mod glob {
234266
pub mod ambig {
@@ -545,6 +577,7 @@ r[names.resolution.type-relative]
545577
[`use` declarations]: ../items/use-declarations.md
546578
[`use` glob shadowing]: ../items/use-declarations.md#r-items.use.glob.shadowing
547579
[derive helper scope]: ../procedural-macros.md#r-macro.proc.derive.attributes.scope
580+
[glob import]: items.use.glob
548581
[item definitions]: ../items.md
549582
[macro invocations]: ../macros.md#macro-invocation
550583
[macro textual scope shadowing]: ../macros-by-example.md#r-macro.decl.scope.textual.shadow

src/names/preludes.md

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ Edition | `no_std` not applied | `no_std` applied
4040
>
4141
> [`core::prelude::rust_2015`] and [`core::prelude::rust_2018`] have the same contents as [`core::prelude::v1`].
4242
43+
> [!NOTE]
44+
> When one of [`core::panic!`] or [`std::panic!`] is brought into scope due to the [standard library prelude], and a user-written [glob import] brings the other into scope, `rustc` currently allows use of `panic!`, even though it is ambiguous. The user-written glob import takes precedence to resolve this ambiguity.
45+
>
46+
> For details, see [names.resolution.expansion.imports.ambiguity.panic-hack].
47+
4348
r[names.preludes.extern]
4449
## Extern prelude
4550

@@ -81,7 +86,7 @@ r[names.preludes.extern.no_std]
8186
### The `no_std` attribute
8287
8388
r[names.preludes.extern.no_std.intro]
84-
The *`no_std` [attribute][attributes]* causes the [`std`] crate to not be linked automatically, the [standard library prelude] to instead use the `core` prelude, and the [`macro_use` prelude] to instead use the macros exported from the `core` crate.
89+
The *`no_std` [attribute][attributes]* causes the [`std`] crate to not be linked automatically and the [standard library prelude] to instead use the `core` prelude.
8590
8691
> [!EXAMPLE]
8792
> <!-- ignore: test infrastructure can't handle no_std -->
@@ -110,9 +115,6 @@ The `no_std` attribute may be used any number of times on a form.
110115
r[names.preludes.extern.no_std.module]
111116
The `no_std` attribute changes the [standard library prelude] to use the `core` prelude instead of the `std` prelude.
112117
113-
r[names.preludes.extern.no_std.macro_use]
114-
By default, all macros exported from the `std` crate are added to the [`macro_use` prelude]. If the `no_std` attribute is specified, then all macros exported from the `core` crate are placed into the [`macro_use` prelude] instead.
115-
116118
r[names.preludes.extern.no_std.edition2018]
117119
> [!EDITION-2018]
118120
> Before the 2018 edition, `std` is injected into the crate root by default. If `no_std` is specified, `core` is injected instead. Starting with the 2018 edition, regardless of `no_std` being specified, neither is injected into the crate root.
@@ -190,6 +192,41 @@ The `no_implicit_prelude` attribute may be used any number of times on a form.
190192
r[names.preludes.no_implicit_prelude.excluded-preludes]
191193
The `no_implicit_prelude` attribute prevents the [standard library prelude], [extern prelude], [`macro_use` prelude], and the [tool prelude] from being brought into scope for the module and its descendants.
192194
195+
r[names.preludes.no_implicit_prelude.implicitly-imported-macros]
196+
> [!NOTE]
197+
> Despite `#![no_implicit_prelude]`, `rustc` currently brings certain macros implicitly into scope. Those macros are:
198+
>
199+
> - [`assert!`]
200+
> - [`cfg!`]
201+
> - [`cfg_select!`]
202+
> - [`column!`]
203+
> - [`compile_error!`]
204+
> - [`concat!`]
205+
> - [`concat_bytes!`]
206+
> - [`env!`]
207+
> - [`file!`]
208+
> - [`format_args!`]
209+
> - [`include!`]
210+
> - [`include_bytes!`]
211+
> - [`include_str!`]
212+
> - [`line!`]
213+
> - [`module_path!`]
214+
> - [`option_env!`]
215+
> - [`panic!`]
216+
> - [`stringify!`]
217+
> - [`unreachable!`]
218+
>
219+
> E.g., this works:
220+
>
221+
> ```rust
222+
> #![no_implicit_prelude]
223+
> fn main() { assert!(true); }
224+
> ```
225+
>
226+
> Don't rely on this behavior; it may be removed in the future. Always bring the items you need into scope explicitly when using `#![no_implicit_prelude]`.
227+
>
228+
> For details, see [Rust PR #62086](https://github.com/rust-lang/rust/pull/62086) and [Rust PR #139493](https://github.com/rust-lang/rust/pull/139493).
229+
193230
r[names.preludes.no_implicit_prelude.lang]
194231
The `no_implicit_prelude` attribute does not affect the [language prelude].
195232
@@ -206,6 +243,7 @@ r[names.preludes.no_implicit_prelude.edition2018]
206243
[Built-in attributes]: ../attributes.md#built-in-attributes-index
207244
[extern prelude]: #extern-prelude
208245
[floating-point types]: ../types/numeric.md#floating-point-types
246+
[glob import]: items.use.glob
209247
[Integer types]: ../types/numeric.md#integer-types
210248
[Language prelude]: #language-prelude
211249
[Machine-dependent integer types]: ../types/numeric.md#machine-dependent-integer-types

0 commit comments

Comments
 (0)