-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Missing tokens in custom derive input generated by macro #51331
Comments
The behavior is correct with rustc 1.15.0 but the current incorrect behavior exists since 1.16.0. |
cc @dtolnay @rust-lang/release — perhaps somebody could bisect this to a specific nightly? (I guess it's too old to get a specific PR) cargo-bisect-rustc may help here :) |
Also, how does it come to happen that |
Marking as P-high but don't have an assignee yet, will revisit next week when we've hopefully had a chance to bisect. |
2016-12-06 has the odd result of 2016-12-27 is the first nightly to have |
These are the bors commits between those two nightlies (a173778...77f7c7a). 77f7c7a Auto merge of #38274 - elahn:windows-readconsole-ctrl-z, r=alexcrichton I think #38232, #38566, #38539, #38490, #38154 are possible candidates based on branch names. I'll try to run git bisect in this commit range. |
I was.. largely unsuccessful at running git bisect. Maybe someone else will have more luck. |
I figure it's easier to bisect the Bors commits which are sure to build correctly, rather than to run 467a7f0 Auto merge of #38533 - jseyfried:legacy_custom_derive_deprecation, r=nrc My money's on Slightly modified repro script for working with such old versions of rust#!/bin/sh
# set the linked toolchain here
TOOLCHAIN=stage2
rm -rf repro
rm -rf repro_dispatch
rm -rf repro_derive
cargo new --lib repro
cargo new --lib repro_dispatch
cargo new --lib repro_derive
echo >repro/src/lib.rs '
#[macro_use]
extern crate repro_dispatch;
#[macro_use]
extern crate repro_derive;
pub struct MyDispatch;
impl repro_dispatch::Dispatch for MyDispatch {
type Call = ();
}
problem!();
'
echo >>repro/Cargo.toml '
repro_dispatch = { path = "../repro_dispatch" }
repro_derive = { path = "../repro_derive" }
'
echo >repro_dispatch/src/lib.rs '
pub trait Dispatch {
type Call;
}
#[macro_export]
macro_rules! problem {
() => {
#[derive(Print)]
pub struct S(<MyDispatch as $crate::Dispatch>::Call);
}
}
'
echo >repro_derive/src/lib.rs '
#![feature(proc_macro, proc_macro_lib)]
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_derive(Print)]
pub fn derive(input: TokenStream) -> TokenStream {
println!("\n\n{}\n\n", input);
"".parse().unwrap()
}
'
echo >>repro_derive/Cargo.toml '
[lib]
proc-macro = true
'
CARGO_INCREMENTAL=0 cargo +$TOOLCHAIN build --manifest-path repro/Cargo.toml
CARGO_INCREMENTAL=0 cargo +$TOOLCHAIN rustc --manifest-path repro/Cargo.toml -- --version |
Okay, I have confirmed that 82611a0 exhibits the issue, and c8e7ec4 does not, so it is #38232. cc @jseyfried |
The following test case (replacing the similarly-named macro in the OP) helps clarify the nature of the bug. It is not "overwriting" the
The
(Note: tested on nightly, because I foolishly did not keep my build of 82611a0) Edit: Additionally, only the trait path is affected. Adding The PR is largely one refactoring commit. I've been reading through looking for the kinds of things that might enable a bug like this, but haven't found the culprit. |
I have a theory. I believe this was buggy prior to jseyfried's PR, but the PR caused the bug to affect this specific test case. The following function (used exclusively by However, the trait path is stored in an Prior to the PR, a path segment was deleted if (and only if) the macro was local. After the PR, a path segment is inserted if (and only if) the macro was from another crate. In each of these cases, the QSelf position field is invalidated. If my theory is correct, then prior to #38232, it should have manifested as printing extra tokens if the definition of |
I'm downloading nightlies via cargo-bisect-rustc's bisection; I also found that for some reason rustup itself refuses to install those nightlies. |
Thanks! I was able to verify my prediction; #[nonlocal]
pub struct S(<MyDispatch as ::repro_dispatch::Dispatch::Second<Test>>::Call);
#[local]
pub struct S(<MyDispatch as ::Dispatch::Second<Test>::Call>::Call); Repro with local and nonlocal macros
I'll start working on a PR. |
Silly question: Would adding an AST type like pub struct QPath(Option<QSelf>, Path); be overkill? This pattern describes all appearances of Edit: It appears that such a type in fact used to exist (evidence), which kind of explains the bizarre name of Edit 2: also perhaps libsyntax is not as malleable as I thought, due to a number of rustc plugin crates that still exist... |
Since I wasn't sure about the above, I wrote two possible fixes, both of which I am now testing:
|
@ExpHP |
Thanks for the feedback! PR is up. |
Fix for $crate var normalization in proc macro for externally defined macros Fixes #51331, a bug that has existed in at least *some* form for a year and a half. The PR includes the addition of a `fold_qpath` method to `syntax::fold::Folder`. Overriding this method is useful for folds that modify paths in a way that invalidates indices (insertion or removal of a component), as it provides the opportunity to update `qself.position` in `<A as B>::C` paths. I added it because the bugfix is messy without it. (unfortunately, grepping around the codebase, I did not see anything else that could use it.)
The script below has a macro_rules macro that expands to:
But inside of the
derive(Print)
custom derive the tokens received are:The
::Dispatch
seems to be missing.Originally reported in serde-rs/serde#1306.
rustc 1.28.0-nightly (4ecf12b 2018-06-02)
Repro script:
The text was updated successfully, but these errors were encountered: