Skip to content

incremental compilation + proc macros: undefined symbol error #47292

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

Closed
rukai opened this issue Jan 9, 2018 · 14 comments
Closed

incremental compilation + proc macros: undefined symbol error #47292

rukai opened this issue Jan 9, 2018 · 14 comments
Assignees
Labels
A-decl-macros-2-0 Area: Declarative macros 2.0 (#39412) A-incr-comp Area: Incremental compilation T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@rukai
Copy link
Contributor

rukai commented Jan 9, 2018

error: /home/rubic/Projects/Crates/syn/examples/heapsize2/example/target/debug/deps/libheapsize_derive-3ef99e9f83ff68d2.so: undefined symbol: __rustc_derive_registrar__59da0d2c3725c53af805cb0071a3b093_24
 --> src/main.rs:2:1
  |
2 | extern crate heapsize_derive;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Disabling incremental compilation or deleting the build files fixes the issue.

$ rustc --version --verbose
rustc 1.25.0-nightly (b5392f545 2018-01-08)
binary: rustc
commit-hash: b5392f54503fdaf04df4b9578510b2baa944f4af
commit-date: 2018-01-08
host: x86_64-unknown-linux-gnu
release: 1.25.0-nightly
LLVM version: 4.0

Steps to reproduce

  1. git clone https://github.com/dtolnay/syn
  2. cd syn/examples/heapsize2/example/src/ && CARGO_INCREMENTAL=1 cargo run (build succeeds as expected)
  3. at syn/examples/heapsize2/heapsize_derive/src/lib.rs:20 insert a line "foo()"
  4. cd syn/examples/heapsize2/example/src/ && CARGO_INCREMENTAL=1 cargo run (build fails as expected)
  5. at syn/examples/heapsize2/heapsize_derive/src/lib.rs:16 insert a line "fn foo() { }"
  6. cd syn/examples/heapsize2/example/src/ && CARGO_INCREMENTAL=1 cargo run (build fails with error above)

In case the changes to source code above weren't clear, refer to the commits 1 & 2 https://github.com/rukai/syn/commits/bug

@michaelwoerister
Copy link
Member

Thanks for the bug report, @rukai!

@michaelwoerister
Copy link
Member

Let's see if #47181 fixes this...

@michaelwoerister michaelwoerister self-assigned this Jan 9, 2018
@michaelwoerister michaelwoerister added A-incr-comp Area: Incremental compilation A-decl-macros-2-0 Area: Declarative macros 2.0 (#39412) labels Jan 9, 2018
@dtolnay
Copy link
Member

dtolnay commented Jan 14, 2018

@michaelwoerister #47181 did not fix this. I am still seeing the same thing on rustc 1.25.0-nightly (e6072a7 2018-01-13) which contains that PR.

@michaelwoerister
Copy link
Member

Thanks a lot for verifying.

Nominating for priority assignment (I'd say P-High).

@michaelwoerister michaelwoerister added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 15, 2018
@michaelwoerister
Copy link
Member

A couple of questions for people knowing about proc-macros (@dtolnay, @jseyfried, @alexcrichton, maybe?):

  • Is there ever going to be more than one macro_derive_registrar function per crate?
  • Is the symbol naming scheme fixed somewhere or can we change it?

@alexcrichton
Copy link
Member

@michaelwoerister there should only be one per crate which is generated by the compiler, so we should have complete control over it.

@alexcrichton
Copy link
Member

Syntactically it's manufactured here

@michaelwoerister
Copy link
Member

Ok, so generate_derive_registrar_symbol() doesn't actually have to factor the registrar's DefIndex into the symbol name in order to make it unique in the crate graph. Removing the DefIndex should fix this bug.

@michaelwoerister
Copy link
Member

I know what's going on here now: The registrar function is generated in its own module, which means that it is not recompiled during incremental compilation unless its contents change. The symbol for the registrar contains the raw DefIndex though, so placing anything with a DefIndex before the generated registrar will change the DefIndex of the registrar and thus also change the symbol we expect it to have. But the object file has been cached, so the actual symbol name does not change. This leads to a mismatch between the actual symbol name and the symbol name that we write into crate metadata.

I think the best solution is to just remove the DefIndex from the symbol name since it is redundant anyway. The same probably goes for regular plugins?

@alexcrichton
Copy link
Member

@michaelwoerister ah sounds like that'd do it!

Unfortunately I don't know enough about regular plugins to know whether this is enough for them.

@michaelwoerister
Copy link
Member

Working on a PR right now.

@michaelwoerister
Copy link
Member

Removed nomination since there's already a fix in the queue.

bors added a commit that referenced this issue Jan 19, 2018
…omatsakis

Don't include DefIndex in proc-macro registrar function symbol.

There can only ever be one registrar function per plugin or proc-macro crate, so adding the `DefIndex` to the function's symbol name does not serve a real purpose. Remove the `DefIndex` from the symbol name makes it stable across incremental compilation sessions.

This should fix issue #47292.
@Techcable
Copy link

This seems to be fixed now that you've merged #47494 , as I don't encounter it anymore.

@dtolnay
Copy link
Member

dtolnay commented Jan 20, 2018

Confirmed fixed. Thanks!

@dtolnay dtolnay closed this as completed Jan 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-decl-macros-2-0 Area: Declarative macros 2.0 (#39412) A-incr-comp Area: Incremental compilation T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants