Skip to content
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

rustc_resolve: Test the order that preludes are resolved #138840

Merged
merged 1 commit into from
Apr 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions tests/ui/resolve/auxiliary/macro_helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* macro namespace. */

extern crate proc_macro;
use proc_macro::*;
use std::str::FromStr;

const ERROR: &str = "fn helper() { \"helper\" }";
// https://doc.rust-lang.org/nightly/std/prelude/v1/index.html#attributes
// NOTE: all the bang macros in std are currently unstable.
#[proc_macro_attribute] pub fn test // lang.
(_: TokenStream, _: TokenStream) -> TokenStream {
TokenStream::from_str("fn test_macro() { \"\" }").unwrap() }
// https://doc.rust-lang.org/nightly/reference/attributes.html#built-in-attributes-index
#[proc_macro_attribute] pub fn global_allocator // lang.
(_: TokenStream, _: TokenStream) -> TokenStream {
TokenStream::from_str("fn global_allocator_macro() { \"\" }").unwrap() }
89 changes: 89 additions & 0 deletions tests/ui/resolve/prelude-order.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//@ proc-macro:macro_helpers.rs
//@ compile-flags: --crate-type=lib

/* There are 5 preludes and 3 namespaces. Test the order in which they are resolved.
* See https://doc.rust-lang.org/nightly/reference/names/preludes.html.
*
* Macros cannot be in the type or value namespace.
* Tools and extern crates cannot be in the macro or value namespace.
*
* Test the following truth tables:

Type:
| ...... | tool | extern | macro | lang | libs |
| tool | N/A | mirror
| extern | extern | N/A | universe
| macro | N/A | N/A | N/A |
| lang | tool | extern | N/A | N/A |
| libs | tool | extern | N/A | X | N/A |

Macro:
| ...... | tool | extern | macro | lang | libs |
| tool | N/A | mirror
| extern | N/A | N/A | universe
| macro | N/A | N/A | N/A |
| lang | N/A | N/A | macro | N/A |
| libs | N/A | N/A | macro | X | N/A |

Value: N/A. Only libs has items in the value namespace.

† ambiguous
X don't care (controlled namespace with no overlap)

* Types are tested with `#[name::inner]`. Macros are tested with `#[name]`.
* WARNING: I have found in testing that attribute macros give ambiguity errors in some contexts
* instead of choosing a prelude. Have not been able to replicate.
*
* There should be 7 total tests.
* See `rustc_resolve::ident::visit_scopes` for more information,
* and for a definition of "controlled namespace".
*/

#![feature(register_tool)]

/* tool prelude */
#![register_tool(type_ns)] // extern prelude. type.
#![register_tool(i8)] // lang prelude. type.
#![register_tool(Sync)] // libs prelude. type.

/* extern prelude */
extern crate macro_helpers as type_ns; // tool prelude. type.
extern crate macro_helpers as usize; // lang prelude. type.
extern crate macro_helpers as Option; // libs prelude. type.

/* macro_use prelude */
#[macro_use]
extern crate macro_helpers as _;

/* lang and libs implicitly in scope */

// tool/extern -> extern
#[type_ns::inner] //~ ERROR could not find `inner` in `type_ns`
fn t1() {}

// tool/lang -> tool
#[i8::inner] // ok
fn t2() {}

// tool/libs -> tool
#[Sync::not_real] // ok
fn t3() {}

// extern/lang -> extern
#[usize::inner] //~ ERROR could not find `inner` in `usize`
fn e1() {} // NOTE: testing with `-> usize` isn't valid, crates aren't considered in that scope
// (unless they have generic arguments, for some reason.)

// extern/libs -> extern
// https://github.com/rust-lang/rust/issues/139095
fn e2() -> Option<i32> { None } //~ ERROR: expected type, found crate

// macro/libs -> macro
#[test] //~ ERROR mismatched types
fn m1() {}

// macro/lang -> macro
#[global_allocator] //~ ERROR mismatched types
fn m2() {}

// lang/libs: no items that currently overlap, in either macro or type ns.
47 changes: 47 additions & 0 deletions tests/ui/resolve/prelude-order.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
error[E0433]: failed to resolve: could not find `inner` in `type_ns`
--> $DIR/prelude-order.rs:61:12
|
LL | #[type_ns::inner]
| ^^^^^ could not find `inner` in `type_ns`

error[E0433]: failed to resolve: could not find `inner` in `usize`
--> $DIR/prelude-order.rs:73:10
|
LL | #[usize::inner]
| ^^^^^ could not find `inner` in `usize`

error[E0573]: expected type, found crate `Option`
--> $DIR/prelude-order.rs:79:12
|
LL | fn e2() -> Option<i32> { None }
| ^^^^^^^^^^^ not a type
|
help: consider importing this enum instead
|
LL + use std::option::Option;
|

error[E0308]: mismatched types
--> $DIR/prelude-order.rs:82:1
|
LL | #[test]
| ^^^^^^^- help: try adding a return type: `-> &'static str`
| |
| expected `()`, found `&str`
|
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> $DIR/prelude-order.rs:86:1
|
LL | #[global_allocator]
| ^^^^^^^^^^^^^^^^^^^- help: try adding a return type: `-> &'static str`
| |
| expected `()`, found `&str`
|
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0308, E0433, E0573.
For more information about an error, try `rustc --explain E0308`.
Loading