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

rustfmt eats _ in underscore_imports (a.k.a. impl-only-use) #2887

Closed
Nemo157 opened this issue Aug 2, 2018 · 7 comments · Fixed by #2951
Closed

rustfmt eats _ in underscore_imports (a.k.a. impl-only-use) #2887

Nemo157 opened this issue Aug 2, 2018 · 7 comments · Fixed by #2951
Labels
bug Panic, non-idempotency, invalid code, etc. good first issue Issues up for grabs, also good candidates for new rustfmt contributors

Comments

@Nemo157
Copy link
Member

Nemo157 commented Aug 2, 2018

With an input file like

#![feature(underscore_imports)]

use std::iter::Iterator as _;

fn main() {}

running rustfmt on it produces

#![feature(underscore_imports)]

use std::iter::Iterator as ;

fn main() {}

Version:

rustfmt 0.9.0-nightly (69ad879d 2018-07-27)

Tracking issue for the unstable feature: rust-lang/rust#48216

@nrc nrc added bug Panic, non-idempotency, invalid code, etc. good first issue Issues up for grabs, also good candidates for new rustfmt contributors labels Aug 2, 2018
@nrc nrc added this to the 1.0 (rc) milestone Aug 2, 2018
@nrc
Copy link
Member

nrc commented Aug 2, 2018

cc @max-sixty the universe provides! This would be a great issue to start on. Look in imports.rs and look for the code dealing with aliasing. You'll want to look at libsyntax/ast.rs in the rust repo to find out how the underscore is represented, and then take that into account in the rustfmt code.

@max-sixty
Copy link
Contributor

(FYI I had a look at this over the weekend. It was a steeper learning curve than I had thought, but I'll give it another try)

@max-sixty
Copy link
Contributor

What's the easiest way for me to discover how ast parses the _? I'm struggling to even view the output of a string of code. I've read the docs but let me know if I'm missing something obvious. Thanks

@nrc
Copy link
Member

nrc commented Aug 14, 2018

@max-sixty I would run rustfmt on a very simple program using _ and then dump the entire AST (println). For the code, I would look at token.rs in the compiler - iirc, _ vs other identifiers is handled during lexing, not parsing (it's been a while though, I might be wrong).

@max-sixty
Copy link
Contributor

max-sixty commented Aug 14, 2018

For the sake of progress - and feedback if I'm doing something bad, I ran this file:

// #![allow(unused_variables)]
// #![allow(unused_imports)]
extern crate syntax;
use std::path::PathBuf;
use syntax::with_globals;

use syntax::codemap::FilePathMapping;
use syntax::parse::{filemap_to_stream, ParseSess};

fn main() {
    let parse_session = ParseSess::new(FilePathMapping::empty());
    // let p = Path::new(file!());
    // let string = "use std::iter::Iterator as _;".to_string();
    with_globals(|| {
        let stream = filemap_to_stream(
            &parse_session,
            parse_session
                .codemap()
                .new_filemap(PathBuf::from("").into(), "use a::b as _".to_string()),
            None,
        );

        println!("{:?}", stream)
    });
}

...which generated this output:

TokenStream { kind: Stream([TokenStream { kind: Tree(Token(Span { lo: BytePos(0), hi: BytePos(3), ctxt: #0 }, Ident(use#0, false))) }, TokenStream { kind: JointTree(Token(Span { lo: BytePos(4), hi: BytePos(5), ctxt: #0 }, Ident(a#0, false))) }, TokenStream { kind: Tree(Token(Span { lo: BytePos(5), hi: BytePos(7), ctxt: #0 }, ModSep)) }, TokenStream { kind: Tree(Token(Span { lo: BytePos(7), hi: BytePos(8), ctxt: #0 }, Ident(b#0, false))) }, TokenStream { kind: Tree(Token(Span { lo: BytePos(9), hi: BytePos(11), ctxt: #0 }, Ident(as#0, false))) }, TokenStream { kind: Tree(Token(Span { lo: BytePos(12), hi: BytePos(13), ctxt: #0 }, Ident(_#0, false))) }]) }

...suggesting that _ is parsed as Ident(_#0, false)

@max-sixty
Copy link
Contributor

Reading through the code, my hypothesis is this section is passing an empty ident as an alias.

https://github.com/rust-lang-nursery/rustfmt/blob/master/src/imports.rs#L352-L357

I'm not sure how to debug this though. Let me know if you have any guidance from here!

@nrc
Copy link
Member

nrc commented Aug 22, 2018

I would look at rewrite_ident - I think it might be formatting _ as ``. Probably insert some printlns to confirm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Panic, non-idempotency, invalid code, etc. good first issue Issues up for grabs, also good candidates for new rustfmt contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants