Dont show variables from desugarings in borrowck errors
This commit is contained in:
parent
50a0defd5a
commit
ebd6c7164e
9 changed files with 112 additions and 32 deletions
|
@ -915,6 +915,13 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` is the local is from a compiler desugaring, e.g.,
|
||||||
|
/// `__next` from a `for` loop.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_compiler_desugaring(&self) -> bool {
|
||||||
|
self.source_info.span.compiler_desugaring_kind().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new `LocalDecl` for a temporary.
|
/// Creates a new `LocalDecl` for a temporary.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self {
|
pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self {
|
||||||
|
|
|
@ -1760,15 +1760,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
|
/// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
|
||||||
/// a name, then `Err` is returned
|
/// a name, or its name was generated by the compiler, then `Err` is returned
|
||||||
fn append_local_to_string(&self, local_index: Local, buf: &mut String) -> Result<(), ()> {
|
fn append_local_to_string(&self, local_index: Local, buf: &mut String) -> Result<(), ()> {
|
||||||
let local = &self.mir.local_decls[local_index];
|
let local = &self.mir.local_decls[local_index];
|
||||||
match local.name {
|
match local.name {
|
||||||
Some(name) => {
|
Some(name) if !local.from_compiler_desugaring() => {
|
||||||
buf.push_str(&name.to_string());
|
buf.push_str(name.as_str().get());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
None => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -420,28 +420,31 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(name) = local_decl.name {
|
match local_decl.name {
|
||||||
err.span_label(
|
Some(name) if !local_decl.from_compiler_desugaring() => {
|
||||||
span,
|
err.span_label(
|
||||||
format!(
|
span,
|
||||||
"`{NAME}` is a `{SIGIL}` {DESC}, \
|
format!(
|
||||||
so the data it refers to cannot be {ACTED_ON}",
|
"`{NAME}` is a `{SIGIL}` {DESC}, \
|
||||||
NAME = name,
|
so the data it refers to cannot be {ACTED_ON}",
|
||||||
SIGIL = pointer_sigil,
|
NAME = name,
|
||||||
DESC = pointer_desc,
|
SIGIL = pointer_sigil,
|
||||||
ACTED_ON = acted_on
|
DESC = pointer_desc,
|
||||||
),
|
ACTED_ON = acted_on
|
||||||
);
|
),
|
||||||
} else {
|
);
|
||||||
err.span_label(
|
}
|
||||||
span,
|
_ => {
|
||||||
format!(
|
err.span_label(
|
||||||
"cannot {ACT} through `{SIGIL}` {DESC}",
|
span,
|
||||||
ACT = act,
|
format!(
|
||||||
SIGIL = pointer_sigil,
|
"cannot {ACT} through `{SIGIL}` {DESC}",
|
||||||
DESC = pointer_desc
|
ACT = act,
|
||||||
),
|
SIGIL = pointer_sigil,
|
||||||
);
|
DESC = pointer_desc
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl BorrowExplanation {
|
||||||
};
|
};
|
||||||
|
|
||||||
match local_decl.name {
|
match local_decl.name {
|
||||||
Some(local_name) => {
|
Some(local_name) if !local_decl.from_compiler_desugaring() => {
|
||||||
let message = format!(
|
let message = format!(
|
||||||
"{B}borrow might be used here, when `{LOC}` is dropped \
|
"{B}borrow might be used here, when `{LOC}` is dropped \
|
||||||
and runs the {DTOR} for {TYPE}",
|
and runs the {DTOR} for {TYPE}",
|
||||||
|
@ -130,7 +130,7 @@ impl BorrowExplanation {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
_ => {
|
||||||
err.span_label(
|
err.span_label(
|
||||||
local_decl.source_info.span,
|
local_decl.source_info.span,
|
||||||
format!(
|
format!(
|
||||||
|
|
|
@ -8423,6 +8423,8 @@ impl<'a> Parser<'a> {
|
||||||
for (index, input) in decl.inputs.iter_mut().enumerate() {
|
for (index, input) in decl.inputs.iter_mut().enumerate() {
|
||||||
let id = ast::DUMMY_NODE_ID;
|
let id = ast::DUMMY_NODE_ID;
|
||||||
let span = input.pat.span;
|
let span = input.pat.span;
|
||||||
|
let desugared_span = self.sess.source_map()
|
||||||
|
.mark_span_with_reason(CompilerDesugaringKind::Async, span, None);
|
||||||
|
|
||||||
// Construct a name for our temporary argument.
|
// Construct a name for our temporary argument.
|
||||||
let name = format!("__arg{}", index);
|
let name = format!("__arg{}", index);
|
||||||
|
@ -8439,8 +8441,7 @@ impl<'a> Parser<'a> {
|
||||||
// this would affect the input to procedural macros, but they can have
|
// this would affect the input to procedural macros, but they can have
|
||||||
// their span marked as being the result of a compiler desugaring so
|
// their span marked as being the result of a compiler desugaring so
|
||||||
// that they aren't linted against.
|
// that they aren't linted against.
|
||||||
input.pat.span = self.sess.source_map().mark_span_with_reason(
|
input.pat.span = desugared_span;
|
||||||
CompilerDesugaringKind::Async, span, None);
|
|
||||||
|
|
||||||
(binding_mode, ident, true)
|
(binding_mode, ident, true)
|
||||||
}
|
}
|
||||||
|
@ -8460,7 +8461,7 @@ impl<'a> Parser<'a> {
|
||||||
node: PatKind::Ident(
|
node: PatKind::Ident(
|
||||||
BindingMode::ByValue(Mutability::Immutable), ident, None,
|
BindingMode::ByValue(Mutability::Immutable), ident, None,
|
||||||
),
|
),
|
||||||
span,
|
span: desugared_span,
|
||||||
}),
|
}),
|
||||||
source: ArgSource::AsyncFn(input.pat.clone()),
|
source: ArgSource::AsyncFn(input.pat.clone()),
|
||||||
})
|
})
|
||||||
|
@ -8473,7 +8474,7 @@ impl<'a> Parser<'a> {
|
||||||
pat: P(Pat {
|
pat: P(Pat {
|
||||||
id,
|
id,
|
||||||
node: PatKind::Ident(binding_mode, ident, None),
|
node: PatKind::Ident(binding_mode, ident, None),
|
||||||
span,
|
span: desugared_span,
|
||||||
}),
|
}),
|
||||||
// We explicitly do not specify the type for this statement. When the user's
|
// We explicitly do not specify the type for this statement. When the user's
|
||||||
// argument type is `impl Trait` then this would require the
|
// argument type is `impl Trait` then this would require the
|
||||||
|
|
9
src/test/ui/nll/dont-print-desugared-async.rs
Normal file
9
src/test/ui/nll/dont-print-desugared-async.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// Test that we don't show variables with from async fn desugaring
|
||||||
|
|
||||||
|
// edition:2018
|
||||||
|
#![feature(async_await)]
|
||||||
|
|
||||||
|
async fn async_fn(&ref mut s: &[i32]) {}
|
||||||
|
//~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
|
||||||
|
|
||||||
|
fn main() {}
|
12
src/test/ui/nll/dont-print-desugared-async.stderr
Normal file
12
src/test/ui/nll/dont-print-desugared-async.stderr
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0596]: cannot borrow data in a `&` reference as mutable
|
||||||
|
--> $DIR/dont-print-desugared-async.rs:6:20
|
||||||
|
|
|
||||||
|
LL | async fn async_fn(&ref mut s: &[i32]) {}
|
||||||
|
| -^^^^^^^^^
|
||||||
|
| ||
|
||||||
|
| |cannot borrow as mutable through `&` reference
|
||||||
|
| help: consider changing this to be a mutable reference: `&mut ref mut s`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0596`.
|
21
src/test/ui/nll/dont-print-desugared.rs
Normal file
21
src/test/ui/nll/dont-print-desugared.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Test that we don't show variables with from for loop desugaring
|
||||||
|
|
||||||
|
fn for_loop(s: &[i32]) {
|
||||||
|
for &ref mut x in s {}
|
||||||
|
//~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct D<'a>(&'a ());
|
||||||
|
|
||||||
|
impl Drop for D<'_> {
|
||||||
|
fn drop(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn for_loop_dropck(v: Vec<D<'static>>) {
|
||||||
|
for ref mut d in v {
|
||||||
|
let y = ();
|
||||||
|
*d = D(&y); //~ ERROR `y` does not live long enough
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
27
src/test/ui/nll/dont-print-desugared.stderr
Normal file
27
src/test/ui/nll/dont-print-desugared.stderr
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
error[E0596]: cannot borrow data in a `&` reference as mutable
|
||||||
|
--> $DIR/dont-print-desugared.rs:4:10
|
||||||
|
|
|
||||||
|
LL | for &ref mut x in s {}
|
||||||
|
| -^^^^^^^^^
|
||||||
|
| ||
|
||||||
|
| |cannot borrow as mutable through `&` reference
|
||||||
|
| help: consider changing this to be a mutable reference: `&mut ref mut x`
|
||||||
|
|
||||||
|
error[E0597]: `y` does not live long enough
|
||||||
|
--> $DIR/dont-print-desugared.rs:17:16
|
||||||
|
|
|
||||||
|
LL | for ref mut d in v {
|
||||||
|
| - a temporary with access to the borrow is created here ...
|
||||||
|
LL | let y = ();
|
||||||
|
LL | *d = D(&y);
|
||||||
|
| ^^ borrowed value does not live long enough
|
||||||
|
LL | }
|
||||||
|
| -
|
||||||
|
| |
|
||||||
|
| `y` dropped here while still borrowed
|
||||||
|
| ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0596, E0597.
|
||||||
|
For more information about an error, try `rustc --explain E0596`.
|
Loading…
Add table
Add a link
Reference in a new issue