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

Hacky rustup #3905

Merged
merged 9 commits into from
Apr 1, 2019
Merged

Hacky rustup #3905

merged 9 commits into from
Apr 1, 2019

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Mar 26, 2019

This gets our tests back working, but we now are calling transmute in the compiletest code.

Also I couldn't quickly figure out some test failures and won't have time to get to them until thursday, if someone could take them over that would be great (maybe just merge this PR and open issues for all failures and start addressing them?)

should_panic: libtest::ShouldPanic::No,
},
// oli obk giving up
testfn: unsafe { std::mem::transmute(test.testfn) },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put up an issue about this, there's probably someone who already knows how to write it without transmute right? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think oli-obk meant opening issues only for broken tests, it's probably not possible to avoid transumte until libtest gets fixed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. It's just one line though, it doesn't seem that bad right?

@felix91gr
Copy link
Contributor

I'm trying to fix the test failures, but there's one that seems very suspicious.

This part in the identity_conversion lint appears to be broken:

ExprKind::Call(ref path, ref args) => {
    if let ExprKind::Path(ref qpath) = path.node {
        if let Some(def_id) = resolve_node(cx, qpath, path.hir_id).opt_def_id() {
            if match_def_path(cx.tcx, def_id, &paths::FROM_FROM[..]) {
                let a = cx.tables.expr_ty(e);
                let b = cx.tables.expr_ty(&args[0]);
                if same_tys(cx, a, b) {
                    let sugg = snippet(cx, args[0].span.source_callsite(), "<expr>").into_owned();
                    let sugg_msg =
                        format!("consider removing `{}()`", snippet(cx, path.span, "From::from"));
                    span_lint_and_then(cx, IDENTITY_CONVERSION, e.span, "identical conversion", |db| {
                        db.span_suggestion(
                            e.span,
                            &sugg_msg,
                            sugg,
                            Applicability::MachineApplicable, // snippet
                        );
                    });
                }
            }
        }
    }
},

Because dogfood fails with these two errors:

---- dogfood stdout ----
status: exit code: 101
stdout: 
stderr:     Checking clippy v0.0.212 (/home/felix/Documents/Programming/Rust/clippy_work/clean_clippy)
error: identical conversion
  --> tests/compile-test.rs:80:16
   |
