Skip to content

Commit 629efae

Browse files
committed
look for the note on the guarantor, not the root cmt
This was causing upvar inference to fail for all cases where the move was from a projection, not the root variable.
1 parent dc6af49 commit 629efae

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

src/librustc_typeck/check/upvar.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,14 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
289289
let guarantor = cmt.guarantor();
290290
debug!("adjust_upvar_borrow_kind_for_consume: guarantor={:?}",
291291
guarantor);
292+
debug!("adjust_upvar_borrow_kind_for_consume: guarantor.cat={:?}",
293+
guarantor.cat);
292294
match guarantor.cat {
293295
Categorization::Deref(_, mc::BorrowedPtr(..)) |
294296
Categorization::Deref(_, mc::Implicit(..)) => {
295-
match cmt.note {
297+
debug!("adjust_upvar_borrow_kind_for_consume: found deref with note {:?}",
298+
cmt.note);
299+
match guarantor.note {
296300
mc::NoteUpvarRef(upvar_id) => {
297301
debug!("adjust_upvar_borrow_kind_for_consume: \
298302
setting upvar_id={:?} to by value",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(unused)]
12+
13+
fn foo<F>(f: F)
14+
where F: FnOnce()
15+
{
16+
}
17+
18+
fn main() {
19+
// Test that this closure is inferred to `FnOnce`
20+
// because it moves from `y.as<Option::Some>.0`:
21+
let x = Some(vec![1, 2, 3]);
22+
foo(|| {
23+
match x {
24+
Some(y) => { }
25+
None => { }
26+
}
27+
});
28+
29+
// Test that this closure is inferred to `FnOnce`
30+
// because it moves from `y.0`:
31+
let y = (vec![1, 2, 3], 0);
32+
foo(|| {
33+
let x = y.0;
34+
});
35+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(unused)]
12+
13+
fn foo<F>(f: F)
14+
where F: Fn()
15+
{
16+
}
17+
18+
fn main() {
19+
// Test that this closure is inferred to `FnOnce` because it moves
20+
// from `y.0`. This affects the error output (the error is that
21+
// the closure implements `FnOnce`, not that it moves from inside
22+
// a `Fn` closure.)
23+
let y = (vec![1, 2, 3], 0);
24+
let c = || drop(y.0);
25+
foo(c);
26+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
2+
--> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:24:13
3+
|
4+
24 | let c = || drop(y.0);
5+
| ^^^^^^^^^^^^
6+
25 | foo(c);
7+
| --- the requirement to implement `Fn` derives from here
8+
|
9+
note: closure is `FnOnce` because it moves the variable `y` out of its environment
10+
--> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:24:21
11+
|
12+
24 | let c = || drop(y.0);
13+
| ^
14+
15+
error: aborting due to previous error
16+

0 commit comments

Comments
 (0)