Commit Graph

424 Commits

Author SHA1 Message Date
Jacob Pratt
25b81bf5ad Rollup merge of #145590 - nnethercote:ModKind-Inline, r=petrochenkov
Prevent impossible combinations in `ast::ModKind`.

`ModKind::Loaded` has an `inline` field and a `had_parse_error` field. If the `inline` field is `Inline::Yes` then `had_parse_error` must be `Ok(())`.

This commit moves the `had_parse_error` field into the `Inline::No` variant. This makes it impossible to create the nonsensical combination of `inline == Inline::Yes` and `had_parse_error = Err(_)`.

r? ```@Urgau```
2025-08-21 01:12:19 -04:00
Nicholas Nethercote
bfd5d59f97 Prevent impossible combinations in ast::ModKind.
`ModKind::Loaded` has an `inline` field and a `had_parse_error` field.
If the `inline` field is `Inline::Yes` then `had_parse_error` must be
`Ok(())`.

This commit moves the `had_parse_error` field into the `Inline::No`
variant. This makes it impossible to create the nonsensical combination
of `inline == Inline::Yes` and `had_parse_error = Err(_)`.
2025-08-19 21:57:31 +10:00
Esteban Küber
8baab4cdf7 Detect missing derive on unresolved attribute even when not imported
```
error: cannot find attribute `sede` in this scope
  --> $DIR/missing-derive-3.rs:20:7
   |
LL |     #[sede(untagged)]
   |       ^^^^
   |
help: the derive macros `Deserialize` and `Serialize` accept the similarly named `serde` attribute
   |
LL |     #[serde(untagged)]
   |         +

error: cannot find attribute `serde` in this scope
  --> $DIR/missing-derive-3.rs:14:7
   |
LL |     #[serde(untagged)]
   |       ^^^^^
   |
note: `serde` is imported here, but it is a crate, not an attribute
  --> $DIR/missing-derive-3.rs:4:1
   |
LL | extern crate serde;
   | ^^^^^^^^^^^^^^^^^^^
help: `serde` is an attribute that can be used by the derive macros `Deserialize` and `Serialize`, you might be missing a `derive` attribute
   |
LL + #[derive(Deserialize, Serialize)]
LL | enum B {
   |
```
2025-08-15 15:56:45 +00:00
Esteban Küber
caadc8df35 Do not ICE on private type in field of unresolved struct 2025-08-14 15:59:32 +00:00
Vadim Petrochenkov
9b797b9f7a resolve: Improve code reuse in typo candidate collection 2025-08-14 09:53:49 +03:00
Vadim Petrochenkov
d682943396 resolve: Do not show deprecated helper attributes in typo recommendations
Remove one FIXME, addressing it does not reduce the hacky-ness much, and the logic is going to be removed anyway together with the `legacy_derive_helpers` deprecation lint.
2025-08-14 09:53:49 +03:00
Vadim Petrochenkov
51eb5ed8f0 resolve: Do not call resolve_macro_path from late resolution
`maybe_resolve_path` is less precise in corner cases, but it's only used for diagnostics and error recovery, so it's good enough.
2025-08-14 09:53:46 +03:00
bors
8e7795415a Auto merge of #144793 - petrochenkov:extprel3, r=davidtwco
resolve: Split extern prelude into two scopes

One scope for `extern crate` items and another for `--extern` options, with the former shadowing the latter.

If in a single scope some things can overwrite other things, especially with ad hoc restrictions like `MacroExpandedExternCrateCannotShadowExternArguments`, then it's not really a single scope.
So this PR splits `Scope::ExternPrelude` into two cleaner scopes.

This is similar to how https://github.com/rust-lang/rust/pull/144131 splits module scope into two scopes for globs and non-globs, but simpler.
2025-08-13 22:52:17 +00:00
Vadim Petrochenkov
d98eaad509 resolve: Improve diagnostics for ambiguities in extern prelude 2025-08-13 17:45:40 +03:00
Vadim Petrochenkov
772493d51d resolve: Split extern prelude into two scopes
One for `--extern` options and another for `extern crate` items.
2025-08-13 17:45:40 +03:00
Josh Triplett
ba231db3f3 Detect and report macro kind mismatches early, and more precisely
This eliminates the case in `failed_to_match_macro` to check for a
function-like invocation of a macro with no function-like rules.

Instead, macro kind mismatches now result in an unresolved macro, and we
detect this case in `unresolved_macro_suggestions`, which now carefully
distinguishes between a kind mismatch and other errors.