80 |     for dir in fs::read_dir(&config.src_base)? {
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `fs::read_dir(&config.src_base)?()`: `fs::read_dir(&config.src_base)?`
   |
   = note: `-D clippy::identity-conversion` implied by `-D clippy::all`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#identity_conversion

error: identical conversion
  --> tests/compile-test.rs:83:21
   |
83 |         for file in fs::read_dir(&dir_path)? {
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `fs::read_dir(&dir_path)?()`: `fs::read_dir(&dir_path)?`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#identity_conversion

error: aborting due to 2 previous errors

The error is nonsensical. I think I can make a regression test for this. Anyone knows why the lint produces this error, though? I'll try to take a deeper look later in the day :)

@oli-obk
Copy link
Contributor Author

oli-obk commented Mar 26, 2019

That error should not actually be emitted. The macro checks seem to be failing. Either it needs a macro check, or rustc stopped emitting macro expansion information and we need to fix it in rustc.

@felix91gr
Copy link
Contributor

Oh no, that's bad. Do you know where should I report that error (specifically, what part of the rustc might be responsible for this? If not, who should I tell otherwise?

@felix91gr
Copy link
Contributor

PS: I added some fixes at #3906

@mati865
Copy link
Contributor

mati865 commented Mar 26, 2019

I don't have time to debug it further but Rust may be broken indeed.
I have added println!("expr: {:?}\nexpr_node: {:?}\n", expr, expr.node); in

here are the results:

Works:

pub fn main() {
    let _ = [1, 2, 3].into_iter();
}

debug:

expr: expr(HirId { owner: DefIndex(0:3), local_id: 11 }: { let _ = [1, 2, 3].into_iter(); })
expr_node: Block(Block { stmts: [stmt(HirId { owner: DefIndex(0:3), local_id: 9 }: let _ = [1, 2, 3].into_iter();)], expr: None, hir_id: HirId { owner: DefIndex(0:3), local_id: 10 }, rules: DefaultBlock, span: test.rs:3:15: 5:2, targeted_by_break: false }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 8 }: [1, 2, 3].into_iter())
expr_node: MethodCall(PathSegment { ident: into_iter#0, hir_id: Some(HirId { owner: DefIndex(0:3), local_id: 3 }), def: Some(Err), args: None, infer_types: true }, test.rs:4:23: 4:32, [expr(HirId { owner: DefIndex(0:3), local_id: 7 }: [1, 2, 3])])

error: this .into_iter() call is equivalent to .iter() and will not move the array
 --> test.rs:4:23
  |
4 |     let _ = [1, 2, 3].into_iter();
  |                       ^^^^^^^^^ help: call directly: `iter`
<removed irrelevant output>

Doesn't work:

pub fn main() {
    for _ in [1, 2, 3].into_iter() {}
}

debug:

expr: expr(HirId { owner: DefIndex(0:3), local_id: 43 }: {
    {
        let _result =
            match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter())
                {
                mut iter =>
                loop  {
                    let mut __next;
                    match ::std::iter::Iterator::next(&mut iter) {
                        ::std::option::Option::Some(val) => __next = val,
                        ::std::option::Option::None => break ,
                    }
                    let _ = __next;
                    { }
                },
            };
        _result
    }
})
expr_node: Block(Block { stmts: [], expr: Some(expr(HirId { owner: DefIndex(0:3), local_id: 41 }: {
    let _result =
        match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()) {
            mut iter =>
            loop  {
                let mut __next;
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(val) => __next = val,
                    ::std::option::Option::None => break ,
                }
                let _ = __next;
                { }
            },
        };
    _result
})), hir_id: HirId { owner: DefIndex(0:3), local_id: 42 }, rules: DefaultBlock, span: test.rs:3:15: 5:2, targeted_by_break: false }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 41 }: {
    let _result =
        match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()) {
            mut iter =>
            loop  {
                let mut __next;
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(val) => __next = val,
                    ::std::option::Option::None => break ,
                }
                let _ = __next;
                { }
            },
        };
    _result
})
expr_node: Block(Block { stmts: [stmt(HirId { owner: DefIndex(0:3), local_id: 38 }: let _result =
    match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()) {
        mut iter =>
        loop  {
            let mut __next;
            match ::std::iter::Iterator::next(&mut iter) {
                ::std::option::Option::Some(val) => __next = val,
                ::std::option::Option::None => break ,
            }
            let _ = __next;
            { }
        },
    };)], expr: Some(expr(HirId { owner: DefIndex(0:3), local_id: 39 }: _result)), hir_id: HirId { owner: DefIndex(0:3), local_id: 40 }, rules: DefaultBlock, span: test.rs:4:5: 4:38, targeted_by_break: false }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 35 }: match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()) {
    mut iter =>
    loop  {
        let mut __next;
        match ::std::iter::Iterator::next(&mut iter) {
            ::std::option::Option::Some(val) => __next = val,
            ::std::option::Option::None => break ,
        }
        let _ = __next;
        { }
    },
})
expr_node: Match(expr(HirId { owner: DefIndex(0:3), local_id: 34 }: ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter())), [Arm { attrs: [], pats: [pat(HirId { owner: DefIndex(0:3), local_id: 16 }: mut iter)], guard: None, body: expr(HirId { owner: DefIndex(0:3), local_id: 13 }: loop  {
    let mut __next;
    match ::std::iter::Iterator::next(&mut iter) {
        ::std::option::Option::Some(val) => __next = val,
        ::std::option::Option::None => break ,
    }
    let _ = __next;
    { }
}) }], ForLoopDesugar)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 34 }: ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()))
expr_node: Call(expr(HirId { owner: DefIndex(0:3), local_id: 33 }: ::std::iter::IntoIterator::into_iter), [expr(HirId { owner: DefIndex(0:3), local_id: 6 }: [1, 2, 3].into_iter())])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 33 }: ::std::iter::IntoIterator::into_iter)
expr_node: Path(Resolved(None, path(::std::iter::IntoIterator::into_iter)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 5 }: [1, 2, 3])
expr_node: Array([expr(HirId { owner: DefIndex(0:3), local_id: 2 }: 1), expr(HirId { owner: DefIndex(0:3), local_id: 3 }: 2), expr(HirId { owner: DefIndex(0:3), local_id: 4 }: 3)])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 2 }: 1)
expr_node: Lit(Spanned { node: Int(1, Unsuffixed), span: test.rs:4:15: 4:16 })

expr: expr(HirId { owner: DefIndex(0:3), local_id: 3 }: 2)
expr_node: Lit(Spanned { node: Int(2, Unsuffixed), span: test.rs:4:18: 4:19 })

expr: expr(HirId { owner: DefIndex(0:3), local_id: 4 }: 3)
expr_node: Lit(Spanned { node: Int(3, Unsuffixed), span: test.rs:4:21: 4:22 })

expr: expr(HirId { owner: DefIndex(0:3), local_id: 13 }: loop  {
    let mut __next;
    match ::std::iter::Iterator::next(&mut iter) {
        ::std::option::Option::Some(val) => __next = val,
        ::std::option::Option::None => break ,
    }
    let _ = __next;
    { }
})
expr_node: Loop(Block { stmts: [stmt(HirId { owner: DefIndex(0:3), local_id: 25 }: let mut __next;), stmt(HirId { owner: DefIndex(0:3), local_id: 22 }: match ::std::iter::Iterator::next(&mut iter) {
    ::std::option::Option::Some(val) => __next = val,
    ::std::option::Option::None => break ,
}), stmt(HirId { owner: DefIndex(0:3), local_id: 28 }: let _ = __next;), stmt(HirId { owner: DefIndex(0:3), local_id: 31 }: { })], expr: None, hir_id: HirId { owner: DefIndex(0:3), local_id: 32 }, rules: DefaultBlock, span: test.rs:4:5: 4:38, targeted_by_break: false }, None, ForLoop)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 21 }: match ::std::iter::Iterator::next(&mut iter) {
    ::std::option::Option::Some(val) => __next = val,
    ::std::option::Option::None => break ,
})
expr_node: Match(expr(HirId { owner: DefIndex(0:3), local_id: 20 }: ::std::iter::Iterator::next(&mut iter)), [Arm { attrs: [], pats: [pat(HirId { owner: DefIndex(0:3), local_id: 12 }: ::std::option::Option::Some(val))], guard: None, body: expr(HirId { owner: DefIndex(0:3), local_id: 11 }: __next = val) }, Arm { attrs: [], pats: [pat(HirId { owner: DefIndex(0:3), local_id: 15 }: ::std::option::Option::None)], guard: None, body: expr(HirId { owner: DefIndex(0:3), local_id: 14 }: break) }], ForLoopDesugar)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 20 }: ::std::iter::Iterator::next(&mut iter))
expr_node: Call(expr(HirId { owner: DefIndex(0:3), local_id: 19 }: ::std::iter::Iterator::next), [expr(HirId { owner: DefIndex(0:3), local_id: 18 }: &mut iter)])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 19 }: ::std::iter::Iterator::next)
expr_node: Path(Resolved(None, path(::std::iter::Iterator::next)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 18 }: &mut iter)
expr_node: AddrOf(MutMutable, expr(HirId { owner: DefIndex(0:3), local_id: 17 }: iter))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 17 }: iter)
expr_node: Path(Resolved(None, path(iter)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 11 }: __next = val)
expr_node: Assign(expr(HirId { owner: DefIndex(0:3), local_id: 10 }: __next), expr(HirId { owner: DefIndex(0:3), local_id: 9 }: val))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 9 }: val)
expr_node: Path(Resolved(None, path(val)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 10 }: __next)
expr_node: Path(Resolved(None, path(__next)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 14 }: break)
expr_node: Break(Destination { label: None, target_id: Ok(HirId { owner: DefIndex(0:3), local_id: 13 }) }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 23 }: __next)
expr_node: Path(Resolved(None, path(__next)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 30 }: { })
expr_node: Block(Block { stmts: [], expr: None, hir_id: HirId { owner: DefIndex(0:3), local_id: 29 }, rules: DefaultBlock, span: test.rs:4:36: 4:38, targeted_by_break: false }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 39 }: _result)
expr_node: Path(Resolved(None, path(_result)))

There is no MethodCall this time but there is:

expr: expr(HirId { owner: DefIndex(0:3), local_id: 34 }: ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()))
expr_node: Call(expr(HirId { owner: DefIndex(0:3), local_id: 33 }: ::std::iter::IntoIterator::into_iter), [expr(HirId { owner: DefIndex(0:3), local_id: 6 }: [1, 2, 3].into_iter())])

@flip1995
Copy link
Member

flip1995 commented Mar 27, 2019

Had a little bit of time for debugging the read_dir problem:
Minimum example:

use std::fs;
use std::path::Path;

fn main() -> Result<(), std::io::Error> {
    let path = Path::new(".");
    for _ in fs::read_dir(path)? {

    }

    Ok(())
}

-Zunpretty=hir:

#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
use std::fs;
use std::path::Path;

fn main() -> Result<(), std::io::Error> {
    let path = <Path>::new(".");
    {
        let _result = match ::std::iter::IntoIterator::into_iter(
            match ::std::ops::Try::into_result(fs::read_dir(path)) {
                ::std::result::Result::Err(err) =>
                #[allow(unreachable_code)]
                {
                    #[allow(unreachable_code)]
                    return ::std::ops::Try::from_error(::std::convert::From::from(err))
                }
                ::std::result::Result::Ok(val) =>
                #[allow(unreachable_code)]
                {
                    #[allow(unreachable_code)]
                    val
                }
            },
        ) {
            mut iter => loop {
                let mut __next;
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(val) => __next = val,
                    ::std::option::Option::None => break,
                }
                let _ = __next;
                {}
            },
        };
        _result
    }

    Ok(())
}

The problem is the line return ::std::ops::Try::from_error(::std::convert::From::from(err)). Have we always linted the hir expanded code like this? Or were there some changes to the LintPass Code in rustc?

@felix91gr
Copy link
Contributor

felix91gr commented Mar 28, 2019

Have we always linted the hir expanded code like this? Or were there some changes to the LintPass Code in rustc?

I have just tested the snippet with all the nightly toolchains from 03-13 to 03-28 and the output from all of them is the same. Maybe the error lies somewhere else in rustc?

The command I used for testing every version is this, lemme know if it's the right one:

rustup install nightly-2019-03-13;
rustup run nightly-2019-03-13 rustc -Zunpretty=hir test.rs

@felix91gr
Copy link
Contributor

Also, fwiw: with latest nightly (28-03), the errors are the same as they have been lately. But with current master toolchain, there are new build failures (seems to me that they are related to the ongoing hiridification process?):

error[E0308]: mismatched types
  --> clippy_lints/src/enum_glob_use.rs:44:57
   |
44 |             self.lint_item(cx, cx.tcx.hir().expect_item(item.id));
   |                                                         ^^^^^^^ expected struct `syntax::ast::NodeId`, found struct `rustc::hir::HirId`
   |
   = note: expected type `syntax::ast::NodeId`
              found type `rustc::hir::HirId`

error[E0308]: mismatched types
   --> clippy_lints/src/lifetimes.rs:359:92
    |
