mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Rollup merge of #135147 - compiler-errors:borrowck-tweaks, r=chenyukang
A few borrowck tweaks to improve 2024 edition migration lints See first two commits' changes to test outputs. Test coverage in this area is kinda weak, but I think it affects more cases than this (like the craters that will begin to trigger the `tail_expr_drop_order` tests in #134523). Third commit is a drive-by change that removes a deref hack from `UseSpans` which doesn't really improve diagnostics much.
This commit is contained in:
commit
ee6914a45b
@ -17,6 +17,7 @@ use rustc_middle::mir::{
|
|||||||
};
|
};
|
||||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
||||||
|
use rustc_middle::util::CallKind;
|
||||||
use rustc_span::{DesugaringKind, Span, Symbol, kw, sym};
|
use rustc_span::{DesugaringKind, Span, Symbol, kw, sym};
|
||||||
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
@ -635,6 +636,39 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
|||||||
// Used in a closure.
|
// Used in a closure.
|
||||||
(LaterUseKind::ClosureCapture, capture_kind_span, Some(path_span))
|
(LaterUseKind::ClosureCapture, capture_kind_span, Some(path_span))
|
||||||
}
|
}
|
||||||
|
// In the case that the borrowed value (probably a temporary)
|
||||||
|
// overlaps with the method's receiver, then point at the method.
|
||||||
|
UseSpans::FnSelfUse {
|
||||||
|
var_span: span,
|
||||||
|
kind: CallKind::Normal { desugaring: None, .. },
|
||||||
|
..
|
||||||
|
} if span
|
||||||
|
.overlaps(self.body.local_decls[borrow.assigned_place.local].source_info.span) =>
|
||||||
|
{
|
||||||
|
if let TerminatorKind::Call { func, call_source: CallSource::Normal, .. } =
|
||||||
|
&self.body.basic_blocks[location.block].terminator().kind
|
||||||
|
{
|
||||||
|
// Just point to the function, to reduce the chance of overlapping spans.
|
||||||
|
let function_span = match func {
|
||||||
|
Operand::Constant(c) => c.span,
|
||||||
|
Operand::Copy(place) | Operand::Move(place) => {
|
||||||
|
if let Some(l) = place.as_local() {
|
||||||
|
let local_decl = &self.body.local_decls[l];
|
||||||
|
if self.local_names[l].is_none() {
|
||||||
|
local_decl.source_info.span
|
||||||
|
} else {
|
||||||
|
span
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
span
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(LaterUseKind::Call, function_span, None)
|
||||||
|
} else {
|
||||||
|
(LaterUseKind::Other, span, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
UseSpans::PatUse(span)
|
UseSpans::PatUse(span)
|
||||||
| UseSpans::OtherUse(span)
|
| UseSpans::OtherUse(span)
|
||||||
| UseSpans::FnSelfUse { var_span: span, .. } => {
|
| UseSpans::FnSelfUse { var_span: span, .. } => {
|
||||||
|
@ -661,9 +661,6 @@ impl UseSpans<'_> {
|
|||||||
UseSpans::ClosureUse { args_span: span, .. }
|
UseSpans::ClosureUse { args_span: span, .. }
|
||||||
| UseSpans::PatUse(span)
|
| UseSpans::PatUse(span)
|
||||||
| UseSpans::OtherUse(span) => span,
|
| UseSpans::OtherUse(span) => span,
|
||||||
UseSpans::FnSelfUse { fn_call_span, kind: CallKind::DerefCoercion { .. }, .. } => {
|
|
||||||
fn_call_span
|
|
||||||
}
|
|
||||||
UseSpans::FnSelfUse { var_span, .. } => var_span,
|
UseSpans::FnSelfUse { var_span, .. } => var_span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -674,9 +671,6 @@ impl UseSpans<'_> {
|
|||||||
UseSpans::ClosureUse { path_span: span, .. }
|
UseSpans::ClosureUse { path_span: span, .. }
|
||||||
| UseSpans::PatUse(span)
|
| UseSpans::PatUse(span)
|
||||||
| UseSpans::OtherUse(span) => span,
|
| UseSpans::OtherUse(span) => span,
|
||||||
UseSpans::FnSelfUse { fn_call_span, kind: CallKind::DerefCoercion { .. }, .. } => {
|
|
||||||
fn_call_span
|
|
||||||
}
|
|
||||||
UseSpans::FnSelfUse { var_span, .. } => var_span,
|
UseSpans::FnSelfUse { var_span, .. } => var_span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -687,9 +681,6 @@ impl UseSpans<'_> {
|
|||||||
UseSpans::ClosureUse { capture_kind_span: span, .. }
|
UseSpans::ClosureUse { capture_kind_span: span, .. }
|
||||||
| UseSpans::PatUse(span)
|
| UseSpans::PatUse(span)
|
||||||
| UseSpans::OtherUse(span) => span,
|
| UseSpans::OtherUse(span) => span,
|
||||||
UseSpans::FnSelfUse { fn_call_span, kind: CallKind::DerefCoercion { .. }, .. } => {
|
|
||||||
fn_call_span
|
|
||||||
}
|
|
||||||
UseSpans::FnSelfUse { var_span, .. } => var_span,
|
UseSpans::FnSelfUse { var_span, .. } => var_span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,26 +17,29 @@ pub fn find_self_call<'tcx>(
|
|||||||
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
|
debug!("find_self_call(local={:?}): terminator={:?}", local, body[block].terminator);
|
||||||
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
if let Some(Terminator { kind: TerminatorKind::Call { func, args, .. }, .. }) =
|
||||||
&body[block].terminator
|
&body[block].terminator
|
||||||
|
&& let Operand::Constant(box ConstOperand { const_, .. }) = func
|
||||||
|
&& let ty::FnDef(def_id, fn_args) = *const_.ty().kind()
|
||||||
|
&& let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
||||||
|
tcx.opt_associated_item(def_id)
|
||||||
|
&& let [Spanned { node: Operand::Move(self_place) | Operand::Copy(self_place), .. }, ..] =
|
||||||
|
**args
|
||||||
{
|
{
|
||||||
debug!("find_self_call: func={:?}", func);
|
if self_place.as_local() == Some(local) {
|
||||||
if let Operand::Constant(box ConstOperand { const_, .. }) = func {
|
return Some((def_id, fn_args));
|
||||||
if let ty::FnDef(def_id, fn_args) = *const_.ty().kind() {
|
}
|
||||||
if let Some(ty::AssocItem { fn_has_self_parameter: true, .. }) =
|
|
||||||
tcx.opt_associated_item(def_id)
|
// Handle the case where `self_place` gets reborrowed.
|
||||||
{
|
// This happens when the receiver is `&T`.
|
||||||
debug!("find_self_call: args={:?}", fn_args);
|
for stmt in &body[block].statements {
|
||||||
if let [
|
if let StatementKind::Assign(box (place, rvalue)) = &stmt.kind
|
||||||
Spanned {
|
&& let Some(reborrow_local) = place.as_local()
|
||||||
node: Operand::Move(self_place) | Operand::Copy(self_place), ..
|
&& self_place.as_local() == Some(reborrow_local)
|
||||||
},
|
&& let Rvalue::Ref(_, _, deref_place) = rvalue
|
||||||
..,
|
&& let PlaceRef { local: deref_local, projection: [ProjectionElem::Deref] } =
|
||||||
] = **args
|
deref_place.as_ref()
|
||||||
{
|
&& deref_local == local
|
||||||
if self_place.as_local() == Some(local) {
|
{
|
||||||
return Some((def_id, fn_args));
|
return Some((def_id, fn_args));
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,10 @@ error[E0716]: temporary value dropped while borrowed
|
|||||||
--> $DIR/tail-expr-in-nested-expr.rs:4:15
|
--> $DIR/tail-expr-in-nested-expr.rs:4:15
|
||||||
|
|
|
|
||||||
LL | let _ = { String::new().as_str() }.len();
|
LL | let _ = { String::new().as_str() }.len();
|
||||||
| ^^^^^^^^^^^^^---------
|
| ^^^^^^^^^^^^^ - --- borrow later used by call
|
||||||
| | |
|
| | |
|
||||||
| | temporary value is freed at the end of this statement
|
| | temporary value is freed at the end of this statement
|
||||||
| creates a temporary value which is freed while still in use
|
| creates a temporary value which is freed while still in use
|
||||||
| borrow later used here
|
|
||||||
|
|
|
|
||||||
= note: consider using a `let` binding to create a longer lived value
|
= note: consider using a `let` binding to create a longer lived value
|
||||||
|
|
||||||
|
@ -75,10 +75,15 @@ warning: taking a mutable reference to a `const` item
|
|||||||
--> $DIR/lint-const-item-mutation.rs:42:5
|
--> $DIR/lint-const-item-mutation.rs:42:5
|
||||||
|
|
|
|
||||||
LL | (&mut MY_STRUCT).use_mut();
|
LL | (&mut MY_STRUCT).use_mut();
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: each usage of a `const` item creates a new temporary
|
= note: each usage of a `const` item creates a new temporary
|
||||||
= note: the mutable reference will refer to this temporary, not the original `const` item
|
= note: the mutable reference will refer to this temporary, not the original `const` item
|
||||||
|
note: mutable reference created due to call to this method
|
||||||
|
--> $DIR/lint-const-item-mutation.rs:9:5
|
||||||
|
|
|
||||||
|
LL | fn use_mut(&mut self) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
note: `const` item defined here
|
note: `const` item defined here
|
||||||
--> $DIR/lint-const-item-mutation.rs:27:1
|
--> $DIR/lint-const-item-mutation.rs:27:1
|
||||||
|
|
|
|
||||||
|
@ -4,7 +4,7 @@ error[E0382]: borrow of partially moved value: `val`
|
|||||||
LL | let _val = val.first;
|
LL | let _val = val.first;
|
||||||
| --------- value partially moved here
|
| --------- value partially moved here
|
||||||
LL | val.inner;
|
LL | val.inner;
|
||||||
| ^^^^^^^^^ value borrowed here after partial move
|
| ^^^ value borrowed here after partial move
|
||||||
|
|
|
|
||||||
= note: partial move occurs because `val.first` has type `NotCopy`, which does not implement the `Copy` trait
|
= note: partial move occurs because `val.first` has type `NotCopy`, which does not implement the `Copy` trait
|
||||||
= note: borrow occurs due to deref coercion to `NotCopy`
|
= note: borrow occurs due to deref coercion to `NotCopy`
|
||||||
@ -20,7 +20,7 @@ error[E0382]: borrow of partially moved value: `val`
|
|||||||
LL | let _val = val.first;
|
LL | let _val = val.first;
|
||||||
| --------- value partially moved here
|
| --------- value partially moved here
|
||||||
LL | val.inner_method();
|
LL | val.inner_method();
|
||||||
| ^^^^^^^^^^^^^^^^^^ value borrowed here after partial move
|
| ^^^ value borrowed here after partial move
|
||||||
|
|
|
|
||||||
= note: partial move occurs because `val.first` has type `NotCopy`, which does not implement the `Copy` trait
|
= note: partial move occurs because `val.first` has type `NotCopy`, which does not implement the `Copy` trait
|
||||||
= note: borrow occurs due to deref coercion to `NotCopy`
|
= note: borrow occurs due to deref coercion to `NotCopy`
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0382]: borrow of moved value: `arc_v`
|
error[E0382]: borrow of moved value: `arc_v`
|
||||||
--> $DIR/no-capture-arc.rs:14:16
|
--> $DIR/no-capture-arc.rs:14:18
|
||||||
|
|
|
|
||||||
LL | let arc_v = Arc::new(v);
|
LL | let arc_v = Arc::new(v);
|
||||||
| ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
|
| ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
|
||||||
@ -10,7 +10,7 @@ LL | assert_eq!((*arc_v)[3], 4);
|
|||||||
| ----- variable moved due to use in closure
|
| ----- variable moved due to use in closure
|
||||||
...
|
...
|
||||||
LL | assert_eq!((*arc_v)[2], 3);
|
LL | assert_eq!((*arc_v)[2], 3);
|
||||||
| ^^^^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
|
||||||
= note: borrow occurs due to deref coercion to `Vec<i32>`
|
= note: borrow occurs due to deref coercion to `Vec<i32>`
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0382]: borrow of moved value: `arc_v`
|
error[E0382]: borrow of moved value: `arc_v`
|
||||||
--> $DIR/no-reuse-move-arc.rs:12:16
|
--> $DIR/no-reuse-move-arc.rs:12:18
|
||||||
|
|
|
|
||||||
LL | let arc_v = Arc::new(v);
|
LL | let arc_v = Arc::new(v);
|
||||||
| ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
|
| ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
|
||||||
@ -10,7 +10,7 @@ LL | assert_eq!((*arc_v)[3], 4);
|
|||||||
| ----- variable moved due to use in closure
|
| ----- variable moved due to use in closure
|
||||||
...
|
...
|
||||||
LL | assert_eq!((*arc_v)[2], 3);
|
LL | assert_eq!((*arc_v)[2], 3);
|
||||||
| ^^^^^^^^ value borrowed here after move
|
| ^^^^^ value borrowed here after move
|
||||||
|
|
|
|
||||||
= note: borrow occurs due to deref coercion to `Vec<i32>`
|
= note: borrow occurs due to deref coercion to `Vec<i32>`
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user