Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
08c4fbce
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
08c4fbce
编写于
3月 17, 2021
作者:
C
Chris Pardy
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Closure capture borrow diagnostics for disjoint captures
上级
6e2a3447
变更
56
显示空白变更内容
内联
并排
Showing
56 changed file
with
531 addition
and
151 deletion
+531
-151
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/mir/mod.rs
+11
-0
compiler/rustc_middle/src/ty/closure.rs
compiler/rustc_middle/src/ty/closure.rs
+20
-0
compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
...rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
+33
-15
compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs
.../rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs
+54
-17
compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
+77
-36
compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
...ler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
+6
-5
compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
...stc_mir/src/borrow_check/diagnostics/mutability_errors.rs
+2
-1
compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
...r/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
+1
-0
compiler/rustc_mir/src/borrow_check/mod.rs
compiler/rustc_mir/src/borrow_check/mod.rs
+1
-5
compiler/rustc_typeck/src/expr_use_visitor.rs
compiler/rustc_typeck/src/expr_use_visitor.rs
+3
-1
src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
...ui/async-await/async-borrowck-escaping-block-error.stderr
+3
-3
src/test/ui/borrowck/borrowck-closures-mut-and-imm.stderr
src/test/ui/borrowck/borrowck-closures-mut-and-imm.stderr
+4
-4
src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr
src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr
+2
-2
src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr
src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr
+2
-2
src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr
src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr
+4
-4
src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr
src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr
+2
-2
src/test/ui/borrowck/borrowck-closures-two-mut.stderr
src/test/ui/borrowck/borrowck-closures-two-mut.stderr
+2
-2
src/test/ui/borrowck/borrowck-closures-unique.stderr
src/test/ui/borrowck/borrowck-closures-unique.stderr
+1
-1
src/test/ui/borrowck/borrowck-closures-use-after-free.stderr
src/test/ui/borrowck/borrowck-closures-use-after-free.stderr
+1
-1
src/test/ui/borrowck/borrowck-insert-during-each.stderr
src/test/ui/borrowck/borrowck-insert-during-each.stderr
+2
-2
src/test/ui/borrowck/borrowck-loan-blocks-move-cc.stderr
src/test/ui/borrowck/borrowck-loan-blocks-move-cc.stderr
+2
-2
src/test/ui/borrowck/borrowck-loan-rcvr.stderr
src/test/ui/borrowck/borrowck-loan-rcvr.stderr
+1
-1
src/test/ui/borrowck/borrowck-move-by-capture.stderr
src/test/ui/borrowck/borrowck-move-by-capture.stderr
+4
-4
src/test/ui/borrowck/borrowck-move-moved-value-into-closure.stderr
...ui/borrowck/borrowck-move-moved-value-into-closure.stderr
+2
-2
src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr
...borrowck/issue-27282-mutate-before-diverging-arm-2.stderr
+1
-1
src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr
.../ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr
+1
-1
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs
.../2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs
+20
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr
...9_closure_analysis/diagnostics/borrowck/borrowck-1.stderr
+28
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs
.../2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs
+20
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr
...9_closure_analysis/diagnostics/borrowck/borrowck-2.stderr
+28
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs
.../2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs
+19
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr
...9_closure_analysis/diagnostics/borrowck/borrowck-3.stderr
+27
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
.../2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
+21
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
...9_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
+31
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs
...sis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs
+26
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr
...diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr
+30
-0
src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
.../ui/closures/2229_closure_analysis/diagnostics/box.stderr
+3
-3
src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr
...losure_analysis/diagnostics/cant-mutate-imm-borrow.stderr
+1
-1
src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs
...ures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs
+2
-2
src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
.../2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
+2
-2
src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr
.../2229_closure_analysis/diagnostics/multilevel-path.stderr
+1
-1
src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
...closures/2229_closure_analysis/diagnostics/mut_ref.stderr
+2
-2
src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
...ure_analysis/diagnostics/simple-struct-min-capture.stderr
+3
-1
src/test/ui/error-codes/E0504.stderr
src/test/ui/error-codes/E0504.stderr
+1
-1
src/test/ui/generator/yield-while-ref-reborrowed.stderr
src/test/ui/generator/yield-while-ref-reborrowed.stderr
+1
-1
src/test/ui/issues/issue-11192.stderr
src/test/ui/issues/issue-11192.stderr
+1
-1
src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr
...i/issues/issue-27282-mutate-before-diverging-arm-1.stderr
+1
-1
src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr
...i/issues/issue-27282-mutate-before-diverging-arm-3.stderr
+1
-1
src/test/ui/issues/issue-61623.stderr
src/test/ui/issues/issue-61623.stderr
+1
-1
src/test/ui/issues/issue-6801.stderr
src/test/ui/issues/issue-6801.stderr
+1
-1
src/test/ui/nll/closure-access-spans.stderr
src/test/ui/nll/closure-access-spans.stderr
+2
-2
src/test/ui/nll/closure-borrow-spans.stderr
src/test/ui/nll/closure-borrow-spans.stderr
+6
-6
src/test/ui/nll/closure-captures.stderr
src/test/ui/nll/closure-captures.stderr
+6
-6
src/test/ui/nll/closure-use-spans.stderr
src/test/ui/nll/closure-use-spans.stderr
+2
-2
src/test/ui/nll/closures-in-loops.stderr
src/test/ui/nll/closures-in-loops.stderr
+1
-1
src/test/ui/nll/issue-51268.stderr
src/test/ui/nll/issue-51268.stderr
+1
-1
未找到文件。
compiler/rustc_middle/src/mir/mod.rs
浏览文件 @
08c4fbce
...
...
@@ -683,6 +683,15 @@ pub fn allows_two_phase_borrow(&self) -> bool {
BorrowKind
::
Mut
{
allow_two_phase_borrow
}
=>
allow_two_phase_borrow
,
}
}
pub
fn
describe_mutability
(
&
self
)
->
String
{
match
*
self
{
BorrowKind
::
Shared
|
BorrowKind
::
Shallow
|
BorrowKind
::
Unique
=>
{
"immutable"
.to_string
()
}
BorrowKind
::
Mut
{
..
}
=>
"mutable"
.to_string
(),
}
}
}
///////////////////////////////////////////////////////////////////////////
...
...
@@ -2369,6 +2378,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
};
let
mut
struct_fmt
=
fmt
.debug_struct
(
&
name
);
// FIXME: This should be a list of capture names/places
if
let
Some
(
upvars
)
=
tcx
.upvars_mentioned
(
def_id
)
{
for
(
&
var_id
,
place
)
in
iter
::
zip
(
upvars
.keys
(),
places
)
{
let
var_name
=
tcx
.hir
()
.name
(
var_id
);
...
...
@@ -2388,6 +2398,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
let
name
=
format!
(
"[generator@{:?}]"
,
tcx
.hir
()
.span
(
hir_id
));
let
mut
struct_fmt
=
fmt
.debug_struct
(
&
name
);
// FIXME: This should be a list of capture names/places
if
let
Some
(
upvars
)
=
tcx
.upvars_mentioned
(
def_id
)
{
for
(
&
var_id
,
place
)
in
iter
::
zip
(
upvars
.keys
(),
places
)
{
let
var_name
=
tcx
.hir
()
.name
(
var_id
);
...
...
compiler/rustc_middle/src/ty/closure.rs
浏览文件 @
08c4fbce
...
...
@@ -151,6 +151,10 @@ pub struct CapturedPlace<'tcx> {
}
impl
CapturedPlace
<
'tcx
>
{
pub
fn
to_string
(
&
self
,
tcx
:
TyCtxt
<
'tcx
>
)
->
String
{
place_to_string_for_capture
(
tcx
,
&
self
.place
)
}
/// Returns the hir-id of the root variable for the captured place.
/// e.g., if `a.b.c` was captured, would return the hir-id for `a`.
pub
fn
get_root_variable
(
&
self
)
->
hir
::
HirId
{
...
...
@@ -168,6 +172,22 @@ pub fn get_closure_local_def_id(&self) -> LocalDefId {
}
}
/// Return span pointing to use that resulted in selecting the captured path
pub
fn
get_path_span
(
&
self
,
tcx
:
TyCtxt
<
'tcx
>
)
->
Span
{
if
let
Some
(
path_expr_id
)
=
self
.info.path_expr_id
{
tcx
.hir
()
.span
(
path_expr_id
)
}
else
if
let
Some
(
capture_kind_expr_id
)
=
self
.info.capture_kind_expr_id
{
tcx
.hir
()
.span
(
capture_kind_expr_id
)
}
else
{
// Fallback on upvars mentioned if neither path or capture expr id is captured
// Safe to unwrap since we know this place is captured by the closure, therefore the closure must have upvars.
tcx
.upvars_mentioned
(
self
.get_closure_local_def_id
())
.unwrap
()
[
&
self
.get_root_variable
()]
.span
}
}
/// Return span pointing to use that resulted in selecting the current capture kind
pub
fn
get_capture_kind_span
(
&
self
,
tcx
:
TyCtxt
<
'tcx
>
)
->
Span
{
if
let
Some
(
capture_kind_expr_id
)
=
self
.info.capture_kind_expr_id
{
...
...
compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
浏览文件 @
08c4fbce
...
...
@@ -99,7 +99,7 @@ pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized(
);
err
.span_label
(
span
,
format!
(
"use of possibly-uninitialized {}"
,
item_msg
));
use_spans
.var_span_label
(
use_spans
.var_span_label
_path_only
(
&
mut
err
,
format!
(
"{} occurs due to use{}"
,
desired_action
.as_noun
(),
use_spans
.describe
()),
);
...
...
@@ -255,6 +255,7 @@ pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized(
partially_str
,
move_spans
.describe
()
),
"moved"
,
);
}
}
...
...
@@ -304,7 +305,7 @@ pub(in crate::borrow_check) fn report_use_of_moved_or_uninitialized(
}
}
use_spans
.var_span_label
(
use_spans
.var_span_label
_path_only
(
&
mut
err
,
format!
(
"{} occurs due to use{}"
,
desired_action
.as_noun
(),
use_spans
.describe
()),
);
...
...
@@ -434,13 +435,16 @@ pub(in crate::borrow_check) fn report_move_out_while_borrowed(
err
.span_label
(
borrow_span
,
format!
(
"borrow of {} occurs here"
,
borrow_msg
));
err
.span_label
(
span
,
format!
(
"move out of {} occurs here"
,
value_msg
));
borrow_spans
.var_span_label
(
borrow_spans
.var_span_label
_path_only
(
&
mut
err
,
format!
(
"borrow occurs due to use{}"
,
borrow_spans
.describe
()),
);
move_spans
.var_span_label
(
&
mut
err
,
format!
(
"move occurs due to use{}"
,
move_spans
.describe
()));
move_spans
.var_span_label
(
&
mut
err
,
format!
(
"move occurs due to use{}"
,
move_spans
.describe
()),
"moved"
,
);
self
.explain_why_borrow_contains_point
(
location
,
borrow
,
None
)
.add_explanation_to_diagnostic
(
...
...
@@ -468,6 +472,8 @@ pub(in crate::borrow_check) fn report_use_while_mutably_borrowed(
let
use_spans
=
self
.move_spans
(
place
.as_ref
(),
location
);
let
span
=
use_spans
.var_or_use
();
// If the attempted use is in a closure then we do not care about the path span of the place we are currently trying to use
// we call `var_span_label` on `borrow_spans` to annotate if the existing borrow was in a closure
let
mut
err
=
self
.cannot_use_when_mutably_borrowed
(
span
,
&
self
.describe_any_place
(
place
.as_ref
()),
...
...
@@ -475,11 +481,15 @@ pub(in crate::borrow_check) fn report_use_while_mutably_borrowed(
&
self
.describe_any_place
(
borrow
.borrowed_place
.as_ref
()),
);
borrow_spans
.var_span_label
(
&
mut
err
,
{
borrow_spans
.var_span_label
(
&
mut
err
,
{
let
place
=
&
borrow
.borrowed_place
;
let
desc_place
=
self
.describe_any_place
(
place
.as_ref
());
format!
(
"borrow occurs due to use of {}{}"
,
desc_place
,
borrow_spans
.describe
())
});
},
"mutable"
,
);
self
.explain_why_borrow_contains_point
(
location
,
borrow
,
None
)
.add_explanation_to_diagnostic
(
...
...
@@ -591,6 +601,7 @@ pub(in crate::borrow_check) fn report_conflicting_borrow(
desc_place
,
borrow_spans
.describe
(),
),
"immutable"
,
);
return
err
;
...
...
@@ -667,7 +678,8 @@ pub(in crate::borrow_check) fn report_conflicting_borrow(
if
issued_spans
==
borrow_spans
{
borrow_spans
.var_span_label
(
&
mut
err
,
format!
(
"borrows occur due to use of {}{}"
,
desc_place
,
borrow_spans
.describe
()),
format!
(
"borrows occur due to use of {}{}"
,
desc_place
,
borrow_spans
.describe
(),),
gen_borrow_kind
.describe_mutability
(),
);
}
else
{
let
borrow_place
=
&
issued_borrow
.borrowed_place
;
...
...
@@ -679,6 +691,7 @@ pub(in crate::borrow_check) fn report_conflicting_borrow(
borrow_place_desc
,
issued_spans
.describe
(),
),
issued_borrow
.kind
.describe_mutability
(),
);
borrow_spans
.var_span_label
(
...
...
@@ -688,6 +701,7 @@ pub(in crate::borrow_check) fn report_conflicting_borrow(
desc_place
,
borrow_spans
.describe
(),
),
gen_borrow_kind
.describe_mutability
(),
);
}
...
...
@@ -847,7 +861,7 @@ pub(in crate::borrow_check) fn report_borrowed_value_does_not_live_long_enough(
self
.prefixes
(
borrow
.borrowed_place
.as_ref
(),
PrefixSet
::
All
)
.last
()
.unwrap
();
let
borrow_spans
=
self
.retrieve_borrow_spans
(
borrow
);
let
borrow_span
=
borrow_spans
.var_or_use
();
let
borrow_span
=
borrow_spans
.var_or_use
_path_span
();
assert
!
(
root_place
.projection
.is_empty
());
let
proper_span
=
self
.body.local_decls
[
root_place
.local
]
.source_info.span
;
...
...
@@ -987,7 +1001,7 @@ fn report_local_value_does_not_live_long_enough(
location
,
name
,
borrow
,
drop_span
,
borrow_spans
);
let
borrow_span
=
borrow_spans
.var_or_use
();
let
borrow_span
=
borrow_spans
.var_or_use
_path_span
();
if
let
BorrowExplanation
::
MustBeValidFor
{
category
,
span
,
...
...
@@ -1575,6 +1589,7 @@ pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed(
loan_spans
.var_span_label
(
&
mut
err
,
format!
(
"borrow occurs due to use{}"
,
loan_spans
.describe
()),
loan
.kind
.describe_mutability
(),
);
err
.buffer
(
&
mut
self
.errors_buffer
);
...
...
@@ -1585,8 +1600,11 @@ pub(in crate::borrow_check) fn report_illegal_mutation_of_borrowed(
let
mut
err
=
self
.cannot_assign_to_borrowed
(
span
,
loan_span
,
&
descr_place
);
loan_spans
.var_span_label
(
&
mut
err
,
format!
(
"borrow occurs due to use{}"
,
loan_spans
.describe
()));
loan_spans
.var_span_label
(
&
mut
err
,
format!
(
"borrow occurs due to use{}"
,
loan_spans
.describe
()),
loan
.kind
.describe_mutability
(),
);
self
.explain_why_borrow_contains_point
(
location
,
loan
,
None
)
.add_explanation_to_diagnostic
(
self
.infcx.tcx
,
...
...
compiler/rustc_mir/src/borrow_check/diagnostics/explain_borrow.rs
浏览文件 @
08c4fbce
...
...
@@ -24,8 +24,8 @@
#[derive(Debug)]
pub
(
in
crate
::
borrow_check
)
enum
BorrowExplanation
{
UsedLater
(
LaterUseKind
,
Span
),
UsedLaterInLoop
(
LaterUseKind
,
Span
),
UsedLater
(
LaterUseKind
,
Span
,
Option
<
Span
>
),
UsedLaterInLoop
(
LaterUseKind
,
Span
,
Option
<
Span
>
),
UsedLaterWhenDropped
{
drop_loc
:
Location
,
dropped_local
:
Local
,
...
...
@@ -67,7 +67,7 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>(
borrow_span
:
Option
<
Span
>
,
)
{
match
*
self
{
BorrowExplanation
::
UsedLater
(
later_use_kind
,
var_or_use_span
)
=>
{
BorrowExplanation
::
UsedLater
(
later_use_kind
,
var_or_use_span
,
path_span
)
=>
{
let
message
=
match
later_use_kind
{
LaterUseKind
::
TraitCapture
=>
"captured here by trait object"
,
LaterUseKind
::
ClosureCapture
=>
"captured here by closure"
,
...
...
@@ -75,14 +75,31 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>(
LaterUseKind
::
FakeLetRead
=>
"stored here"
,
LaterUseKind
::
Other
=>
"used here"
,
};
// We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
if
path_span
.map_or
(
true
,
|
path_span
|
path_span
==
var_or_use_span
)
{
if
!
borrow_span
.map_or
(
false
,
|
sp
|
sp
.overlaps
(
var_or_use_span
))
{
err
.span_label
(
var_or_use_span
,
format!
(
"{}borrow later {}"
,
borrow_desc
,
message
),
);
}
}
else
{
// path_span must be `Some` as otherwise the if condition is true
let
path_span
=
path_span
.unwrap
();
// path_span is only present in the case of closure capture
assert
!
(
matches!
(
later_use_kind
,
LaterUseKind
::
ClosureCapture
));
if
!
borrow_span
.map_or
(
false
,
|
sp
|
sp
.overlaps
(
var_or_use_span
))
{
let
path_label
=
"used here by closure"
;
let
capture_kind_label
=
message
;
err
.span_label
(
var_or_use_span
,
format!
(
"{}borrow later {}"
,
borrow_desc
,
capture_kind_label
),
);
err
.span_label
(
path_span
,
path_label
);
}
}
}
BorrowExplanation
::
UsedLaterInLoop
(
later_use_kind
,
var_or_use_span
)
=>
{
BorrowExplanation
::
UsedLaterInLoop
(
later_use_kind
,
var_or_use_span
,
path_span
)
=>
{
let
message
=
match
later_use_kind
{
LaterUseKind
::
TraitCapture
=>
{
"borrow captured here by trait object, in later iteration of loop"
...
...
@@ -94,7 +111,24 @@ pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>(
LaterUseKind
::
FakeLetRead
=>
"borrow later stored here"
,
LaterUseKind
::
Other
=>
"borrow used here, in later iteration of loop"
,
};
// We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
if
path_span
.map_or
(
true
,
|
path_span
|
path_span
==
var_or_use_span
)
{
err
.span_label
(
var_or_use_span
,
format!
(
"{}{}"
,
borrow_desc
,
message
));
}
else
{
// path_span must be `Some` as otherwise the if condition is true
let
path_span
=
path_span
.unwrap
();
// path_span is only present in the case of closure capture
assert
!
(
matches!
(
later_use_kind
,
LaterUseKind
::
ClosureCapture
));
if
!
borrow_span
.map_or
(
false
,
|
sp
|
sp
.overlaps
(
var_or_use_span
))
{
let
path_label
=
"used here by closure"
;
let
capture_kind_label
=
message
;
err
.span_label
(
var_or_use_span
,
format!
(
"{}borrow later {}"
,
borrow_desc
,
capture_kind_label
),
);
err
.span_label
(
path_span
,
path_label
);
}
}
}
BorrowExplanation
::
UsedLaterWhenDropped
{
drop_loc
,
...
...
@@ -311,13 +345,13 @@ pub(in crate::borrow_check) fn explain_why_borrow_contains_point(
let
borrow_location
=
location
;
if
self
.is_use_in_later_iteration_of_loop
(
borrow_location
,
location
)
{
let
later_use
=
self
.later_use_kind
(
borrow
,
spans
,
location
);
BorrowExplanation
::
UsedLaterInLoop
(
later_use
.0
,
later_use
.1
)
BorrowExplanation
::
UsedLaterInLoop
(
later_use
.0
,
later_use
.1
,
later_use
.2
)
}
else
{
// Check if the location represents a `FakeRead`, and adapt the error
// message to the `FakeReadCause` it is from: in particular,
// the ones inserted in optimized `let var = <expr>` patterns.
let
later_use
=
self
.later_use_kind
(
borrow
,
spans
,
location
);
BorrowExplanation
::
UsedLater
(
later_use
.0
,
later_use
.1
)
BorrowExplanation
::
UsedLater
(
later_use
.0
,
later_use
.1
,
later_use
.2
)
}
}
...
...
@@ -498,16 +532,19 @@ fn is_back_edge(&self, source: Location, target: Location) -> bool {
}
/// Determine how the borrow was later used.
/// First span returned points to the location of the conflicting use
/// Second span if `Some` is returned in the case of closures and points
/// to the use of the path
fn
later_use_kind
(
&
self
,
borrow
:
&
BorrowData
<
'tcx
>
,
use_spans
:
UseSpans
<
'tcx
>
,
location
:
Location
,
)
->
(
LaterUseKind
,
Span
)
{
)
->
(
LaterUseKind
,
Span
,
Option
<
Span
>
)
{
match
use_spans
{
UseSpans
::
ClosureUse
{
var
_span
,
..
}
=>
{
UseSpans
::
ClosureUse
{
capture_kind_span
,
path
_span
,
..
}
=>
{
// Used in a closure.
(
LaterUseKind
::
ClosureCapture
,
var_span
)
(
LaterUseKind
::
ClosureCapture
,
capture_kind_span
,
Some
(
path_span
)
)
}
UseSpans
::
PatUse
(
span
)
|
UseSpans
::
OtherUse
(
span
)
...
...
@@ -542,7 +579,7 @@ fn later_use_kind(
}
}
};
return
(
LaterUseKind
::
Call
,
function_span
);
return
(
LaterUseKind
::
Call
,
function_span
,
None
);
}
else
{
LaterUseKind
::
Other
}
...
...
@@ -550,7 +587,7 @@ fn later_use_kind(
LaterUseKind
::
Other
};
(
kind
,
span
)
(
kind
,
span
,
None
)
}
}
}
...
...
compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs
浏览文件 @
08c4fbce
...
...
@@ -18,7 +18,6 @@
Span
,
};
use
rustc_target
::
abi
::
VariantIdx
;
use
std
::
iter
;
use
super
::
borrow_set
::
BorrowData
;
use
super
::
MirBorrowckCtxt
;
...
...
@@ -216,11 +215,10 @@ fn append_place_to_string(
PlaceRef
{
local
,
projection
:
[
proj_base
@
..
,
elem
]
}
=>
{
match
elem
{
ProjectionElem
::
Deref
=>
{
// FIXME(project-rfc_2229#36): print capture precisely here.
let
upvar_field_projection
=
self
.is_upvar_field_projection
(
place
);
if
let
Some
(
field
)
=
upvar_field_projection
{
let
var_index
=
field
.index
();
let
name
=
self
.upvars
[
var_index
]
.
name
.to_string
(
);
let
name
=
self
.upvars
[
var_index
]
.
place
.to_string
(
self
.infcx.tcx
);
if
self
.upvars
[
var_index
]
.by_ref
{
buf
.push_str
(
&
name
);
}
else
{
...
...
@@ -265,7 +263,7 @@ fn append_place_to_string(
let
upvar_field_projection
=
self
.is_upvar_field_projection
(
place
);
if
let
Some
(
field
)
=
upvar_field_projection
{
let
var_index
=
field
.index
();
let
name
=
self
.upvars
[
var_index
]
.
name
.to_string
(
);
let
name
=
self
.upvars
[
var_index
]
.
place
.to_string
(
self
.infcx.tcx
);
buf
.push_str
(
&
name
);
}
else
{
let
field_name
=
self
...
...
@@ -550,8 +548,12 @@ pub(super) enum UseSpans<'tcx> {
/// The span of the args of the closure, including the `move` keyword if
/// it's present.
args_span
:
Span
,
/// The span of the first use of the captured variable inside the closure.
var_span
:
Span
,
/// The span of the use resulting in capture kind
/// Check `ty::CaptureInfo` for more details
capture_kind_span
:
Span
,
/// The span of the use resulting in the captured path
/// Check `ty::CaptureInfo` for more details
path_span
:
Span
,
},
/// The access is caused by using a variable as the receiver of a method
/// that takes 'self'
...
...
@@ -606,9 +608,21 @@ pub(super) fn args_or_use(self) -> Span {
}
}
pub
(
super
)
fn
var_or_use_path_span
(
self
)
->
Span
{
match
self
{
UseSpans
::
ClosureUse
{
path_span
:
span
,
..
}
|
UseSpans
::
PatUse
(
span
)
|
UseSpans
::
OtherUse
(
span
)
=>
span
,
UseSpans
::
FnSelfUse
{
fn_call_span
,
kind
:
FnSelfUseKind
::
DerefCoercion
{
..
},
..
}
=>
fn_call_span
,
UseSpans
::
FnSelfUse
{
var_span
,
..
}
=>
var_span
,
}
}
pub
(
super
)
fn
var_or_use
(
self
)
->
Span
{
match
self
{
UseSpans
::
ClosureUse
{
var
_span
:
span
,
..
}
UseSpans
::
ClosureUse
{
capture_kind
_span
:
span
,
..
}
|
UseSpans
::
PatUse
(
span
)
|
UseSpans
::
OtherUse
(
span
)
=>
span
,
UseSpans
::
FnSelfUse
{
...
...
@@ -636,14 +650,35 @@ pub(super) fn args_span_label(
}
}
// Add a span label to the use of the captured variable, if it exists.
// only adds label to the `path_span`
pub
(
super
)
fn
var_span_label_path_only
(
self
,
err
:
&
mut
DiagnosticBuilder
<
'_
>
,
message
:
impl
Into
<
String
>
,
)
{
if
let
UseSpans
::
ClosureUse
{
path_span
,
..
}
=
self
{
err
.span_label
(
path_span
,
message
);
}
}
// Add a span label to the use of the captured variable, if it exists.
pub
(
super
)
fn
var_span_label
(
self
,
err
:
&
mut
DiagnosticBuilder
<
'_
>
,
message
:
impl
Into
<
String
>
,
kind_desc
:
impl
Into
<
String
>
,
)
{
if
let
UseSpans
::
ClosureUse
{
var_span
,
..
}
=
self
{
err
.span_label
(
var_span
,
message
);
if
let
UseSpans
::
ClosureUse
{
capture_kind_span
,
path_span
,
..
}
=
self
{
if
capture_kind_span
==
path_span
{
err
.span_label
(
capture_kind_span
,
message
);
}
else
{
let
capture_kind_label
=
format!
(
"capture is {} because of use here"
,
kind_desc
.into
());
let
path_label
=
message
;
err
.span_label
(
capture_kind_span
,
capture_kind_label
);
err
.span_label
(
path_span
,
path_label
);
}
}
}
...
...
@@ -791,10 +826,15 @@ pub(super) fn move_spans(
box
AggregateKind
::
Closure
(
def_id
,
_
)
|
box
AggregateKind
::
Generator
(
def_id
,
_
,
_
)
=>
{
debug!
(
"move_spans: def_id={:?} places={:?}"
,
def_id
,
places
);
if
let
Some
((
args_span
,
generator_kind
,
var
_span
))
=
if
let
Some
((
args_span
,
generator_kind
,
capture_kind_span
,
path
_span
))
=
self
.closure_span
(
*
def_id
,
moved_place
,
places
)
{
return
ClosureUse
{
generator_kind
,
args_span
,
var_span
};
return
ClosureUse
{
generator_kind
,
args_span
,
capture_kind_span
,
path_span
,
};
}
}
_
=>
{}
...
...
@@ -809,10 +849,15 @@ pub(super) fn move_spans(
|
FakeReadCause
::
ForLet
(
Some
(
closure_def_id
))
=>
{
debug!
(
"move_spans: def_id={:?} place={:?}"
,
closure_def_id
,
place
);
let
places
=
&
[
Operand
::
Move
(
*
place
)];
if
let
Some
((
args_span
,
generator_kind
,
var
_span
))
=
if
let
Some
((
args_span
,
generator_kind
,
capture_kind_span
,
path
_span
))
=
self
.closure_span
(
closure_def_id
,
moved_place
,
places
)
{
return
ClosureUse
{
generator_kind
,
args_span
,
var_span
};
return
ClosureUse
{
generator_kind
,
args_span
,
capture_kind_span
,
path_span
,
};
}
}
_
=>
{}
...
...
@@ -972,10 +1017,10 @@ pub(super) fn borrow_spans(&self, use_span: Span, location: Location) -> UseSpan
"borrow_spans: def_id={:?} is_generator={:?} places={:?}"
,
def_id
,
is_generator
,
places
);
if
let
Some
((
args_span
,
generator_kind
,
var
_span
))
=
if
let
Some
((
args_span
,
generator_kind
,
capture_kind_span
,
path
_span
))
=
self
.closure_span
(
*
def_id
,
Place
::
from
(
target
)
.as_ref
(),
places
)
{
return
ClosureUse
{
generator_kind
,
args_span
,
var
_span
};
return
ClosureUse
{
generator_kind
,
args_span
,
capture_kind_span
,
path
_span
};
}
else
{
return
OtherUse
(
use_span
);
}
...
...
@@ -989,13 +1034,15 @@ pub(super) fn borrow_spans(&self, use_span: Span, location: Location) -> UseSpan
OtherUse
(
use_span
)
}
/// Finds the span of a captured variable within a closure or generator.
/// Finds the spans of a captured place within a closure or generator.
/// The first span is the location of the use resulting in the capture kind of the capture
/// The second span is the location the use resulting in the captured path of the capture
fn
closure_span
(
&
self
,
def_id
:
DefId
,
target_place
:
PlaceRef
<
'tcx
>
,
places
:
&
[
Operand
<
'tcx
>
],
)
->
Option
<
(
Span
,
Option
<
GeneratorKind
>
,
Span
)
>
{
)
->
Option
<
(
Span
,
Option
<
GeneratorKind
>
,
Span
,
Span
)
>
{
debug!
(
"closure_span: def_id={:?} target_place={:?} places={:?}"
,
def_id
,
target_place
,
places
...
...
@@ -1005,13 +1052,13 @@ fn closure_span(
let
expr
=
&
self
.infcx.tcx
.hir
()
.expect_expr
(
hir_id
)
.kind
;
debug!
(
"closure_span: hir_id={:?} expr={:?}"
,
hir_id
,
expr
);
if
let
hir
::
ExprKind
::
Closure
(
..
,
body_id
,
args_span
,
_
)
=
expr
{
for
(
captured_place
,
place
)
in
iter
::
zip
(
self
.infcx.tcx
.typeck
(
def_id
.expect_local
())
.closure_min_captures_flattened
(
def_id
),
places
,
)
{
let
upvar_hir_id
=
captured_place
.get_root_variable
();
//FIXME(project-rfc-2229#8): Use better span from captured_place
let
span
=
self
.infcx.tcx
.upvars_mentioned
(
local_did
)
?
[
&
upvar_hir_id
]
.span
;
for
(
captured_place
,
place
)
in
self
.infcx
.tcx
.typeck
(
def_id
.expect_local
())
.closure_min_captures_flattened
(
def_id
)
.zip
(
places
)
{
match
place
{
Operand
::
Copy
(
place
)
|
Operand
::
Move
(
place
)
if
target_place
==
place
.as_ref
()
=>
...
...
@@ -1020,18 +1067,12 @@ fn closure_span(
let
body
=
self
.infcx.tcx
.hir
()
.body
(
*
body_id
);
let
generator_kind
=
body
.generator_kind
();
// If we have a more specific span available, point to that.
// We do this even though this span might be part of a borrow error
// message rather than a move error message. Our goal is to point
// to a span that shows why the upvar is used in the closure,
// so a move-related span is as good as any (and potentially better,
// if the overall error is due to a move of the upvar).
let
usage_span
=
match
captured_place
.info.capture_kind
{
ty
::
UpvarCapture
::
ByValue
(
Some
(
span
))
=>
span
,
_
=>
span
,
};
return
Some
((
*
args_span
,
generator_kind
,
usage_span
));
return
Some
((
*
args_span
,
generator_kind
,
captured_place
.get_capture_kind_span
(
self
.infcx.tcx
),
captured_place
.get_path_span
(
self
.infcx.tcx
),
));
}
_
=>
{}
}
...
...
compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
浏览文件 @
08c4fbce
...
...
@@ -345,10 +345,8 @@ fn report_cannot_move_from_borrowed_content(
};
let
upvar
=
&
self
.upvars
[
upvar_field
.unwrap
()
.index
()];
// FIXME(project-rfc-2229#8): Improve borrow-check diagnostics in case of precise
// capture.
let
upvar_hir_id
=
upvar
.place
.get_root_variable
();
let
upvar_name
=
upvar
.
name
;
let
upvar_name
=
upvar
.
place
.to_string
(
self
.infcx.tcx
)
;
let
upvar_span
=
self
.infcx.tcx
.hir
()
.span
(
upvar_hir_id
);
let
place_name
=
self
.describe_any_place
(
move_place
.as_ref
());
...
...
@@ -478,8 +476,11 @@ fn add_move_hints(
self
.note_type_does_not_implement_copy
(
err
,
&
place_desc
,
place_ty
,
Some
(
span
),
""
);
use_spans
.args_span_label
(
err
,
format!
(
"move out of {} occurs here"
,
place_desc
));
use_spans
.var_span_label
(
err
,
format!
(
"move occurs due to use{}"
,
use_spans
.describe
()));
use_spans
.var_span_label
(
err
,
format!
(
"move occurs due to use{}"
,
use_spans
.describe
()),
"moved"
,
);
}
}
}
...
...
compiler/rustc_mir/src/borrow_check/diagnostics/mutability_errors.rs
浏览文件 @
08c4fbce
...
...
@@ -85,7 +85,7 @@ pub(crate) fn report_mutability_error(
if
self
.is_upvar_field_projection
(
access_place
.as_ref
())
.is_some
()
{
reason
=
", as it is not declared as mutable"
.to_string
();
}
else
{
let
name
=
self
.upvars
[
upvar_index
.index
()]
.
name
;
let
name
=
self
.upvars
[
upvar_index
.index
()]
.
place
.to_string
(
self
.infcx.tcx
)
;
reason
=
format!
(
", as `{}` is not declared as mutable"
,
name
);
}
}
...
...
@@ -195,6 +195,7 @@ pub(crate) fn report_mutability_error(
"mutable borrow occurs due to use of {} in closure"
,
self
.describe_any_place
(
access_place
.as_ref
()),
),
"mutable"
,
);
borrow_span
}
...
...
compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs
浏览文件 @
08c4fbce
...
...
@@ -385,6 +385,7 @@ fn report_fnmut_error(
diag
.span_label
(
*
span
,
message
);
// FIXME: This should store a captured_place not a hir id
if
let
ReturnConstraint
::
ClosureUpvar
(
upvar
)
=
kind
{
let
def_id
=
match
self
.regioncx
.universal_regions
()
.defining_ty
{
DefiningTy
::
Closure
(
def_id
,
_
)
=>
def_id
,
...
...
compiler/rustc_mir/src/borrow_check/mod.rs
浏览文件 @
08c4fbce
...
...
@@ -74,9 +74,6 @@
// FIXME(eddyb) perhaps move this somewhere more centrally.
#[derive(Debug)]
crate
struct
Upvar
<
'tcx
>
{
// FIXME(project-rfc_2229#36): print capture precisely here.
name
:
Symbol
,
place
:
CapturedPlace
<
'tcx
>
,
/// If true, the capture is behind a reference.
...
...
@@ -159,13 +156,12 @@ fn do_mir_borrowck<'a, 'tcx>(
let
upvars
:
Vec
<
_
>
=
tables
.closure_min_captures_flattened
(
def
.did
.to_def_id
())
.map
(|
captured_place
|
{
let
var_hir_id
=
captured_place
.get_root_variable
();
let
capture
=
captured_place
.info.capture_kind
;
let
by_ref
=
match
capture
{
ty
::
UpvarCapture
::
ByValue
(
_
)
=>
false
,
ty
::
UpvarCapture
::
ByRef
(
..
)
=>
true
,
};
Upvar
{
name
:
tcx
.hir
()
.name
(
var_hir_id
),
place
:
captured_place
.clone
(),
by_ref
}
Upvar
{
place
:
captured_place
.clone
(),
by_ref
}
})
.collect
();
...
...
compiler/rustc_typeck/src/expr_use_visitor.rs
浏览文件 @
08c4fbce
...
...
@@ -763,7 +763,9 @@ fn upvar_is_local_variable(
PlaceBase
::
Local
(
*
var_hir_id
)
};
let
place_with_id
=
PlaceWithHirId
::
new
(
capture_info
.path_expr_id
.unwrap_or
(
closure_expr
.hir_id
),
capture_info
.path_expr_id
.unwrap_or
(
capture_info
.capture_kind_expr_id
.unwrap_or
(
closure_expr
.hir_id
),
),
place
.base_ty
,
place_base
,
place
.projections
.clone
(),
...
...
src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
浏览文件 @
08c4fbce
...
...
@@ -21,7 +21,7 @@ error[E0373]: async block may outlive the current function, but it borrows `x`,
--> $DIR/async-borrowck-escaping-block-error.rs:11:11
|
LL | async { *x }
| ^^
^
-^^
| ^^
-
-^^
| | |
| | `x` is borrowed here
| may outlive borrowed value `x`
...
...
src/test/ui/borrowck/borrowck-closures-mut-and-imm.stderr
浏览文件 @
08c4fbce
...
...
@@ -73,7 +73,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed
--> $DIR/borrowck-closures-mut-and-imm.rs:57:5
|
LL | let c1 = || get(&*x);
| --
- borrow occurs due to use in closure
| --
-
- borrow occurs due to use in closure
| |
| borrow of `*x` occurs here
LL | *x = 5;
...
...
@@ -86,7 +86,7 @@ error[E0506]: cannot assign to `*x.f` because it is borrowed
--> $DIR/borrowck-closures-mut-and-imm.rs:69:5
|
LL | let c1 = || get(&*x.f);
| --
- borrow occurs due to use in closure
| --
---
- borrow occurs due to use in closure
| |
| borrow of `*x.f` occurs here
LL | *x.f = 5;
...
...
@@ -99,11 +99,11 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immuta
--> $DIR/borrowck-closures-mut-and-imm.rs:81:14
|
LL | let c1 = || get(&*x.f);
| --
- first borrow occurs due to use of `x` in closure
| --
---
- first borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
LL | let c2 = || *x.f = 5;
| ^^
- second borrow occurs due to use of `x` in closure
| ^^
---
- second borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
LL |
...
...
src/test/ui/borrowck/borrowck-closures-mut-of-imm.stderr
浏览文件 @
08c4fbce
...
...
@@ -14,12 +14,12 @@ error[E0524]: two closures require unique access to `x` at the same time
--> $DIR/borrowck-closures-mut-of-imm.rs:11:18
|
LL | let mut c1 = || set(&mut *x);
| --
- first borrow occurs due to use of `x` in closure
| --
-
- first borrow occurs due to use of `x` in closure
| |
| first closure is constructed here
LL |
LL | let mut c2 = || set(&mut *x);
| ^^
- second borrow occurs due to use of `x` in closure
| ^^
-
- second borrow occurs due to use of `x` in closure
| |
| second closure is constructed here
...
...
...
src/test/ui/borrowck/borrowck-closures-mut-of-mut.stderr
浏览文件 @
08c4fbce
...
...
@@ -2,11 +2,11 @@ error[E0524]: two closures require unique access to `x` at the same time
--> $DIR/borrowck-closures-mut-of-mut.rs:14:18
|
LL | let mut c1 = || set(&mut *x);
| --
- first borrow occurs due to use of `x` in closure
| --
-
- first borrow occurs due to use of `x` in closure
| |
| first closure is constructed here
LL | let mut c2 = || set(&mut *x);
| ^^
- second borrow occurs due to use of `x` in closure
| ^^
-
- second borrow occurs due to use of `x` in closure
| |
| second closure is constructed here
LL |
...
...
src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr
浏览文件 @
08c4fbce
...
...
@@ -45,7 +45,7 @@ error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immut
LL | let f = || {
| -- immutable borrow occurs here
LL | let [ref y, ref z @ ..] = *x;
|
- first borrow occurs due to use of `x` in closure
|
-
- first borrow occurs due to use of `x` in closure
LL | };
LL | let r = &mut *x;
| ^^^^^^^ mutable borrow occurs here
...
...
@@ -59,7 +59,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u
LL | let mut f = || {
| -- closure construction occurs here
LL | let [ref mut y, ref mut z @ ..] = *x;
|
- first borrow occurs due to use of `x` in closure
|
-
- first borrow occurs due to use of `x` in closure
LL | };
LL | let r = &x;
| ^^ second borrow occurs here
...
...
@@ -86,7 +86,7 @@ error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immut
LL | let f = || {
| -- immutable borrow occurs here
LL | if let [ref y, ref z @ ..] = *x {}
|
- first borrow occurs due to use of `x` in closure
|
-
- first borrow occurs due to use of `x` in closure
LL | };
LL | let r = &mut *x;
| ^^^^^^^ mutable borrow occurs here
...
...
@@ -100,7 +100,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u
LL | let mut f = || {
| -- closure construction occurs here
LL | if let [ref mut y, ref mut z @ ..] = *x {}
|
- first borrow occurs due to use of `x` in closure
|
-
- first borrow occurs due to use of `x` in closure
LL | };
LL | let r = &x;
| ^^ second borrow occurs here
...
...
src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr
浏览文件 @
08c4fbce
...
...
@@ -59,11 +59,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-closures-two-mut-fail.rs:53:24
|
LL | let c1 = to_fn_mut(|| set(&mut *x.f));
| --
- first borrow occurs due to use of `x` in closure
| --
---
- first borrow occurs due to use of `x` in closure
| |
| first mutable borrow occurs here
LL | let c2 = to_fn_mut(|| set(&mut *x.f));
| ^^
- second borrow occurs due to use of `x` in closure
| ^^
---
- second borrow occurs due to use of `x` in closure
| |
| second mutable borrow occurs here
LL |
...
...
src/test/ui/borrowck/borrowck-closures-two-mut.stderr
浏览文件 @
08c4fbce
...
...
@@ -59,11 +59,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-closures-two-mut.rs:49:24
|
LL | let c1 = to_fn_mut(|| set(&mut *x.f));
| --
- first borrow occurs due to use of `x` in closure
| --
---
- first borrow occurs due to use of `x` in closure
| |
| first mutable borrow occurs here
LL | let c2 = to_fn_mut(|| set(&mut *x.f));
| ^^
- second borrow occurs due to use of `x` in closure
| ^^
---
- second borrow occurs due to use of `x` in closure
| |
| second mutable borrow occurs here
LL |
...
...
src/test/ui/borrowck/borrowck-closures-unique.stderr
浏览文件 @
08c4fbce
src/test/ui/borrowck/borrowck-closures-use-after-free.stderr
浏览文件 @
08c4fbce
src/test/ui/borrowck/borrowck-insert-during-each.stderr
浏览文件 @
08c4fbce
...
...
@@ -9,7 +9,7 @@ LL | |
LL | | |a| {
| | --- closure construction occurs here
LL | | f.n.insert(*a);
| | - first borrow occurs due to use of `f` in closure
| | -
--
first borrow occurs due to use of `f` in closure
LL | | })
| |__________^ second borrow occurs here
...
...
@@ -24,7 +24,7 @@ LL |
LL | |a| {
| ^^^ closure construction occurs here
LL | f.n.insert(*a);
| - second borrow occurs due to use of `f` in closure
| -
--
second borrow occurs due to use of `f` in closure
error: aborting due to 2 previous errors
...
...
src/test/ui/borrowck/borrowck-loan-blocks-move-cc.stderr
浏览文件 @
08c4fbce
...
...
@@ -7,7 +7,7 @@ LL | thread::spawn(move|| {
| ^^^^^^ move out of `v` occurs here
LL |
LL | println!("v={}", *v);
|
- move occurs due to use in closure
|
-
- move occurs due to use in closure
LL | });
LL | w.use_ref();
| - borrow later used here
...
...
@@ -21,7 +21,7 @@ LL | thread::spawn(move|| {
| ^^^^^^ move out of `v` occurs here
LL |
LL | println!("v={}", *v);
|
- move occurs due to use in closure
|
-
- move occurs due to use in closure
LL | });
LL | w.use_ref();
| - borrow later used here
...
...
src/test/ui/borrowck/borrowck-loan-rcvr.stderr
浏览文件 @
08c4fbce
...
...
@@ -7,7 +7,7 @@ LL | p.blockm(|| {
| | immutable borrow later used by call
| immutable borrow occurs here
LL | p.x = 10;
| - second borrow occurs due to use of `p` in closure
| -
--
second borrow occurs due to use of `p` in closure
error[E0502]: cannot borrow `p` as immutable because it is also borrowed as mutable
--> $DIR/borrowck-loan-rcvr.rs:34:5
...
...
src/test/ui/borrowck/borrowck-move-by-capture.stderr
浏览文件 @
08c4fbce
...
...
@@ -5,7 +5,7 @@ LL | let bar: Box<_> = box 3;
| --- captured outer variable
LL | let _g = to_fn_mut(|| {
LL | let _h = to_fn_once(move || -> isize { *bar });
| ^^^^^^^^^^^^^^^^
---
| ^^^^^^^^^^^^^^^^
-
---
| | |
| | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
| | move occurs due to use in closure
...
...
src/test/ui/borrowck/borrowck-move-moved-value-into-closure.stderr
浏览文件 @
08c4fbce
...
...
@@ -5,11 +5,11 @@ LL | let t: Box<_> = box 3;
| - move occurs because `t` has type `Box<isize>`, which does not implement the `Copy` trait
LL |
LL | call_f(move|| { *t + 1 });
| ------
- variable moved due to use in closure
| ------
-
- variable moved due to use in closure
| |
| value moved into closure here
LL | call_f(move|| { *t + 1 });
| ^^^^^^
- use occurs due to use in closure
| ^^^^^^
-
- use occurs due to use in closure
| |
| value used here after move
...
...
src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr
浏览文件 @
08c4fbce
...
...
@@ -5,7 +5,7 @@ LL | match x {
| - value is immutable in match guard
...
LL | (|| { *x = None; drop(force_fn_once); })();
| ^^
- borrow occurs due to use of `x` in closure
| ^^
-
- borrow occurs due to use of `x` in closure
| |
| cannot mutably borrow
...
...
src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr
浏览文件 @
08c4fbce
...
...
@@ -2,7 +2,7 @@ error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern g
--> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:12:25
|
LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
| ^^
- mutable borrow occurs due to use of `r` in closure
| ^^
-
- mutable borrow occurs due to use of `r` in closure
| |
| cannot borrow as mutable
|
...
...
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.rs
0 → 100644
浏览文件 @
08c4fbce
#![feature(capture_disjoint_fields)]
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
#[derive(Debug)]
struct
Point
{
x
:
i32
,
y
:
i32
,
}
fn
main
()
{
let
mut
p
=
Point
{
x
:
1
,
y
:
2
};
let
y
=
&
mut
p
.y
;
let
mut
c
=
||
{
//~^ ERROR cannot borrow `p` as mutable more than once at a time
let
x
=
&
mut
p
.x
;
println!
(
"{:?}"
,
p
);
};
c
();
*
y
+=
1
;
}
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-1.stderr
0 → 100644
浏览文件 @
08c4fbce
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/borrowck-1.rs:1:12
|
LL | #![feature(capture_disjoint_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
error[E0499]: cannot borrow `p` as mutable more than once at a time
--> $DIR/borrowck-1.rs:13:17
|
LL | let y = &mut p.y;
| -------- first mutable borrow occurs here
LL | let mut c = || {
| ^^ second mutable borrow occurs here
LL |
LL | let x = &mut p.x;
| --- capture is mutable because of use here
LL | println!("{:?}", p);
| - second borrow occurs due to use of `p` in closure
...
LL | *y+=1;
| ----- first borrow later used here
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0499`.
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.rs
0 → 100644
浏览文件 @
08c4fbce
#![feature(capture_disjoint_fields)]
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
#[derive(Debug)]
struct
Point
{
x
:
i32
,
y
:
i32
,
}
fn
main
()
{
let
mut
p
=
Point
{
x
:
1
,
y
:
2
};
let
y
=
&
p
.y
;
let
mut
c
=
||
{
//~^ ERROR cannot borrow `p` as mutable because it is also borrowed as immutable
println!
(
"{:?}"
,
p
);
let
x
=
&
mut
p
.x
;
};
c
();
println!
(
"{}"
,
y
);
}
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-2.stderr
0 → 100644
浏览文件 @
08c4fbce
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/borrowck-2.rs:1:12
|
LL | #![feature(capture_disjoint_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-2.rs:13:17
|
LL | let y = &p.y;
| ---- immutable borrow occurs here
LL | let mut c = || {
| ^^ mutable borrow occurs here
LL |
LL | println!("{:?}", p);
| - second borrow occurs due to use of `p` in closure
LL | let x = &mut p.x;
| --- capture is mutable because of use here
...
LL | println!("{}", y);
| - immutable borrow later used here
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0502`.
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.rs
0 → 100644
浏览文件 @
08c4fbce
#![feature(capture_disjoint_fields)]
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
#[derive(Debug)]
struct
Point
{
x
:
String
,
y
:
String
,
}
fn
main
()
{
let
mut
c
=
{
let
mut
p
=
Point
{
x
:
"1"
.to_string
(),
y
:
"2"
.to_string
()
};
||
{
let
x
=
&
mut
p
.x
;
println!
(
"{:?}"
,
p
);
//~^ ERROR `p` does not live long enough
}
};
c
();
}
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-3.stderr
0 → 100644
浏览文件 @
08c4fbce
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/borrowck-3.rs:1:12
|
LL | #![feature(capture_disjoint_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
error[E0597]: `p` does not live long enough
--> $DIR/borrowck-3.rs:14:29
|
LL | let mut c = {
| ----- borrow later stored here
LL | let mut p = Point {x: "1".to_string(), y: "2".to_string() };
LL | || {
| -- value captured here
LL | let x = &mut p.x;
LL | println!("{:?}", p);
| ^ borrowed value does not live long enough
...
LL | };
| - `p` dropped here while still borrowed
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0597`.
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
0 → 100644
浏览文件 @
08c4fbce
#![feature(capture_disjoint_fields)]
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
#[derive(Debug)]
struct
Point
{
x
:
i32
,
y
:
i32
,
}
fn
foo
()
->
impl
FnMut
()
->
()
{
let
mut
p
=
Point
{
x
:
1
,
y
:
2
};
let
mut
c
=
||
{
//~^ ERROR closure may outlive the current function, but it borrows `p`
p
.x
+=
5
;
println!
(
"{:?}"
,
p
);
};
c
}
fn
main
()
{
let
c
=
foo
();
c
();
}
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
0 → 100644
浏览文件 @
08c4fbce
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/borrowck-4.rs:1:12
|
LL | #![feature(capture_disjoint_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
error[E0373]: closure may outlive the current function, but it borrows `p`, which is owned by the current function
--> $DIR/borrowck-4.rs:11:17
|
LL | let mut c = || {
| ^^ may outlive borrowed value `p`
...
LL | println!("{:?}", p);
| - `p` is borrowed here
|
note: closure is returned here
--> $DIR/borrowck-4.rs:9:14
|
LL | fn foo () -> impl FnMut()->() {
| ^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `p` (and any other referenced variables), use the `move` keyword
|
LL | let mut c = move || {
| ^^^^^^^
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0373`.
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.rs
0 → 100644
浏览文件 @
08c4fbce
// Tests that two closures cannot simultaneously have mutable
// and immutable access to the variable. Issue #6801.
#![feature(capture_disjoint_fields)]
//~^ WARNING: the feature `capture_disjoint_fields` is incomplete
#![feature(box_syntax)]
#[derive(Debug)]
struct
Point
{
x
:
i32
,
y
:
i32
,
}
fn
a
()
{
let
mut
p
=
Point
{
x
:
3
,
y
:
4
};
let
c2
=
||
p
.y
*
5
;
let
c1
=
||
{
//~^ ERROR cannot borrow `p` as mutable because it is also borrowed as immutable
dbg!
(
&
p
);
p
.x
=
4
;
};
drop
(
c2
);
}
fn
main
()
{
}
src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-closures-mut-and-imm.stderr
0 → 100644
浏览文件 @
08c4fbce
warning: the feature `capture_disjoint_fields` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/borrowck-closures-mut-and-imm.rs:4:12
|
LL | #![feature(capture_disjoint_fields)]
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
error[E0502]: cannot borrow `p` as mutable because it is also borrowed as immutable
--> $DIR/borrowck-closures-mut-and-imm.rs:17:14
|
LL | let c2 = || p.y * 5;
| -- --- first borrow occurs due to use of `p.y` in closure
| |
| immutable borrow occurs here
LL | let c1 = || {
| ^^ mutable borrow occurs here
LL |
LL | dbg!(&p);
| - second borrow occurs due to use of `p` in closure
LL | p.x = 4;
| --- capture is mutable because of use here
LL | };
LL | drop(c2);
| -- immutable borrow later used here
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0502`.
src/test/ui/closures/2229_closure_analysis/diagnostics/box.stderr
浏览文件 @
08c4fbce
...
...
@@ -13,7 +13,7 @@ error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
LL | let mut c = || {
| -- borrow of `e.0.0.m.x` occurs here
LL | e.0.0.m.x = format!("not-x");
| - borrow occurs due to use in closure
| -
--------
borrow occurs due to use in closure
...
LL | e.0.0.m.x = format!("not-x");
| ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
...
...
@@ -27,7 +27,7 @@ error[E0502]: cannot borrow `e.0.0.m.x` as immutable because it is also borrowed
LL | let mut c = || {
| -- mutable borrow occurs here
LL | e.0.0.m.x = format!("not-x");
| - first borrow occurs due to use of `e.0.0.m.x` in closure
| -
--------
first borrow occurs due to use of `e.0.0.m.x` in closure
...
LL | println!("{}", e.0.0.m.x);
| ^^^^^^^^^ immutable borrow occurs here
...
...
@@ -41,7 +41,7 @@ error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed
LL | let c = || {
| -- borrow of `e.0.0.m.x` occurs here
LL | println!("{}", e.0.0.m.x);
| - borrow occurs due to use in closure
| -
--------
borrow occurs due to use in closure
...
LL | e.0.0.m.x = format!("not-x");
| ^^^^^^^^^ assignment to borrowed `e.0.0.m.x` occurs here
...
...
src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm-borrow.stderr
浏览文件 @
08c4fbce
...
...
@@ -14,7 +14,7 @@ LL | let mut c = || {
| ^^ cannot borrow as mutable
LL |
LL | z.0.0.0 = format!("X1");
| - mutable borrow occurs due to use of `z.0.0.0` in closure
| -
------
mutable borrow occurs due to use of `z.0.0.0` in closure
error: aborting due to previous error; 1 warning emitted
...
...
src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.rs
浏览文件 @
08c4fbce
...
...
@@ -11,7 +11,7 @@ fn mut_error_struct() {
let
mut
c
=
||
{
z
.0.0.0
=
20
;
//~^ ERROR: cannot assign to `z`, as it is not declared as mutable
//~^ ERROR: cannot assign to `z
.0.0.0
`, as it is not declared as mutable
};
c
();
...
...
@@ -23,7 +23,7 @@ fn mut_error_box() {
let
mut
c
=
||
{
bx
.0
=
20
;
//~^ ERROR: cannot assign to `
bx
`, as it is not declared as mutable
//~^ ERROR: cannot assign to `
*bx.0
`, as it is not declared as mutable
};
c
();
...
...
src/test/ui/closures/2229_closure_analysis/diagnostics/cant-mutate-imm.stderr
浏览文件 @
08c4fbce
...
...
@@ -7,7 +7,7 @@ LL | #![feature(capture_disjoint_fields)]
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #53488 <https://github.com/rust-lang/rust/issues/53488> for more information
error[E0594]: cannot assign to `z`, as it is not declared as mutable
error[E0594]: cannot assign to `z
.0.0.0
`, as it is not declared as mutable
--> $DIR/cant-mutate-imm.rs:13:9
|
LL | let z = (y, 10);
...
...
@@ -16,7 +16,7 @@ LL | let z = (y, 10);
LL | z.0.0.0 = 20;
| ^^^^^^^^^^^^ cannot assign
error[E0594]: cannot assign to `
bx
`, as it is not declared as mutable
error[E0594]: cannot assign to `
*bx.0
`, as it is not declared as mutable
--> $DIR/cant-mutate-imm.rs:25:9
|
LL | let bx = Box::new(x);
...
...
src/test/ui/closures/2229_closure_analysis/diagnostics/multilevel-path.stderr
浏览文件 @
08c4fbce
...
...
@@ -13,7 +13,7 @@ error[E0499]: cannot borrow `w.p.x` as mutable more than once at a time
LL | let mut c = || {
| -- first mutable borrow occurs here
LL | w.p.x += 20;
| - first borrow occurs due to use of `w.p.x` in closure
| -
----
first borrow occurs due to use of `w.p.x` in closure
...
LL | let py = &mut w.p.x;
| ^^^^^^^^^^ second mutable borrow occurs here
...
...
src/test/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr
浏览文件 @
08c4fbce
...
...
@@ -17,7 +17,7 @@ LL | let c = || {
| ^^ `ref_mref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
LL |
LL | **ref_mref_x = y;
|
---------- mutable borrow occurs due to use of `**ref_mref_x` in closure
|
--
---------- mutable borrow occurs due to use of `**ref_mref_x` in closure
error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference
--> $DIR/mut_ref.rs:27:13
...
...
@@ -26,7 +26,7 @@ LL | let c = || {
| ^^ cannot borrow as mutable
LL |
LL | **mref_ref_x = y;
|
---------- mutable borrow occurs due to use of `**mref_ref_x` in closure
|
--
---------- mutable borrow occurs due to use of `**mref_ref_x` in closure
error: aborting due to 2 previous errors; 1 warning emitted
...
...
src/test/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr
浏览文件 @
08c4fbce
...
...
@@ -13,6 +13,8 @@ error[E0502]: cannot borrow `p` as immutable because it is also borrowed as muta
LL | let mut c = || {
| -- mutable borrow occurs here
LL | p.x += 10;
| --- capture is mutable because of use here
LL | println!("{:?}", p);
| - first borrow occurs due to use of `p` in closure
...
LL | println!("{:?}", p);
...
...
src/test/ui/error-codes/E0504.stderr
浏览文件 @
08c4fbce
...
...
@@ -7,7 +7,7 @@ LL |
LL | let x = move || {
| ^^^^^^^ move out of `fancy_num` occurs here
LL | println!("child function: {}", fancy_num.num);
| --------- move occurs due to use in closure
| ---------
----
move occurs due to use in closure
...
LL | println!("main function: {}", fancy_ref.num);
| ------------- borrow later used here
...
...
src/test/ui/generator/yield-while-ref-reborrowed.stderr
浏览文件 @
08c4fbce
...
...
@@ -4,7 +4,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u
LL | let mut b = || {
| -- generator construction occurs here
LL | let a = &mut *x;
|
- first borrow occurs due to use of `x` in generator
|
-
- first borrow occurs due to use of `x` in generator
...
LL | println!("{}", x);
| ^ second borrow occurs here
...
...
src/test/ui/issues/issue-11192.stderr
浏览文件 @
08c4fbce
src/test/ui/issues/issue-27282-mutate-before-diverging-arm-1.stderr
浏览文件 @
08c4fbce
...
...
@@ -5,7 +5,7 @@ LL | match x {
| - value is immutable in match guard
...
LL | (|| { *x = None; drop(force_fn_once); })();
| ^^
- borrow occurs due to use of `x` in closure
| ^^
-
- borrow occurs due to use of `x` in closure
| |
| cannot mutably borrow
...
...
src/test/ui/issues/issue-27282-mutate-before-diverging-arm-3.stderr
浏览文件 @
08c4fbce
...
...
@@ -5,7 +5,7 @@ LL | match **x {
| --- value is immutable in match guard
...
LL | (|| { *x = &None; drop(force_fn_once); })();
| ^^
- borrow occurs due to use of `x` in closure
| ^^
-
- borrow occurs due to use of `x` in closure
| |
| cannot mutably borrow
...
...
src/test/ui/issues/issue-61623.stderr
浏览文件 @
08c4fbce
...
...
@@ -10,7 +10,7 @@ error[E0502]: cannot borrow `*x.1` as mutable because it is also borrowed as imm
--> $DIR/issue-61623.rs:6:19
|
LL | f2(|| x.0, f1(x.1))
| -- -- -
^^^ mutable borrow occurs here
| -- -- -
--
^^^ mutable borrow occurs here
| | | |
| | | first borrow occurs due to use of `x` in closure
| | immutable borrow occurs here
...
...
src/test/ui/issues/issue-6801.stderr
浏览文件 @
08c4fbce
...
...
@@ -2,7 +2,7 @@ error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/issue-6801.rs:19:13
|
LL | let sq = || { *x * *x };
| --
- borrow occurs due to use in closure
| --
-
- borrow occurs due to use in closure
| |
| borrow of `x` occurs here
LL |
...
...
src/test/ui/nll/closure-access-spans.stderr
浏览文件 @
08c4fbce
...
...
@@ -28,7 +28,7 @@ error[E0500]: closure requires unique access to `x` but it is already borrowed
LL | let r = &mut x;
| ------ borrow occurs here
LL | || *x = 2;
| ^^
- second borrow occurs due to use of `x` in closure
| ^^
-
- second borrow occurs due to use of `x` in closure
| |
| closure construction occurs here
LL | r.use_mut();
...
...
@@ -88,7 +88,7 @@ LL | fn closure_unique_capture_moved(x: &mut String) {
LL | let r = x;
| - value moved here
LL | || *x = String::new();
| ^^
- borrow occurs due to use in closure
| ^^
-
- borrow occurs due to use in closure
| |
| value borrowed here after move
...
...
src/test/ui/nll/closure-borrow-spans.stderr
浏览文件 @
08c4fbce
...
...
@@ -110,7 +110,7 @@ error[E0505]: cannot move out of `x` because it is borrowed
--> $DIR/closure-borrow-spans.rs:65:13
|
LL | let f = || *x = 0;
| --
- borrow occurs due to use in closure
| --
-
- borrow occurs due to use in closure
| |
| borrow of `x` occurs here
LL | let y = x;
...
...
@@ -122,7 +122,7 @@ error[E0501]: cannot borrow `x` as immutable because previous closure requires u
--> $DIR/closure-borrow-spans.rs:71:13
|
LL | let f = || *x = 0;
| --
- first borrow occurs due to use of `x` in closure
| --
-
- first borrow occurs due to use of `x` in closure
| |
| closure construction occurs here
LL | let y = &x;
...
...
@@ -134,7 +134,7 @@ error[E0501]: cannot borrow `x` as mutable because previous closure requires uni
--> $DIR/closure-borrow-spans.rs:77:13
|
LL | let f = || *x = 0;
| --
- first borrow occurs due to use of `x` in closure
| --
-
- first borrow occurs due to use of `x` in closure
| |
| closure construction occurs here
LL | let y = &mut x;
...
...
@@ -143,10 +143,10 @@ LL | f.use_ref();
| - first borrow later used here
error[E0597]: `x` does not live long enough
--> $DIR/closure-borrow-spans.rs:86:1
7
--> $DIR/closure-borrow-spans.rs:86:1
6
|
LL | f = || *x = 0;
| --
^ borrowed value does not live long enough
| --
^
^ borrowed value does not live long enough
| |
| value captured here
LL | }
...
...
@@ -158,7 +158,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed
--> $DIR/closure-borrow-spans.rs:93:5
|
LL | let f = || *x = 0;
| --
- borrow occurs due to use in closure
| --
-
- borrow occurs due to use in closure
| |
| borrow of `*x` occurs here
LL | *x = 1;
...
...
src/test/ui/nll/closure-captures.stderr
浏览文件 @
08c4fbce
...
...
@@ -133,7 +133,7 @@ LL | fn_ref(|| {
LL | | ||
| | ^^ cannot borrow as mutable
LL | | *x = 1;});
| |_________
_
-_____- in this closure
| |_________
-
-_____- in this closure
| |
| mutable borrow occurs due to use of `x` in closure
...
...
@@ -150,7 +150,7 @@ LL | fn_ref(move || {
LL | | ||
| | ^^ cannot borrow as mutable
LL | | *x = 1;});
| |_________
_
-_____- in this closure
| |_________
-
-_____- in this closure
| |
| mutable borrow occurs due to use of `x` in closure
...
...
src/test/ui/nll/closure-use-spans.stderr
浏览文件 @
08c4fbce
...
...
@@ -6,7 +6,7 @@ LL | let y = &x;
LL | x = 0;
| ^^^^^ assignment to borrowed `x` occurs here
LL | || *y;
|
- borrow later captured here by closure
|
-
- borrow later captured here by closure
error[E0506]: cannot assign to `x` because it is borrowed
--> $DIR/closure-use-spans.rs:11:5
...
...
@@ -16,7 +16,7 @@ LL | let y = &mut x;
LL | x = 0;
| ^^^^^ assignment to borrowed `x` occurs here
LL | || *y = 1;
|
- borrow later captured here by closure
|
-
- borrow later captured here by closure
error[E0506]: cannot assign to `x` because it is borrowed
--> $DIR/closure-use-spans.rs:17:5
...
...
src/test/ui/nll/closures-in-loops.stderr
浏览文件 @
08c4fbce
...
...
@@ -21,7 +21,7 @@ error[E0524]: two closures require unique access to `x` at the same time
--> $DIR/closures-in-loops.rs:20:16
|
LL | v.push(|| *x = String::new());
| ^^
- borrows occur due to use of `x` in closure
| ^^
-
- borrows occur due to use of `x` in closure
| |
| closures are constructed here in different iterations of loop
...
...
src/test/ui/nll/issue-51268.stderr
浏览文件 @
08c4fbce
...
...
@@ -8,7 +8,7 @@ LL | self.thing.bar(|| {
| |
LL | |
LL | | &self.number;
| | ---- first borrow occurs due to use of `self` in closure
| | ----
-------
first borrow occurs due to use of `self` in closure
LL | | });
| |__________^ mutable borrow occurs here
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录