359 |                 if let ItemKind::Existential(ref exist_ty) = self.cx.tcx.hir().expect_item(item.id).node {
    |                                                                                            ^^^^^^^ expected struct `syntax::ast::NodeId`, found struct `rustc::hir::HirId`
    |
    = note: expected type `syntax::ast::NodeId`
               found type `rustc::hir::HirId`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `clippy_lints`.

To learn more, run the command again with --verbose.

@mati865
Copy link
Contributor

mati865 commented Mar 29, 2019

Beta will be released on April 11 but backlog here dangerously grows.

@felix91gr
Copy link
Contributor

felix91gr commented Mar 29, 2019

Yeah :c

I wonder if there's a way to add a CI command to rustc that tests for breakage in Clippy's test suite?

Like, sure, 1/4 of rustc's PRs might break Clippy's build stage (the HirIdification ones, for example). But that's already probably clear coming from the PR itself. But what if they don't break Clippy's build stage but do break Clippy's tests? Those PRs would probably be introducing a regression, right?

I feel like this error could've been detected in such a way. Well, if libtest didn't break Clippy beforehand it would.

@mati865
Copy link
Contributor

mati865 commented Mar 29, 2019

There is such test but it can detect only first breakage (it doesn't check exact errors but failure in build or tests).
CI doesn't fail on tools error because it's often fixed within 2-3 days and it'd be hard to land important changes.

@Manishearth
Copy link
Member

I wonder if there's a way to add a CI command to rustc that tests for breakage in Clippy's test suite?

This already happens, we get notified.

The current status is due to libtest being broken in a way we can't move forward with. We are blocked on @gnzlbg and @alexcrichton resolving the issues.

@felix91gr
Copy link
Contributor

felix91gr commented Mar 29, 2019

@mati865, I tested your snippet:

pub fn main() {
    for _ in [1, 2, 3].into_iter() {}
}

Using the command rustup run nightly-<date> rustc -Zunpretty=hir-tree test.rs and the output changed between 2019-03-23 and 2019-03-24. However, the only change was this:

$ diff test_tree_23.txt test2_tree_24.txt 
159d158
<     trait_auto_impl: {},

I tested it as far back as 2019-03-15 and there were no changes in the hir tree from there until 2019-03-24.

Here's the full output for 2019-03-23:

Crate {
    module: Mod {
        inner: test2.rs:1:1: 3:2,
        item_ids: [
            ItemId {
                id: NodeId(3)
            },
            ItemId {
                id: NodeId(9)
            },
            ItemId {
                id: NodeId(10)
            }
        ]
    },
    attrs: [],
    span: test2.rs:1:1: 3:2,
    exported_macros: [],
    items: {
        NodeId(3): Item {
            ident: #0,
            hir_id: HirId {
                owner: DefIndex(0:1),
                local_id: 0
            },
            attrs: [
                Attribute {
                    id: AttrId(
                        1
                    ),
                    style: Outer,
                    path: path(prelude_import),
                    tokens: TokenStream(
                        None
                    ),
                    is_sugared_doc: false,
                    span: test2.rs:1:1: 1:1
                }
            ],
            node: Use(
                path(::std::prelude::v1),
                Glob
            ),
            vis: Spanned {
                node: Inherited,
                span: test2.rs:1:1: 1:1
            },
            span: test2.rs:1:1: 1:1
        },
        NodeId(9): Item {
            ident: std#0,
            hir_id: HirId {
                owner: DefIndex(0:2),
                local_id: 0
            },
            attrs: [
                Attribute {
                    id: AttrId(
                        0
                    ),
                    style: Outer,
                    path: path(macro_use),
                    tokens: TokenStream(
                        None
                    ),
                    is_sugared_doc: false,
                    span: test2.rs:1:1: 1:1
                }
            ],
            node: ExternCrate(
                None
            ),
            vis: Spanned {
                node: Inherited,
                span: test2.rs:1:1: 1:1
            },
            span: test2.rs:1:1: 1:1
        },
        NodeId(10): Item {
            ident: main#0,
            hir_id: HirId {
                owner: DefIndex(0:3),
                local_id: 0
            },
            attrs: [],
            node: Fn(
                FnDecl {
                    inputs: [],
                    output: DefaultReturn(
                        test2.rs:1:15: 1:15
                    ),
                    c_variadic: false,
                    implicit_self: None
                },
                FnHeader {
                    unsafety: Normal,
                    constness: NotConst,
                    asyncness: NotAsync,
                    abi: Rust
                },
                Generics {
                    params: [],
                    where_clause: WhereClause {
                        hir_id: HirId {
                            owner: DefIndex(0:3),
                            local_id: 44
                        },
                        predicates: []
                    },
                    span: test2.rs:1:1: 1:1
                },
                BodyId {
                    hir_id: HirId {
                        owner: DefIndex(0:3),
                        local_id: 43
                    }
                }
            ),
            vis: Spanned {
                node: Public,
                span: test2.rs:1:1: 1:4
            },
            span: test2.rs:1:1: 3:2
        }
    },
    trait_items: {},
    impl_items: {},
    bodies: {
        BodyId {
            hir_id: HirId {
                owner: DefIndex(0:3),
                local_id: 43
            }
        }: Body {
            arguments: [],
            value: expr(HirId { owner: DefIndex(0:3), local_id: 43 }: {
                {
                    let _result =
                        match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter())
                            {
                            mut iter =>
                            loop  {
                                let mut __next;
                                match ::std::iter::Iterator::next(&mut iter) {
                                    ::std::option::Option::Some(val) => __next = val,
                                    ::std::option::Option::None => break ,
                                }
                                let _ = __next;
                                { }
                            },
                        };
                    _result
                }
            }),
            is_generator: false
        }
    },
    trait_impls: {},
    trait_auto_impl: {},
    body_ids: [
        BodyId {
            hir_id: HirId {
                owner: DefIndex(0:3),
                local_id: 43
            }
        }
    ],
    modules: {
        NodeId(0): ModuleItems {
            items: {
                NodeId(3),
                NodeId(9),
                NodeId(10)
            },
            trait_items: {},
            impl_items: {}
        }
    }
}

And here it is for 2019-03-24:

Crate {
    module: Mod {
        inner: test2.rs:1:1: 3:2,
        item_ids: [
            ItemId {
                id: NodeId(3)
            },
            ItemId {
                id: NodeId(9)
            },
            ItemId {
                id: NodeId(10)
            }
        ]
    },
    attrs: [],
    span: test2.rs:1:1: 3:2,
    exported_macros: [],
    items: {
        NodeId(3): Item {
            ident: #0,
            hir_id: HirId {
                owner: DefIndex(0:1),
                local_id: 0
            },
            attrs: [
                Attribute {
                    id: AttrId(
                        1
                    ),
                    style: Outer,
                    path: path(prelude_import),
                    tokens: TokenStream(
                        None
                    ),
                    is_sugared_doc: false,
                    span: test2.rs:1:1: 1:1
                }
            ],
            node: Use(
                path(::std::prelude::v1),
                Glob
            ),
            vis: Spanned {
                node: Inherited,
                span: test2.rs:1:1: 1:1
            },
            span: test2.rs:1:1: 1:1
        },
        NodeId(9): Item {
            ident: std#0,
            hir_id: HirId {
                owner: DefIndex(0:2),
                local_id: 0
            },
            attrs: [
                Attribute {
                    id: AttrId(
                        0
                    ),
                    style: Outer,
                    path: path(macro_use),
                    tokens: TokenStream(
                        None
                    ),
                    is_sugared_doc: false,
                    span: test2.rs:1:1: 1:1
                }
            ],
            node: ExternCrate(
                None
            ),
            vis: Spanned {
                node: Inherited,
                span: test2.rs:1:1: 1:1
            },
            span: test2.rs:1:1: 1:1
        },
        NodeId(10): Item {
            ident: main#0,
            hir_id: HirId {
                owner: DefIndex(0:3),
                local_id: 0
            },
            attrs: [],
            node: Fn(
                FnDecl {
                    inputs: [],
                    output: DefaultReturn(
                        test2.rs:1:15: 1:15
                    ),
                    c_variadic: false,
                    implicit_self: None
                },
                FnHeader {
                    unsafety: Normal,
                    constness: NotConst,
                    asyncness: NotAsync,
                    abi: Rust
                },
                Generics {
                    params: [],
                    where_clause: WhereClause {
                        hir_id: HirId {
                            owner: DefIndex(0:3),
                            local_id: 44
                        },
                        predicates: []
                    },
                    span: test2.rs:1:1: 1:1
                },
                BodyId {
                    hir_id: HirId {
                        owner: DefIndex(0:3),
                        local_id: 43
                    }
                }
            ),
            vis: Spanned {
                node: Public,
                span: test2.rs:1:1: 1:4
            },
            span: test2.rs:1:1: 3:2
        }
    },
    trait_items: {},
    impl_items: {},
    bodies: {
        BodyId {
            hir_id: HirId {
                owner: DefIndex(0:3),
                local_id: 43
            }
        }: Body {
            arguments: [],
            value: expr(HirId { owner: DefIndex(0:3), local_id: 43 }: {
                {
                    let _result =
                        match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter())
                            {
                            mut iter =>
                            loop  {
                                let mut __next;
                                match ::std::iter::Iterator::next(&mut iter) {
                                    ::std::option::Option::Some(val) => __next = val,
                                    ::std::option::Option::None => break ,
                                }
                                let _ = __next;
                                { }
                            },
                        };
                    _result
                }
            }),
            is_generator: false
        }
    },
    trait_impls: {},
    body_ids: [
        BodyId {
            hir_id: HirId {
                owner: DefIndex(0:3),
                local_id: 43
            }
        }
    ],
    modules: {
        NodeId(0): ModuleItems {
            items: {
                NodeId(3),
                NodeId(9),
                NodeId(10)
            },
            trait_items: {},
            impl_items: {}
        }
    }
}

Did I use the wrong command? Or maybe this means that the regression is somewhere else? 🤔

@felix91gr
Copy link
Contributor

Added some changes at #3908 so that Clippy builds again. The weird linting error is still there, however u.u

@flip1995
Copy link
Member

Things left to do to unbreak Clippy:

  • fix read_dir()? problem
  • fix into_iter() in for-loop problem
  • fix suggestions on explicit_iter_loop

@flip1995
Copy link
Member

flip1995 commented Mar 29, 2019

My thoughts about the into_iter problem:

  • Maybe something in the lowering phase was changed, so that <array>.into_iter() is lowered to ::into_iter(<array>), but printed with the original span.
  • Or maybe somthing in the visiting of HIR nodes changed and the MethodCall gets skipped, which I think is unlikely.
  • Or maybe something in the methods module deals with the MethodCall (and returns?) and that's why the debug output from @mati865 doesn't show the MethodCall.
    Yep that's it, in_macro(expr.span) returns true for the MethodCall expression.

My thoughts on explicit_iter_loop:

  • We had that problem some time before in a pull request, where the suggestion somehow just wouldn't get printed. We couldn't resolve this issue back then and just left out the suggestion. But now that this happened again, it may be worth to look into this.
  • I wouldn't let this block this PR

My thoughts on the read_dir()? problem:

  • there's no diff in the -Zunpretty=hir of the nightly-2019-03-15 and master toolchain for the minimum example.

