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

When moving out of a for loop head, suggest borrowing it #59195

Merged
merged 2 commits into from Mar 25, 2019

Conversation

Projects
None yet
5 participants
@estebank
Copy link
Contributor

commented Mar 14, 2019

When encountering code like the following, suggest borrowing the for loop
head to avoid moving it into the for loop pattern:

fn main() {
    let a = vec![1, 2, 3];
    for i in &a {
        for j in a {
            println!("{} * {} = {}", i, j, i * j);
        }
    }
}

Fix #25534.

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

commented Mar 14, 2019

r? @petrochenkov

(rust_highfive has picked a reviewer for you, use r? to override)

@@ -746,6 +747,19 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
},
moved_lp.ty));
}
if let (Some(CompilerDesugaringKind::ForLoop), Ok(snippet)) = (

This comment has been minimized.

Copy link
@estebank

estebank Mar 14, 2019

Author Contributor

We might want to use a separate CompilerDesugaringKind variant to differentiate in errors, something along the lines of ForLoopHead, or something, or modify ForLoop to carry information on wether the source is completely synthetic or just moving around code that the user has written.

@@ -746,6 +747,19 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
},
moved_lp.ty));
}
if let (Some(CompilerDesugaringKind::ForLoop), Ok(snippet)) = (
move_span.compiler_desugaring_kind(),
self.tcx.sess.source_map().span_to_snippet(move_span),

This comment has been minimized.

Copy link
@petrochenkov

petrochenkov Mar 15, 2019

Contributor

Nit: not sure whether span_to_snippet is expensive or not, but if it is, them it may make sense to nest if lets to avoid pessimizing.

@petrochenkov

This comment has been minimized.

Copy link
Contributor

commented Mar 15, 2019

@bors r+

@bors

This comment has been minimized.

Copy link
Contributor

commented Mar 15, 2019

📌 Commit d189e6d has been approved by petrochenkov

bors added a commit that referenced this pull request Mar 17, 2019

Auto merge of #59244 - Centril:rollup, r=Centril
Rollup of 9 pull requests

Successful merges:

 - #57729 (extra testing of how NLL handles wildcard type `_`)
 - #58995 (Refactor tools/build-mainfest)
 - #59035 (When encountetring `||{}()`, suggest the likely intended `(||{})()`)
 - #59038 (Track embedded-book in the toolstate)
 - #59047 (resolve: Account for new importable entities)
 - #59068 (HirIdification: kill off NodeId stragglers)
 - #59096 (middle: replace NodeId with HirId in AccessLevels)
 - #59106 (Add peer_addr function to UdpSocket)
 - #59116 (Be more discerning on when to attempt suggesting a comma in a macro invocation)

Failed merges:

 - #59195 (When moving out of a for loop head, suggest borrowing it)

r? @ghost

bors added a commit that referenced this pull request Mar 17, 2019

Auto merge of #59244 - Centril:rollup, r=Centril
Rollup of 9 pull requests

Successful merges:

 - #57729 (extra testing of how NLL handles wildcard type `_`)
 - #58995 (Refactor tools/build-mainfest)
 - #59035 (When encountetring `||{}()`, suggest the likely intended `(||{})()`)
 - #59038 (Track embedded-book in the toolstate)
 - #59047 (resolve: Account for new importable entities)
 - #59068 (HirIdification: kill off NodeId stragglers)
 - #59096 (middle: replace NodeId with HirId in AccessLevels)
 - #59106 (Add peer_addr function to UdpSocket)
 - #59116 (Be more discerning on when to attempt suggesting a comma in a macro invocation)

Failed merges:

 - #59195 (When moving out of a for loop head, suggest borrowing it)

r? @ghost

bors added a commit that referenced this pull request Mar 17, 2019

Auto merge of #59244 - Centril:rollup, r=Centril
Rollup of 9 pull requests

Successful merges:

 - #57729 (extra testing of how NLL handles wildcard type `_`)
 - #58995 (Refactor tools/build-mainfest)
 - #59035 (When encountetring `||{}()`, suggest the likely intended `(||{})()`)
 - #59038 (Track embedded-book in the toolstate)
 - #59047 (resolve: Account for new importable entities)
 - #59068 (HirIdification: kill off NodeId stragglers)
 - #59096 (middle: replace NodeId with HirId in AccessLevels)
 - #59106 (Add peer_addr function to UdpSocket)
 - #59116 (Be more discerning on when to attempt suggesting a comma in a macro invocation)

Failed merges:

 - #59195 (When moving out of a for loop head, suggest borrowing it)

r? @ghost

bors added a commit that referenced this pull request Mar 17, 2019

Auto merge of #59244 - Centril:rollup, r=Centril
Rollup of 9 pull requests

Successful merges:

 - #57729 (extra testing of how NLL handles wildcard type `_`)
 - #58995 (Refactor tools/build-mainfest)
 - #59035 (When encountetring `||{}()`, suggest the likely intended `(||{})()`)
 - #59038 (Track embedded-book in the toolstate)
 - #59047 (resolve: Account for new importable entities)
 - #59068 (HirIdification: kill off NodeId stragglers)
 - #59096 (middle: replace NodeId with HirId in AccessLevels)
 - #59106 (Add peer_addr function to UdpSocket)
 - #59116 (Be more discerning on when to attempt suggesting a comma in a macro invocation)

Failed merges:

 - #59195 (When moving out of a for loop head, suggest borrowing it)

r? @ghost

Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Mar 23, 2019

Rollup merge of rust-lang#59195 - estebank:for-loop-move, r=petrochenkov
When moving out of a for loop head, suggest borrowing it

When encountering code like the following, suggest borrowing the for loop
head to avoid moving it into the for loop pattern:

```
fn main() {
    let a = vec![1, 2, 3];
    for i in &a {
        for j in a {
            println!("{} * {} = {}", i, j, i * j);
        }
    }
}
```

Fix rust-lang#25534.
@bors

This comment was marked as resolved.

Copy link
Contributor

commented Mar 23, 2019

☔️ The latest upstream changes (presumably #59068) made this pull request unmergeable. Please resolve the merge conflicts.

@estebank estebank force-pushed the estebank:for-loop-move branch from d189e6d to 6efdfbd Mar 23, 2019

@estebank

This comment has been minimized.

Copy link
Contributor Author

commented Mar 23, 2019

@bors r=petrochenkov

@bors

This comment has been minimized.

Copy link
Contributor

commented Mar 23, 2019

📌 Commit 6efdfbd has been approved by petrochenkov

@bors

This comment has been minimized.

Copy link
Contributor

commented Mar 24, 2019

⌛️ Testing commit 6efdfbd with merge e65450e...

bors added a commit that referenced this pull request Mar 24, 2019

Auto merge of #59195 - estebank:for-loop-move, r=petrochenkov
When moving out of a for loop head, suggest borrowing it

When encountering code like the following, suggest borrowing the for loop
head to avoid moving it into the for loop pattern:

```
fn main() {
    let a = vec![1, 2, 3];
    for i in &a {
        for j in a {
            println!("{} * {} = {}", i, j, i * j);
        }
    }
}
```

Fix #25534.
@bors

This comment has been minimized.

Copy link
Contributor

commented Mar 24, 2019

💔 Test failed - checks-travis

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

commented Mar 24, 2019

The job x86_64-gnu-nopt of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[01:40:36] +    |              --
[01:40:36] +    |              |
[01:40:36] +    |              borrow of `a` occurs here
[01:40:36] +    |              borrow later used here
[01:40:36] 6 LL |         for j in a {
[01:40:36] 7    |                  ^ move out of `a` occurs here
[01:40:36] 
[01:40:36] 9 error[E0382]: use of moved value: `a`
[01:40:36] 10   --> $DIR/borrow-for-loop-head.rs:4:18
[01:40:36] 11    |
[01:40:36] 11    |
[01:40:36] + LL |     let a = vec![1, 2, 3];
[01:40:36] +    |         - move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
[01:40:36] + LL |     for i in &a {
[01:40:36] 12 LL |         for j in a {
[01:40:36] -    |                  ^ value moved here in previous iteration of loop
[01:40:36] -    |
[01:40:36] -    = note: move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
[01:40:36] - help: consider borrowing this to avoid moving it into the for loop
[01:40:36] -    |
[01:40:36] - LL |         for j in &a {
[01:40:36] -    |                  ^^
[01:40:36] +    |                  ^ value moved here, in previous iteration of loop
[01:40:36] 21 error: aborting due to 2 previous errors
[01:40:36] 22 
[01:40:36] 
[01:40:36] 
[01:40:36] 
[01:40:36] The actual stderr differed from the expected stderr.
[01:40:36] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/suggestions/borrow-for-loop-head.nll/borrow-for-loop-head.nll.stderr
[01:40:36] To update references, rerun the tests and pass the `--bless` flag
[01:40:36] To only update this specific test, also pass `--test-args suggestions/borrow-for-loop-head.rs`
[01:40:36] error: 1 errors occurred comparing output.
[01:40:36] status: exit code: 1
[01:40:36] status: exit code: 1
[01:40:36] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/suggestions/borrow-for-loop-head.nll/a" "-Zborrowck=migrate" "-Ztwo-phase-borrows" "-Crpath" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/suggestions/borrow-for-loop-head.nll/auxiliary" "-A" "unused"
[01:40:36] ------------------------------------------
[01:40:36] 
[01:40:36] ------------------------------------------
[01:40:36] stderr:
[01:40:36] stderr:
[01:40:36] ------------------------------------------
[01:40:36] {"message":"cannot move out of `a` because it is borrowed","code":{"code":"E0505","explanation":"\nA value was moved out while it was still borrowed.\n\nErroneous code example:\n\n```compile_fail,E0505\nstruct Value {}\n\nfn borrow(val: &Value) {}\n\nfn eat(val: Value) {}\n\nfn main() {\n    let x = Value{};\n    let _ref_to_val: &Value = &x;\n    eat(x);\n    borrow(_ref_to_val);\n}\n```\n\nHere, the function `eat` takes ownership of `x`. However,\n`x` cannot be moved because the borrow to `_ref_to_val`\nneeds to last till the function `borrow`.\nTo fix that you can do a few different things:\n\n* Try to avoid moving the variable.\n* Release borrow before move.\n* Implement the `Copy` trait on the type.\n\nExamples:\n\n```\nstruct Value {}\n\nfn borrow(val: &Value) {}\n\nfn eat(val: &Value) {}\n\nfn main() {\n    let x = Value{};\n    let _ref_to_val: &Value = &x;\n    eat(&x); // pass by reference, if it's possible\n    borrow(_ref_to_val);\n}\n```\n\nOr:\n\n```\nstruct Value {}\n\nfn borrow(val: &Value) {}\n\nfn eat(val: Value) {}\n\nfn main() {\n    let x = Value{};\n    {\n        let _ref_to_val: &Value = &x;\n        borrow(_ref_to_val);\n    }\n    eat(x); // release borrow and then move it.\n}\n```\n\nOr:\n\n```\n#[derive(Clone, Copy)] // implement Copy trait\nstruct Value {}\n\nfn borrow(val: &Value) {}\n\nfn eat(val: Value) {}\n\nfn main() {\n    let x = Value{};\n    let _ref_to_val: &Value = &x;\n    eat(x); // it will be copied here.\n    borrow(_ref_to_val);\n}\n```\n\nYou can find more information about borrowing in the rust-book:\nhttp://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":52,"byte_end":54,"line_start":3,"line_end":3,"column_start":14,"column_end":16,"is_primary":false,"text":[{"text":"    for i in &a {","highlight_start":14,"highlight_end":16}],"label":"borrow of `a` occurs here","suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":52,"byte_end":54,"line_start":3,"line_end":3,"column_start":14,"column_end":16,"is_primary":false,"text":[{"text":"    for i in &a {","highlight_start":14,"highlight_end":16}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `for loop`","def_site_span":{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":52,"byte_end":54,"line_start":3,"line_end":3,"column_start":14,"column_end":16,"is_primary":false,"text":[{"text":"    for i in &a {","highlight_start":14,"highlight_end":16}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}},{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":74,"byte_end":75,"line_start":4,"line_end":4,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for j in a {","highlight_start":18,"highlight_end":19}],"label":"move out of `a` occurs here","suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":74,"byte_end":75,"line_start":4,"line_end":4,"column_start":18,"column_end":19,"is_primary":false,"text":[{"text":"        for j in a {","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `for loop`","def_site_span":{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":74,"byte_end":75,"line_start":4,"line_end":4,"column_start":18,"column_end":19,"is_primary":false,"text":[{"text":"        for j in a {","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}},{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":52,"byte_end":54,"line_start":3,"line_end":3,"column_start":14,"column_end":16,"is_primary":false,"text":[{"text":"    for i in &a {","highlight_start":14,"highlight_end":16}],"label":"borrow later used here","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0505]: cannot move out of `a` because it is borrowed\n  --> /checkout/src/test/ui/suggestions/borrow-for-loop-head.rs:4:18\n   |\nLL |     for i in &a {\n   |              --\n   |              |\n   |              borrow of `a` occurs here\n   |              borrow later used here\nLL |         for j in a {\n   |                  ^ move out of `a` occurs here\n\n"}
[01:40:36] {"message":"use of moved value: `a`","code":{"code":"E0382","explanation":"\nThis error occurs when an attempt is made to use a variable after its contents\nhave been moved elsewhere. For example:\n\n```compile_fail,E0382\nstruct MyStruct { s: u32 }\n\nfn main() {\n    let mut x = MyStruct{ s: 5u32 };\n    let y = x;\n    x.s = 6;\n    println!(\"{}\", x.s);\n}\n```\n\nSince `MyStruct` is a type that is not marked `Copy`, the data gets moved out\nof `x` when we set `y`. This is fundamental to Rust's ownership system: outside\nof workarounds like `Rc`, a value cannot be owned by more than one variable.\n\nSometimes we don't need to move the value. Using a reference, we can let another\nfunction borrow the value without changing its ownership. In the example below,\nwe don't actually have to move our string to `calculate_length`, we can give it\na reference to it with `&` instead.\n\n```\nfn main() {\n    let s1 = String::from(\"hello\");\n\n    let len = calculate_length(&s1);\n\n    println!(\"The length of '{}' is {}.\", s1, len);\n}\n\nfn calculate_length(s: &String) -> usize {\n    s.len()\n}\n```\n\nA mutable reference can be created with `&mut`.\n\nSometimes we don't want a reference, but a duplicate. All types marked `Clone`\ncan be duplicated by calling `.clone()`. Subsequent changes to a clone do not\naffect the original variable.\n\nMost types in the standard library are marked `Clone`. The example below\ndemonstrates using `clone()` on a string. `s1` is first set to \"many\", and then\ncopied to `s2`. Then the first character of `s1` is removed, without affecting\n`s2`. \"any many\" is printed to the console.\n\n```\nfn main() {\n    let mut s1 = String::from(\"many\");\n    let s2 = s1.clone();\n    s1.remove(0);\n    println!(\"{} {}\", s1, s2);\n}\n```\n\nIf we control the definition of a type, we can implement `Clone` on it ourselves\nwith `#[derive(Clone)]`.\n\nSome types have no ownership semantics at all and are trivial to duplicate. An\nexample is `i32` and the other number types. We don't have to call `.clone()` to\nclone them, because they are marked `Copy` in addition to `Clone`.  Implicit\ncloning is more convenient in this case. We can mark our own types `Copy` if\nall their members also are marked `Copy`.\n\nIn the example below, we implement a `Point` type. Because it only stores two\nintegers, we opt-out of ownership semantics with `Copy`. Then we can\n`let p2 = p1` without `p1` being moved.\n\n```\n#[derive(Copy, Clone)]\nstruct Point { x: i32, y: i32 }\n\nfn main() {\n    let mut p1 = Point{ x: -1, y: 2 };\n    let p2 = p1;\n    p1.x = 1;\n    println!(\"p1: {}, {}\", p1.x, p1.y);\n    println!(\"p2: {}, {}\", p2.x, p2.y);\n}\n```\n\nAlternatively, if we don't control the struct's definition, or mutable shared\nownership is truly required, we can use `Rc` and `RefCell`:\n\n```\nuse std::cell::RefCell;\nuse std::rc::Rc;\n\nstruct MyStruct { s: u32 }\n\nfn main() {\n    let mut x = Rc::new(RefCell::new(MyStruct{ s: 5u32 }));\n    let y = x.clone();\n    x.borrow_mut().s = 6;\n    println!(\"{}\", x.borrow().s);\n}\n```\n\nWith this approach, x and y share ownership of the data via the `Rc` (reference\ncount type). `RefCell` essentially performs runtime borrow checking: ensuring\nthat at most one writer or multiple readers can access the data at any one time.\n\nIf you wish to learn more about ownership in Rust, start with the chapter in the\nBook:\n\nhttps://doc.rust-lang.org/book/ch04-00-understanding-ownership.html\n"},"level":"error","spans":[{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":74,"byte_end":75,"line_start":4,"line_end":4,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":"        for j in a {","highlight_start":18,"highlight_end":19}],"label":"value moved here, in previous iteration of loop","suggested_replacement":null,"suggestion_applicability":null,"expansion":{"span":{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":74,"byte_end":75,"line_start":4,"line_end":4,"column_start":18,"column_end":19,"is_primary":false,"text":[{"text":"        for j in a {","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},"macro_decl_name":"desugaring of `for loop`","def_site_span":{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":74,"byte_end":75,"line_start":4,"line_end":4,"column_start":18,"column_end":19,"is_primary":false,"text":[{"text":"        for j in a {","highlight_start":18,"highlight_end":19}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}}},{"file_name":"/checkout/src/test/ui/suggestions/borrow-for-loop-head.rs","byte_start":20,"byte_end":21,"line_start":2,"line_end":2,"column_start":9,"column_end":10,"is_primary":false,"text":[{"text":"    let a = vec![1, 2, 3];","highlight_start":9,"highlight_end":10}],"label":"move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0382]: use of moved value: `a`\n  --> /checkout/src/test/ui/suggestions/borrow-for-loop-head.rs:4:18\n   |\nLL |     let a = vec![1, 2, 3];\n   |         - move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait\nLL |     for i in &a {\nLL |         for j in a {\n   |                  ^ value moved here, in previous iteration of loop\n\n"}
[01:40:36] {"message":"aborting due to 2 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 2 previous errors\n\n"}
[01:40:36] {"message":"Some errors occurred: E0382, E0505.","code":null,"level":"","spans":[],"children":[],"rendered":"Some errors occurred: E0382, E0505.\n"}
[01:40:36] 
[01:40:36] ------------------------------------------
[01:40:36] 
[01:40:36] thread '[ui (nll)] ui/suggestions/borrow-for-loop-head.rs' panicked at 'explicit panic', src/tools/compiletest/src/runtest.rs:3369:9
---
[01:40:36] 
[01:40:36] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:496:22
[01:40:36] 
[01:40:36] 
[01:40:36] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/checkout/obj/build/x86_64-unknown-linux-gnu/llvm/build/bin/FileCheck" "--host-rustcflags" "-Crpath -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--llvm-version" "8.0.0-rust-1.35.0-dev\n" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always" "--compare-mode" "nll"
[01:40:36] 
[01:40:36] 
[01:40:36] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:40:36] Build completed unsuccessfully in 0:08:08
[01:40:36] Build completed unsuccessfully in 0:08:08
[01:40:36] Makefile:48: recipe for target 'check' failed
[01:40:36] make: *** [check] Error 1
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:05bd9ca0
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Sun Mar 24 05:36:21 UTC 2019
---
travis_time:end:00f079cd:start=1553405783500252427,finish=1553405783516598457,duration=16346030
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:0ea09360
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:22b4d2b2
travis_time:start:22b4d2b2
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:313edb69
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

estebank added some commits Mar 14, 2019

When moving out of a for loop head, suggest borrowing it
When encountering code like the following, suggest borrowing the for loop
head to avoid moving it into the for loop pattern:

```
fn main() {
    let a = vec![1, 2, 3];
    for i in &a {
        for j in a {
            println!("{} * {} = {}", i, j, i * j);
        }
    }
}
```

@estebank estebank force-pushed the estebank:for-loop-move branch from 6efdfbd to 66202c1 Mar 24, 2019

@estebank

This comment has been minimized.

Copy link
Contributor Author

commented Mar 24, 2019

@bors r=petrochenkov

I'll deal with replicating this output in nll mode later.

@bors

This comment has been minimized.

Copy link
Contributor

commented Mar 24, 2019

📌 Commit 66202c1 has been approved by petrochenkov

@bors

This comment has been minimized.

Copy link
Contributor

commented Mar 25, 2019

⌛️ Testing commit 66202c1 with merge 4691471...

bors added a commit that referenced this pull request Mar 25, 2019

Auto merge of #59195 - estebank:for-loop-move, r=petrochenkov
When moving out of a for loop head, suggest borrowing it

When encountering code like the following, suggest borrowing the for loop
head to avoid moving it into the for loop pattern:

```
fn main() {
    let a = vec![1, 2, 3];
    for i in &a {
        for j in a {
            println!("{} * {} = {}", i, j, i * j);
        }
    }
}
```

Fix #25534.
@bors

This comment has been minimized.

Copy link
Contributor

commented Mar 25, 2019

☀️ Test successful - checks-travis, status-appveyor
Approved by: petrochenkov
Pushing 4691471 to master...

@bors bors added the merged-by-bors label Mar 25, 2019

@bors bors merged commit 66202c1 into rust-lang:master Mar 25, 2019

1 check passed

homu Test successful
Details

Centril added a commit to Centril/rust that referenced this pull request Mar 27, 2019

Rollup merge of rust-lang#59429 - estebank:for-loop-move-nll, r=petro…
…chenkov

When moving out of a for loop head, suggest borrowing it in nll mode

Follow up to rust-lang#59195 for NLL.

Centril added a commit to Centril/rust that referenced this pull request Mar 27, 2019

Rollup merge of rust-lang#59429 - estebank:for-loop-move-nll, r=petro…
…chenkov

When moving out of a for loop head, suggest borrowing it in nll mode

Follow up to rust-lang#59195 for NLL.

Centril added a commit to Centril/rust that referenced this pull request Mar 28, 2019

Rollup merge of rust-lang#59429 - estebank:for-loop-move-nll, r=petro…
…chenkov

When moving out of a for loop head, suggest borrowing it in nll mode

Follow up to rust-lang#59195 for NLL.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.