This also handles cases of forward-referenced attributes and cyclic
attributes.

Expand test coverage to include all of these cases.
2025-08-12 09:24:45 -07:00
Josh Triplett
0b855bcdc9 Switch to a bitflags MacroKinds to support macros with more than one kind
Review everything that uses `MacroKind`, and switch anything that could
refer to more than one kind to use `MacroKinds`.

Add a new `SyntaxExtensionKind::MacroRules` for `macro_rules!` macros,
using the concrete `MacroRulesMacroExpander` type, and have it track
which kinds it can handle. Eliminate the separate optional `attr_ext`,
now that a `SyntaxExtension` can handle multiple macro kinds.

This also avoids the need to downcast when calling methods on
`MacroRulesMacroExpander`, such as `get_unused_rule`.

Integrate macro kind checking into name resolution's
`sub_namespace_match`, so that we only find a macro if it's the right
type, and eliminate the special-case hack for attributes.
2025-08-12 09:24:45 -07:00
Esteban Küber
29d26f27a6 review comments 2025-08-10 19:15:20 +00:00
Esteban Küber
464a6b1b4a Detect struct construction with private field in field with default
When trying to construct a struct that has a public field of a private type, suggest using `..` if that field has a default value.

```
error[E0603]: struct `Priv1` is private
  --> $DIR/non-exhaustive-ctor.rs:25:39
   |
LL |     let _ = S { field: (), field1: m::Priv1 {} };
   |                            ------     ^^^^^ private struct
   |                            |
   |                            while setting this field
   |
note: the struct `Priv1` is defined here
  --> $DIR/non-exhaustive-ctor.rs:14:4
   |
LL |    struct Priv1 {}
   |    ^^^^^^^^^^^^
help: the field `field1` you're trying to set has a default value, you can use `..` to use it
   |
LL |     let _ = S { field: (), .. };
   |                            ~~
```
2025-08-10 19:15:18 +00:00
Deadbeef
ad1113f87e remove P 2025-08-09 15:47:01 +08:00
Stuart Cook
ecce94c0a5 Rollup merge of #144912 - LorrensP-2158466:smart-resolver, r=petrochenkov
Resolver: introduce a conditionally mutable Resolver for (non-)speculative resolution.

This pr introduces a `CmResolver`, a wrapper around the main resolver which gives out mutable access given a condition.

`CmResolver` only allows mutation when we’re not in speculative import resolution. This ensures we can’t accidentally mutate the resolver during this process, which is important as we move towards a batched resolution algorithm.

This also changes functions that are used during speculative import resolution to take a `CmResolver` instead of a `&mut Resolver`.

Also introduces a new kind of "smart pointer" which has the behaviour described above:
```rust
/// A wrapper around a mutable reference that conditionally allows mutable access.
pub(crate) struct RefOrMut<'a, T> {
    p: &'a mut T,
    mutable: bool,
}

type CmResolver<'r, 'ra, 'tcx> = RefOrMut<'r, Resolver<'ra, 'tcx>>;
```
r? petrochenkov
2025-08-08 12:52:52 +10:00
LorrensP-2158466
487e5ce371 Introduce, implement and use CmResolver. 2025-08-07 16:05:00 +02:00
xizheyin
6e7b9d5149 Introduce ModernIdent type to unify macro 2.0 hygiene handling
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
2025-08-06 21:19:09 +08:00
Stuart Cook
2105044784 Rollup merge of #144746 - petrochenkov:extpreltidy, r=b-naber
resolve: Cleanups and micro-optimizations to extern prelude

This is what can be done without changing the structure of `ExternPreludeEntry`, like in https://github.com/rust-lang/rust/pull/144737.

See individual commits for details.
2025-08-04 11:24:39 +10:00
bors
889701db1f Auto merge of #129183 - estebank:cfg-visitor, r=davidtwco
Detect more `cfg`d out items in resolution errors

Use a visitor to collect *all* items (including those nested) that were stripped behind a `cfg` condition.

```
error[E0425]: cannot find function `f` in this scope
  --> $DIR/nested-cfg-attrs.rs:4:13
   |
LL | fn main() { f() }
   |             ^ not found in this scope
   |
note: found an item that was configured out
  --> $DIR/nested-cfg-attrs.rs:2:4
   |
LL | fn f() {}
   |    ^
note: the item is gated here
  --> $DIR/nested-cfg-attrs.rs:1:35
   |
LL | #[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))]
   |                                   ^^^^^^^^^^
```
2025-08-02 05:09:31 +00:00
Esteban Küber
4b24c4bf23 Tweak rendering of cfg'd out item
```
error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner`
  --> $DIR/diagnostics-cross-crate.rs:18:23
   |
LL |     cfged_out::inner::doesnt_exist::hello();
   |                       ^^^^^^^^^^^^ could not find `doesnt_exist` in `inner`
   |
note: found an item that was configured out
  --> $DIR/auxiliary/cfged_out.rs:6:13
   |
LL |     #[cfg(false)]
   |           ----- the item is gated here
LL |     pub mod doesnt_exist {
   |             ^^^^^^^^^^^^
```
2025-08-01 23:58:15 +00:00
Esteban Küber
77f75f91c5 tiny cleanup 2025-08-01 22:11:45 +00:00
Esteban Küber
adcda6ca9a Detect more cfgd out items in resolution errors
Use a visitor to collect *all* items (including those nested) that were stripped behind a `cfg` condition.

```
error[E0425]: cannot find function `f` in this scope
  --> $DIR/nested-cfg-attrs.rs:4:13
   |
LL | fn main() { f() }
   |             ^ not found in this scope
   |
note: found an item that was configured out
  --> $DIR/nested-cfg-attrs.rs:2:4
   |
LL | fn f() {}
   |    ^
note: the item is gated here
  --> $DIR/nested-cfg-attrs.rs:1:35
   |
LL | #[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))]
   |                                   ^^^^^^^^^^
```
2025-08-01 21:50:36 +00:00
Vadim Petrochenkov
e58e6f857f resolve: Cleanup some uses of extern prelude in diagnostics 2025-07-31 20:35:14 +03:00
Jana Dönszelmann
e1d3ad89c7 remove rustc_attr_data_structures 2025-07-31 14:19:27 +02:00
LorrensP-2158466
451a93e2b8 split up define into define_extern and define_local 2025-07-27 12:17:23 +02:00
Vadim Petrochenkov
e82011255b resolve: Do not create NameResolutions on access unless necessary 2025-07-26 00:25:26 +03:00
Vadim Petrochenkov
2c65790160 resolve: Minimize borrow scopes for resolutions 2025-07-26 00:19:12 +03:00
Vadim Petrochenkov
9ffa775232 resolve: Remove Scope::CrateRoot
Use `Scope::Module` with the crate root module inside instead, which should be identical.
2025-07-24 15:59:47 +03:00
LorrensP-2158466
466d33cb5c inline CrateLoader inside of CStore 2025-07-18 13:16:09 +02:00
Matthias Krüger
52a405b6c9 Rollup merge of #143550 - petrochenkov:lessmutres, r=lcnr
resolve: Use interior mutability for extern module map

Module map for extern modules is a lazily populated cache, it's not *significantly* mutable.
If some logic in name resolver is parallelized, then this cache can be populated from any thread, and without affecting results of any speculative resolution.

Unblocks https://github.com/rust-lang/rust/pull/143884.
This is a part of [#gsoc > Project: Parallel Macro Expansion](https://rust-lang.zulipchat.com/#narrow/channel/421156-gsoc/topic/Project.3A.20Parallel.20Macro.20Expansion/with/527348747).
cc `@LorrensP-2158466`
2025-07-17 10:41:44 +02:00
Vadim Petrochenkov
6849f816b1 resolve: Change &mut Resolver to &Resolver when possible 2025-07-17 02:09:01 +03:00
Vadim Petrochenkov
8b8889df25 resolve: Split module_map into two maps for local and extern modules 2025-07-17 02:09:01 +03:00
Vadim Petrochenkov
8d7193973f resolve: Use module_map and get_module less 2025-07-17 02:09:00 +03:00
Nicholas Nethercote
fb7aa9e4fd Improve path segment joining.
There are many places that join path segments with `::` to produce a
string. A lot of these use `join("::")`. Many in rustdoc use
`join_with_double_colon`, and a few use `.joined("..")`. One in Clippy
uses `itertools::join`. A couple of them look for `kw::PathRoot` in the
first segment, which can be important.

This commit introduces `rustc_ast::join_path_{syms,ident}` to do the
joining for everyone. `rustc_ast` is as good a location for these as
any, being the earliest-running of the several crates with a `Path`
type. Two functions are needed because `Ident` printing is more complex
than simple `Symbol` printing.

The commit also removes `join_with_double_colon`, and
`estimate_item_path_byte_length` with it.

There are still a handful of places that join strings with "::" that are
unchanged. They are not that important: some of them are in tests, and
some of them first split a path around "::" and then rejoin with "::".

This fixes one test case where `{{root}}` shows up in an error message.
2025-07-17 08:37:19 +10:00
Vadim Petrochenkov
babe2c0d0f resolve: Merge NameBindingKind::Module into NameBindingKind::Res 2025-07-16 08:28:17 +03:00
Jonathan Brouwer
6133c676d7 Define attribute parser & config evaluator 2025-07-15 09:21:26 +02:00
b-naber
9ed5378cfd replace binding and shadowed_glob on NameResolution with non_glob_binding and glob_binding 2025-07-12 15:06:32 +02:00
LorrensP-2158466
e9e31b1a93 MacroData in ResolverArenas + split macro_map into extern_macro_map and local_macro_map. 2025-07-09 23:24:36 +02:00
Jonathan Brouwer
027126ce0b Port #[non_exhaustive] to the new attribute parsing infrastructure 2025-07-04 20:30:42 +02:00
Matthias Krüger
190a1a7f74 Rollup merge of #142730 - bend-n:suggest_declaring_modules_when_file_found_but_module_not_defined, r=petrochenkov
suggest declaring modules when file found but module not defined

suggests declaring modules when a module is found but not defined, i.e
```
├── main.rs: `use thing::thang;`
└── thing.rs: `struct thang`
```
or
```
├── main.rs: `use thing::thang;`
└── thing
    └── mod.rs: `struct thang`
```
which currently is just
```rust
error[E0432]: unresolved import `yeah`
 --> src/main.rs:1:1
  |
1 | use thing::thang;
  |     ^^^^^ use of unresolved module or unlinked crate `thing`
  |
```
but now would have this nice help:
```text
= help: you may have forgotten to declare the module `thing`. use `mod thing` in this file to declare this module.
```
2025-06-27 22:13:02 +02:00
xizheyin
d2d17c60bd Add runtime check to avoid overwrite arg easily in diag and store and restore snapshot when set subdiag arg
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
2025-06-25 21:07:16 +08:00
bendn
3583423536 suggest declaring modules when file found but module not defined 2025-06-25 01:12:15 +07:00
Esteban Küber
92a798dac0 Detect when attribute is provided by missing derive macro
```
error: cannot find attribute `empty_helper` in this scope
  --> $DIR/derive-helper-legacy-limits.rs:17:3
   |
LL | #[empty_helper]
   |   ^^^^^^^^^^^^
   |
help: `empty_helper` is an attribute that can be used by the derive macro `Empty`, you might be missing a `derive` attribute
   |
LL + #[derive(Empty)]
LL | struct S2;
   |
```

Look at proc-macro attributes when encountering unknown attribute

```
error: cannot find attribute `sede` in this scope
  --> src/main.rs:18:7
   |
18 |     #[sede(untagged)]
   |       ^^^^
   |
help: the derive macros `Serialize` and `Deserialize` accept the similarly named `serde` attribute
   |
18 |     #[serde(untagged)]
   |       ~~~~~

error: cannot find attribute `serde` in this scope
  --> src/main.rs:12:7
   |
12 |     #[serde(untagged)]
   |       ^^^^^
   |
   = note: `serde` is in scope, but it is a crate, not an attribute
help: `serde` is an attribute that can be used by the derive macros `Serialize` and `Deserialize`, you might be missing a `derive` attribute
   |
10 | #[derive(Serialize, Deserialize)]
   |
```
2025-06-12 21:28:49 +00:00
bohan
e9080948c6 consider glob imports in cfg suggestion 2025-05-28 00:59:47 +08:00
bohan
1adfdb42b9 Use crate:: prefix for root macro suggestions 2025-05-17 22:01:57 +08:00
mu001999
7c253ac504 Suggest stable candidates rather than unstable ones 2025-05-09 22:05:59 +08:00
Vadim Petrochenkov
3eee3dad5c resolve: Support imports of associated types and glob imports from traits 2025-05-02 15:59:38 +03:00
Oli Scherer
24efefafcb Avoid a reverse map that is only used in diagnostics paths 2025-04-11 09:33:38 +00:00
Nicholas Nethercote
1b3fc585cb Rename some name variables as ident.
It bugs me when variables of type `Ident` are called `name`. It leads to
silly things like `name.name`. `Ident` variables should be called
`ident`, and `name` should be used for variables of type `Symbol`.

This commit improves things by by doing `s/name/ident/` on a bunch of
`Ident` variables. Not all of them, but a decent chunk.
2025-04-10 09:30:55 +10:00