EDIT: I won't have time to look into this more today, if someone wants to pick this up.

@felix91gr
Copy link
Contributor

felix91gr commented Mar 29, 2019

More info on the current state: I've just tested adding #[warn(clippy::identity_conversion)] (to override the lint giving an error) right above the triggering function:

fn run_ui_toml_tests(config: &compiletest::Config, mut tests: Vec<TestDescAndFn>) -> Result<bool, io::Error> {

After that change, all remaining tests pass. So, it seems we're not so far from unbreaking Clippy.


Yep that's it, in_macro(expr.span) returns true for the MethodCall expression.

That's awesome. I'll try to look more into it later today, I'm not sure if I can fix it but I'll try.

Edit: what module is that you were talking about? I want to give it a look :)

@flip1995
Copy link
Member

flip1995 commented Mar 29, 2019

So, it seems we're not so far from unbreaking Clippy.

Note that there are 2 updated *.stderr files, which shouldn't be updated, because nothing should have changed there.

#[warn...

do you mean allow?

what module is that you were talking about?

if in_macro(expr.span) {
return;
}

If you put the debugging println! expression @mati865 posted here #3905 (comment), in front of the if statement, it will print out the into_iter MethodCall. Behind the if statement the MethodCall won't be printed.
My guess is, that something changed how expn_info is generated in rustc. But that's just a really wild guess.

@felix91gr
Copy link
Contributor

felix91gr commented Mar 29, 2019

do you mean allow?

allow was my first attempt, but I prefer warn so that the error is still there ringing for someone to pick it up. Should it be just allow?

If you put the debugging println! expression @mati865 posted here...

Ah! I thought it was a module on rustc, that's why I couldn't find it. Okay, I'll run some tests, maybe I can find the regression from there :D

@flip1995
Copy link
Member

flip1995 commented Mar 29, 2019

I think the dogfood tests are run with the -Dwarnings flag, so it would be turned into an error if it was warn. Otherwise warn would be better.

@felix91gr
Copy link
Contributor

Yeah, it works alright with warn :) I've tested it again to make sure.

@felix91gr
Copy link
Contributor

felix91gr commented Mar 29, 2019

Okay I tested @mati865's print, together with @flip1995's suggestion of writing the print before the if in_macro(expr.span) line, with two versions of Clippy and rustc:

  1. Clippy's commit c7d4445, the last to have a passing build in CI, together with rustc's nightly toolchain at 2019-03-19, which is the day of that passing build.
  2. Clippy's current version of the compiletest branch with rustc's master toolchain at the time of writing. Had to add a couple of hirid-fication lines to Clippy and had to update the lint registering call again because of API changes in rustc, but apart from that everything was the same as what we have in the repo.

The tested files had just the two snippets written by @mati865:

pub fn main() {
    for _ in [1, 2, 3].into_iter() {}
}
pub fn main() {
    let _ = [1, 2, 3].into_iter();
}

Their stdout was filtered from Clippy's test output and the result was this:

Both files' generated stdout do not change between the different versions of Clippy and rustc.

These are the results for each file:

First file's:

