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

You aren't allowed to use i32 or use self::i32 #3429

Open
liamnaddell opened this issue Feb 12, 2025 · 13 comments
Open

You aren't allowed to use i32 or use self::i32 #3429

liamnaddell opened this issue Feb 12, 2025 · 13 comments

Comments

@liamnaddell
Copy link
Contributor

I tried the following code:

use i32 as B; // { dg-error "unresolved import .self::i32." }

fn main() -> isize {
    let i: i32 = 0 as i32;
    i as isize
}

What I expected:

TRS-E14 build $ rustc issue-3315-2.rs
error[E0432]: unresolved import `i32`
 --> issue-3315-2.rs:2:5
  |
2 | use i32 as B; // { dg-error "unresolved import .self::i32." }
  |     ^^^^^^^^ no `i32` in the root
  |
help: consider importing one of these items instead
  |
2 | use std::i32 as B; // { dg-error "unresolved import .self::i32." }
  |     ~~~~~~~~~~~~~
2 | use std::primitive::i32 as B; // { dg-error "unresolved import .self::i32." }
  |     ~~~~~~~~~~~~~~~~~~~~~~~~

What I got:
gccrs compiles this code with no error

Source: https://doc.rust-lang.org/reference/names/preludes.html, "These prelude names are not part of the module itself: they are implicitly queried during name resolution. For example, even though something like Box is in scope in every module, you cannot refer to it as self::Box because it is not a member of the current module."

@powerboat9
Copy link
Collaborator

I wish I had read that paragraph earlier -- makes implementation easier

@liamnaddell
Copy link
Contributor Author

I think I might be able to get it working on NR2 with the prelude fixes, but no promises yet -- I'm having some trouble resolving modules separately from other types at the moment.

@powerboat9
Copy link
Collaborator

powerboat9 commented Feb 12, 2025

Maybe try using the builtin prelude only on single-segment paths?

@powerboat9
Copy link
Collaborator

Nevermind (comment/uncomment line)

@liamnaddell
Copy link
Contributor Author

Yea... I saw a case that's similar to this. Modules have to be being handled differently somehow, because the rules are applied differently for modules and structs (despite them both being in the TYpes namespace)

@liamnaddell
Copy link
Contributor Author

Maybe try using the builtin prelude only on single-segment paths?

This won't work because you can reference multisegment types out of the prelude, for example, Option::Some(1) works without importing Option

@liamnaddell
Copy link
Contributor Author

Like rustc seems to do the following:

if (mod_shadows_builtin) {
    resolve to builtin
} else if (struct_shadows_builtin) {
  resolve to struct
}

Which is super super weird

@powerboat9
Copy link
Collaborator

Like rustc seems to do the following:

if (mod_shadows_builtin) {
    resolve to builtin
} else if (struct_shadows_builtin) {
  resolve to struct
}

Which is super super weird

It gets even weirder -- see this

@powerboat9
Copy link
Collaborator

It seems like rust tries to resolve paths without the language prelude, and then tries again with the language prelude if the first attempt didn't succeed.

@powerboat9
Copy link
Collaborator

It appears to only retry if every segment in the path is either

  1. unresolved
  2. resolved to a module

@liamnaddell
Copy link
Contributor Author

It appears to only retry if every segment in the path is either

1. unresolved

2. resolved to a module

You can see roughly how I'm trying to solve the problem: liamnaddell@f25bbab

Basically I added a special prelude rib, then dumped the language prelude in there, then treated it as a "resolution of last resort" for single-segment identifiers.

That actually solves the "module w/ name i32 causes ice" problem, but it doesn't address this test case correctly:

mod i32 {
}
fn main() -> isize {
    let i: i32 = 0 as i32;
    i as isize
}

Because the code I wrote gets confused and thinks i32 in 0 as i32 is talking about the module.

At this point I'm thinking about some sort of weird precedence rule where we try resolving structs first, then language prelude, then modules, but that just kinda seems dumb...

Maybe it's a good idea to break this up into a separate issue for the wacky module resolution rules?

@powerboat9
Copy link
Collaborator

I left a few comments on the commit (didn't know that was possible 10 minutes ago), but yeah, it doesn't look like there's an easy way to solve this. I'm going to look through the rustc source code to see if I can figure out what's going on.

@liamnaddell
Copy link
Contributor Author

I left a few comments on the commit (didn't know that was possible 10 minutes ago), but yeah, it doesn't look like there's an easy way to solve this. I'm going to look through the rustc source code to see if I can figure out what's going on.

Thanks for the review comments. I'll make a separate issue about the shadow shenanigans

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants