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

decl_macro incremental compilation bug: missing field #112680

Closed
dawnofmidnight opened this issue Jun 15, 2023 · 1 comment · Fixed by #127279
Closed

decl_macro incremental compilation bug: missing field #112680

dawnofmidnight opened this issue Jun 15, 2023 · 1 comment · Fixed by #127279
Labels
A-incr-comp Area: Incremental compilation A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-macros-2.0 Area: Declarative macros 2.0 (#39412) C-bug Category: This is a bug. F-decl_macro `#![feature(decl_macro)]` S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue

Comments

@dawnofmidnight
Copy link
Contributor

dawnofmidnight commented Jun 15, 2023

Note: This may be a duplicate, but I couldn't find one, so I'm going ahead and reporting it.

When using decl_macro, I'm encountering a strange incremental compilation bug. I have a struct, declared as follows:

use a::entity_impl;
entity_impl!(TestId, Test); // entity_impl! is the `decl_macro`

struct Test(u32);
// now uncomment the following, and comment the above
// struct Test;

To reproduce this, do the following:

  1. Run cargo clean, then cargo check.
  2. Comment line 3, and uncomment line 5.
  3. Run cargo check again. The error below is emitted.
  4. If cargo clean && cargo check is run again with either version, it compiles fine.

I don't understand why this would happen, but I do have the code, all of which can be found in this repository. a/src/lib.rs has the entity_impl macros 2.0 macro, while b/src/lib.rs has the struct & macro invocation shown above. I've minimized the example as best I can, but a normal (non-decl_macro) does not work, and I can't seem to reproduce in a single crate. If there's anything else needed, or anything I should try, please let me know.

Error message:

error[E0609]: no field `inner` on type `TestId`
 --> b/src/lib.rs:2:1
  |
2 | entity_impl!(TestId, Test);
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `inner`
  |
  = note: this error originates in the macro `entity_impl` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0609`.
error: could not compile `b` (lib) due to previous error

Meta

rustc --version --verbose:

rustc 1.72.0-nightly (8c74a5d27 2023-06-14)
binary: rustc
commit-hash: 8c74a5d27c644a0f7a22bb2fa8dd3ff8257bc220
commit-date: 2023-06-14
host: x86_64-unknown-linux-gnu // also reproduces on x86_64-pc-windows-msvc
release: 1.72.0-nightly
LLVM version: 16.0.5

@rustbot label +A-incr-comp +A-macros-2.0
(I'm just guessing on these labels.)

@dawnofmidnight dawnofmidnight added the C-bug Category: This is a bug. label Jun 15, 2023
@jyn514 jyn514 added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-macros-2.0 Area: Declarative macros 2.0 (#39412) A-incr-comp Area: Incremental compilation S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue labels Jun 16, 2023
@Noratrieb Noratrieb added the F-decl_macro `#![feature(decl_macro)]` label Jun 16, 2023
@Noratrieb
Copy link
Member

full code
a

#![feature(decl_macro)]

pub trait Entity {
    type Key;
    fn index_from_key(key: Self::Key) -> usize;
}

pub macro entity_impl($key_ty:ident, $val_ty:ident) {
    struct $key_ty {
        inner: usize,
    }

    impl ::a::Entity for $val_ty {
        type Key = $key_ty;

        fn index_from_key(key: Self::Key) -> usize {
            key.inner
        }
    }
}

// does not reproduce with this uncommented, and the macro above commented
// #[macro_export]
// macro_rules! entity_impl {
//     ($key_ty:ident, $val_ty:ident) => {
//         struct $key_ty {
//             inner: usize,
//         }

//         impl ::a::Entity for $val_ty {
//             type Key = $key_ty;

//             fn index_from_key(key: Self::Key) -> usize {
//                 key.inner
//             }
//         }
//     }
// }

b

use a::entity_impl;
entity_impl!(TestId, Test);

struct Test(u32);
// now uncomment the following, and comment the above
// struct Test;

jieyouxu added a commit to jieyouxu/rust that referenced this issue Aug 22, 2024
use old ctx if has same expand environment during decode span

Fixes rust-lang#112680

The root reason why rust-lang#112680 failed with incremental compilation on the second attempt is the difference in `opaque` between the span of the field [`ident`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir_typeck/src/expr.rs#L2348) and the span in the incremental cache at `tcx.def_ident_span(field.did)`.

-  Let's call the span of `ident` as `span_a`, which is generated by [`apply_mark_internal`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/hygiene.rs#L553-L554). Its content is similar to:

```rs
span_a_ctx -> SyntaxContextData {
      opaque: span_a_ctx,
      opaque_and_semitransparent: span_a_ctx,
      // ....
}
```

- And call the span of `tcx.def_ident_span` as `span_b`, which is generated by [`decode_syntax_context`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/hygiene.rs#L1390). Its content is:

```rs
span_b_ctx -> SyntaxContextData {
      opaque: span_b_ctx,
      // note `span_b_ctx` is not same as `span_a_ctx`
      opaque_and_semitransparent: span_b_ctx,
      // ....
}
```

Although they have the same `parent` (both refer to the root) and `outer_expn`, I cannot find the specific connection between them. Therefore, I chose a solution that may not be the best: give up the incremental compile cache to ensure we can use `span_a` in this case.

r?  ``@petrochenkov`` Do you have any advice on this? Or perhaps this solution is acceptable?
@bors bors closed this as completed in 221b53c Aug 22, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Aug 22, 2024
Rollup merge of rust-lang#127279 - bvanjoi:fix-112680, r=petrochenkov

use old ctx if has same expand environment during decode span

Fixes rust-lang#112680

The root reason why rust-lang#112680 failed with incremental compilation on the second attempt is the difference in `opaque` between the span of the field [`ident`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir_typeck/src/expr.rs#L2348) and the span in the incremental cache at `tcx.def_ident_span(field.did)`.

-  Let's call the span of `ident` as `span_a`, which is generated by [`apply_mark_internal`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/hygiene.rs#L553-L554). Its content is similar to:

```rs
span_a_ctx -> SyntaxContextData {
      opaque: span_a_ctx,
      opaque_and_semitransparent: span_a_ctx,
      // ....
}
```

- And call the span of `tcx.def_ident_span` as `span_b`, which is generated by [`decode_syntax_context`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/hygiene.rs#L1390). Its content is:

```rs
span_b_ctx -> SyntaxContextData {
      opaque: span_b_ctx,
      // note `span_b_ctx` is not same as `span_a_ctx`
      opaque_and_semitransparent: span_b_ctx,
      // ....
}
```

Although they have the same `parent` (both refer to the root) and `outer_expn`, I cannot find the specific connection between them. Therefore, I chose a solution that may not be the best: give up the incremental compile cache to ensure we can use `span_a` in this case.

r?  `@petrochenkov` Do you have any advice on this? Or perhaps this solution is acceptable?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-incr-comp Area: Incremental compilation A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-macros-2.0 Area: Declarative macros 2.0 (#39412) C-bug Category: This is a bug. F-decl_macro `#![feature(decl_macro)]` S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants
@jyn514 @Noratrieb @dawnofmidnight and others