expr: expr(HirId { owner: DefIndex(0:3), local_id: 43 }: {
    {
        let _result =
            match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter())
                {
                mut iter =>
                loop  {
                    let mut __next;
                    match ::std::iter::Iterator::next(&mut iter) {
                        ::std::option::Option::Some(val) => __next = val,
                        ::std::option::Option::None => break ,
                    }
                    let _ = __next;
                    { }
                },
            };
        _result
    }
})
expr_node: Block(Block { stmts: [], expr: Some(expr(HirId { owner: DefIndex(0:3), local_id: 41 }: {
    let _result =
        match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()) {
            mut iter =>
            loop  {
                let mut __next;
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(val) => __next = val,
                    ::std::option::Option::None => break ,
                }
                let _ = __next;
                { }
            },
        };
    _result
})), hir_id: HirId { owner: DefIndex(0:3), local_id: 42 }, rules: DefaultBlock, span: tests/ui/reg_test.rs:1:15: 3:2, targeted_by_break: false }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 41 }: {
    let _result =
        match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()) {
            mut iter =>
            loop  {
                let mut __next;
                match ::std::iter::Iterator::next(&mut iter) {
                    ::std::option::Option::Some(val) => __next = val,
                    ::std::option::Option::None => break ,
                }
                let _ = __next;
                { }
            },
        };
    _result
})
expr_node: Block(Block { stmts: [stmt(HirId { owner: DefIndex(0:3), local_id: 38 }: let _result =
    match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()) {
        mut iter =>
        loop  {
            let mut __next;
            match ::std::iter::Iterator::next(&mut iter) {
                ::std::option::Option::Some(val) => __next = val,
                ::std::option::Option::None => break ,
            }
            let _ = __next;
            { }
        },
    };)], expr: Some(expr(HirId { owner: DefIndex(0:3), local_id: 39 }: _result)), hir_id: HirId { owner: DefIndex(0:3), local_id: 40 }, rules: DefaultBlock, span: tests/ui/reg_test.rs:2:5: 2:38, targeted_by_break: false }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 35 }: match ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()) {
    mut iter =>
    loop  {
        let mut __next;
        match ::std::iter::Iterator::next(&mut iter) {
            ::std::option::Option::Some(val) => __next = val,
            ::std::option::Option::None => break ,
        }
        let _ = __next;
        { }
    },
})
expr_node: Match(expr(HirId { owner: DefIndex(0:3), local_id: 34 }: ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter())), [Arm { attrs: [], pats: [pat(HirId { owner: DefIndex(0:3), local_id: 16 }: mut iter)], guard: None, body: expr(HirId { owner: DefIndex(0:3), local_id: 13 }: loop  {
    let mut __next;
    match ::std::iter::Iterator::next(&mut iter) {
        ::std::option::Option::Some(val) => __next = val,
        ::std::option::Option::None => break ,
    }
    let _ = __next;
    { }
}) }], ForLoopDesugar)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 34 }: ::std::iter::IntoIterator::into_iter([1, 2, 3].into_iter()))
expr_node: Call(expr(HirId { owner: DefIndex(0:3), local_id: 33 }: ::std::iter::IntoIterator::into_iter), [expr(HirId { owner: DefIndex(0:3), local_id: 6 }: [1, 2, 3].into_iter())])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 33 }: ::std::iter::IntoIterator::into_iter)
expr_node: Path(Resolved(None, path(::std::iter::IntoIterator::into_iter)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 6 }: [1, 2, 3].into_iter())
expr_node: MethodCall(PathSegment { ident: into_iter#0, hir_id: Some(HirId { owner: DefIndex(0:3), local_id: 1 }), def: Some(Err), args: None, infer_types: true }, tests/ui/reg_test.rs:2:24: 2:33, [expr(HirId { owner: DefIndex(0:3), local_id: 5 }: [1, 2, 3])])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 5 }: [1, 2, 3])
expr_node: Array([expr(HirId { owner: DefIndex(0:3), local_id: 2 }: 1), expr(HirId { owner: DefIndex(0:3), local_id: 3 }: 2), expr(HirId { owner: DefIndex(0:3), local_id: 4 }: 3)])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 2 }: 1)
expr_node: Lit(Spanned { node: Int(1, Unsuffixed), span: tests/ui/reg_test.rs:2:15: 2:16 })

expr: expr(HirId { owner: DefIndex(0:3), local_id: 3 }: 2)
expr_node: Lit(Spanned { node: Int(2, Unsuffixed), span: tests/ui/reg_test.rs:2:18: 2:19 })

expr: expr(HirId { owner: DefIndex(0:3), local_id: 4 }: 3)
expr_node: Lit(Spanned { node: Int(3, Unsuffixed), span: tests/ui/reg_test.rs:2:21: 2:22 })

expr: expr(HirId { owner: DefIndex(0:3), local_id: 13 }: loop  {
    let mut __next;
    match ::std::iter::Iterator::next(&mut iter) {
        ::std::option::Option::Some(val) => __next = val,
        ::std::option::Option::None => break ,
    }
    let _ = __next;
    { }
})
expr_node: Loop(Block { stmts: [stmt(HirId { owner: DefIndex(0:3), local_id: 25 }: let mut __next;), stmt(HirId { owner: DefIndex(0:3), local_id: 22 }: match ::std::iter::Iterator::next(&mut iter) {
    ::std::option::Option::Some(val) => __next = val,
    ::std::option::Option::None => break ,
}), stmt(HirId { owner: DefIndex(0:3), local_id: 28 }: let _ = __next;), stmt(HirId { owner: DefIndex(0:3), local_id: 31 }: { })], expr: None, hir_id: HirId { owner: DefIndex(0:3), local_id: 32 }, rules: DefaultBlock, span: tests/ui/reg_test.rs:2:5: 2:38, targeted_by_break: false }, None, ForLoop)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 21 }: match ::std::iter::Iterator::next(&mut iter) {
    ::std::option::Option::Some(val) => __next = val,
    ::std::option::Option::None => break ,
})
expr_node: Match(expr(HirId { owner: DefIndex(0:3), local_id: 20 }: ::std::iter::Iterator::next(&mut iter)), [Arm { attrs: [], pats: [pat(HirId { owner: DefIndex(0:3), local_id: 12 }: ::std::option::Option::Some(val))], guard: None, body: expr(HirId { owner: DefIndex(0:3), local_id: 11 }: __next = val) }, Arm { attrs: [], pats: [pat(HirId { owner: DefIndex(0:3), local_id: 15 }: ::std::option::Option::None)], guard: None, body: expr(HirId { owner: DefIndex(0:3), local_id: 14 }: break) }], ForLoopDesugar)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 20 }: ::std::iter::Iterator::next(&mut iter))
expr_node: Call(expr(HirId { owner: DefIndex(0:3), local_id: 19 }: ::std::iter::Iterator::next), [expr(HirId { owner: DefIndex(0:3), local_id: 18 }: &mut iter)])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 19 }: ::std::iter::Iterator::next)
expr_node: Path(Resolved(None, path(::std::iter::Iterator::next)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 18 }: &mut iter)
expr_node: AddrOf(MutMutable, expr(HirId { owner: DefIndex(0:3), local_id: 17 }: iter))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 17 }: iter)
expr_node: Path(Resolved(None, path(iter)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 11 }: __next = val)
expr_node: Assign(expr(HirId { owner: DefIndex(0:3), local_id: 10 }: __next), expr(HirId { owner: DefIndex(0:3), local_id: 9 }: val))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 9 }: val)
expr_node: Path(Resolved(None, path(val)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 10 }: __next)
expr_node: Path(Resolved(None, path(__next)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 14 }: break)
expr_node: Break(Destination { label: None, target_id: Ok(HirId { owner: DefIndex(0:3), local_id: 13 }) }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 23 }: __next)
expr_node: Path(Resolved(None, path(__next)))

expr: expr(HirId { owner: DefIndex(0:3), local_id: 30 }: { })
expr_node: Block(Block { stmts: [], expr: None, hir_id: HirId { owner: DefIndex(0:3), local_id: 29 }, rules: DefaultBlock, span: tests/ui/reg_test.rs:2:36: 2:38, targeted_by_break: false }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 39 }: _result)
expr_node: Path(Resolved(None, path(_result)))

Second file's:

expr: expr(HirId { owner: DefIndex(0:3), local_id: 11 }: { let _ = [1, 2, 3].into_iter(); })
expr_node: Block(Block { stmts: [stmt(HirId { owner: DefIndex(0:3), local_id: 9 }: let _ = [1, 2, 3].into_iter();)], expr: None, hir_id: HirId { owner: DefIndex(0:3), local_id: 10 }, rules: DefaultBlock, span: tests/ui/reg_testno.rs:1:15: 3:2, targeted_by_break: false }, None)

expr: expr(HirId { owner: DefIndex(0:3), local_id: 8 }: [1, 2, 3].into_iter())
expr_node: MethodCall(PathSegment { ident: into_iter#0, hir_id: Some(HirId { owner: DefIndex(0:3), local_id: 3 }), def: Some(Err), args: None, infer_types: true }, tests/ui/reg_testno.rs:2:23: 2:32, [expr(HirId { owner: DefIndex(0:3), local_id: 7 }: [1, 2, 3])])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 7 }: [1, 2, 3])
expr_node: Array([expr(HirId { owner: DefIndex(0:3), local_id: 4 }: 1), expr(HirId { owner: DefIndex(0:3), local_id: 5 }: 2), expr(HirId { owner: DefIndex(0:3), local_id: 6 }: 3)])

expr: expr(HirId { owner: DefIndex(0:3), local_id: 4 }: 1)
expr_node: Lit(Spanned { node: Int(1, Unsuffixed), span: tests/ui/reg_testno.rs:2:14: 2:15 })

expr: expr(HirId { owner: DefIndex(0:3), local_id: 5 }: 2)
expr_node: Lit(Spanned { node: Int(2, Unsuffixed), span: tests/ui/reg_testno.rs:2:17: 2:18 })

expr: expr(HirId { owner: DefIndex(0:3), local_id: 6 }: 3)
expr_node: Lit(Spanned { node: Int(3, Unsuffixed), span: tests/ui/reg_testno.rs:2:20: 2:21 })

@flip1995
Copy link
Member

flip1995 commented Apr 1, 2019

I would suggest to merge this this evening (with the warn attributes on read_dir()?), even if there are no fixes for the remaining issues #3905 (comment).

Then we should open high priority issues to fix those. But 3 known bugs in Clippy is better than no Clippy in the nightlies IMHO.

@Manishearth
Copy link
Member

I agree, and we've merged rustups with test failures in the past.

@Manishearth
Copy link
Member

Though, to be clear, for rustc to accept this clippy will have to appear to pass tests, i.e. we'll have to temporarily delete the test.

@flip1995
Copy link
Member

flip1995 commented Apr 1, 2019

we'll have to temporarily delete the test

I would just use the wrongly updated *.stderr files from this PR instead of deleting them completely. Then it also appears as if the tests pass.

@Manishearth
Copy link
Member

Oh, sorry, that's basically what I meant. "Removing the test".

@mati865
Copy link
Contributor

mati865 commented Apr 1, 2019

Or use 2nd option from rust-lang/rust#59396 (comment)

@flip1995
Copy link
Member

flip1995 commented Apr 1, 2019

@bors try

Appveyor will fail, but let's see if this introduced ICEs in some crates.

bors added a commit that referenced this pull request Apr 1, 2019
Hacky rustup

This gets our tests back working, but we now are calling `transmute` in the compiletest code.

Also I couldn't quickly figure out some test failures and won't have time to get to them until thursday, if someone could take them over that would be great (maybe just merge this PR and open issues for all failures and start addressing them?)
@bors
Copy link
Contributor

bors commented Apr 1, 2019

⌛ Trying commit 4192779 with merge 027a659...

@bors
Copy link
Contributor

bors commented Apr 1, 2019

💔 Test failed - status-appveyor

@flip1995
Copy link
Member

flip1995 commented Apr 1, 2019

Travis is green, no ICEs introduced by this. Let's merge this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants