Skip to content

Commit 1c69947

Browse files
Try to explain borrow for tail expr temporary drop order change in 2024
1 parent 16d16b0 commit 1c69947

9 files changed

+82
-35
lines changed

Diff for: compiler/rustc_borrowck/messages.ftl

+3-2
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ borrowck_suggest_create_fresh_reborrow =
213213
borrowck_suggest_iterate_over_slice =
214214
consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop
215215
216-
borrowck_tail_expr_drop_order = a temporary value will be dropped here before the execution exits the block in Edition 2024, which will raise borrow checking error
217-
.label = consider using a `let` binding to create a longer lived value; or replacing the `{"{"} .. {"}"}` block with curly brackets `( .. )`; or folding the rest of the expression into the surrounding `unsafe {"{"} .. {"}"}`
216+
borrowck_tail_expr_drop_order = relative drop order changing in Rust 2024
217+
.label = this temporary value will be dropped at the end of the block
218+
.note = consider using a `let` binding to ensure the value will live long enough
218219
219220
borrowck_ty_no_impl_copy =
220221
{$is_partial_move ->

Diff for: compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
use std::assert_matches::assert_matches;
77

8-
use rustc_errors::{Applicability, Diag};
8+
use rustc_errors::{Applicability, Diag, EmissionGuarantee};
99
use rustc_hir as hir;
1010
use rustc_hir::intravisit::Visitor;
1111
use rustc_index::IndexSlice;
@@ -61,12 +61,12 @@ impl<'tcx> BorrowExplanation<'tcx> {
6161
pub(crate) fn is_explained(&self) -> bool {
6262
!matches!(self, BorrowExplanation::Unexplained)
6363
}
64-
pub(crate) fn add_explanation_to_diagnostic(
64+
pub(crate) fn add_explanation_to_diagnostic<G: EmissionGuarantee>(
6565
&self,
6666
tcx: TyCtxt<'tcx>,
6767
body: &Body<'tcx>,
6868
local_names: &IndexSlice<Local, Option<Symbol>>,
69-
err: &mut Diag<'_>,
69+
err: &mut Diag<'_, G>,
7070
borrow_desc: &str,
7171
borrow_span: Option<Span>,
7272
multiple_borrow_span: Option<(Span, Span)>,
@@ -349,10 +349,10 @@ impl<'tcx> BorrowExplanation<'tcx> {
349349
}
350350
}
351351

352-
fn add_object_lifetime_default_note(
352+
fn add_object_lifetime_default_note<G: EmissionGuarantee>(
353353
&self,
354354
tcx: TyCtxt<'tcx>,
355-
err: &mut Diag<'_>,
355+
err: &mut Diag<'_, G>,
356356
unsize_ty: Ty<'tcx>,
357357
) {
358358
if let ty::Adt(def, args) = unsize_ty.kind() {
@@ -406,9 +406,9 @@ impl<'tcx> BorrowExplanation<'tcx> {
406406
}
407407
}
408408

409-
fn add_lifetime_bound_suggestion_to_diagnostic(
409+
fn add_lifetime_bound_suggestion_to_diagnostic<G: EmissionGuarantee>(
410410
&self,
411-
err: &mut Diag<'_>,
411+
err: &mut Diag<'_, G>,
412412
category: &ConstraintCategory<'tcx>,
413413
span: Span,
414414
region_name: &RegionName,
@@ -435,14 +435,14 @@ impl<'tcx> BorrowExplanation<'tcx> {
435435
}
436436
}
437437

438-
fn suggest_rewrite_if_let(
438+
fn suggest_rewrite_if_let<G: EmissionGuarantee>(
439439
tcx: TyCtxt<'_>,
440440
expr: &hir::Expr<'_>,
441441
pat: &str,
442442
init: &hir::Expr<'_>,
443443
conseq: &hir::Expr<'_>,
444444
alt: Option<&hir::Expr<'_>>,
445-
err: &mut Diag<'_>,
445+
err: &mut Diag<'_, G>,
446446
) {
447447
let source_map = tcx.sess.source_map();
448448
err.span_note(

Diff for: compiler/rustc_borrowck/src/diagnostics/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
992992
kind,
993993
};
994994
}
995+
995996
normal_ret
996997
}
997998

Diff for: compiler/rustc_borrowck/src/diagnostics/region_name.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::fmt::{self, Display};
55
use std::iter;
66

77
use rustc_data_structures::fx::IndexEntry;
8-
use rustc_errors::Diag;
8+
use rustc_errors::{Diag, EmissionGuarantee};
99
use rustc_hir as hir;
1010
use rustc_hir::def::{DefKind, Res};
1111
use rustc_middle::ty::print::RegionHighlightMode;
@@ -108,7 +108,7 @@ impl RegionName {
108108
}
109109
}
110110

111-
pub(crate) fn highlight_region_name(&self, diag: &mut Diag<'_>) {
111+
pub(crate) fn highlight_region_name<G: EmissionGuarantee>(&self, diag: &mut Diag<'_, G>) {
112112
match &self.source {
113113
RegionNameSource::NamedLateParamRegion(span)
114114
| RegionNameSource::NamedEarlyParamRegion(span) => {

Diff for: compiler/rustc_borrowck/src/lib.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::ops::Deref;
2323
use rustc_abi::FieldIdx;
2424
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
2525
use rustc_data_structures::graph::dominators::Dominators;
26+
use rustc_errors::LintDiagnostic;
2627
use rustc_hir as hir;
2728
use rustc_hir::CRATE_HIR_ID;
2829
use rustc_hir::def_id::LocalDefId;
@@ -1195,11 +1196,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
11951196
return Control::Continue;
11961197
}
11971198
let borrowed = this.retrieve_borrow_spans(borrow).var_or_use_path_span();
1198-
this.infcx.tcx.emit_node_span_lint(
1199+
let explain = this.explain_why_borrow_contains_point(
1200+
location,
1201+
borrow,
1202+
Some((WriteKind::StorageDeadOrDrop, place)),
1203+
);
1204+
this.infcx.tcx.node_span_lint(
11991205
TAIL_EXPR_DROP_ORDER,
12001206
CRATE_HIR_ID,
1201-
place_span,
1202-
session_diagnostics::TailExprDropOrder { borrowed },
1207+
borrowed,
1208+
|diag| {
1209+
session_diagnostics::TailExprDropOrder { borrowed }.decorate_lint(diag);
1210+
explain.add_explanation_to_diagnostic(
1211+
tcx,
1212+
this.body,
1213+
&this.local_names,
1214+
diag,
1215+
"",
1216+
None,
1217+
None,
1218+
);
1219+
},
12031220
);
12041221
// We may stop at the first case
12051222
Control::Break

Diff for: tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-abort.mir

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ fn method_1(_1: Guard) -> () {
7474

7575
bb7: {
7676
backward incompatible drop(_2);
77+
backward incompatible drop(_4);
7778
backward incompatible drop(_5);
7879
goto -> bb21;
7980
}

Diff for: tests/mir-opt/tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.panic-unwind.mir

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ fn method_1(_1: Guard) -> () {
7474

7575
bb7: {
7676
backward incompatible drop(_2);
77+
backward incompatible drop(_4);
7778
backward incompatible drop(_5);
7879
goto -> bb21;
7980
}

Diff for: tests/ui/drop/lint-tail-expr-drop-order-borrowck.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77

88
fn should_lint_with_potential_borrowck_err() {
99
let _ = { String::new().as_str() }.len();
10-
//~^ ERROR: a temporary value will be dropped here
10+
//~^ ERROR: relative drop order changing
1111
//~| WARN: this changes meaning in Rust 2024
12-
//~| NOTE: consider using a `let` binding
12+
//~| NOTE: this temporary value will be dropped at the end of the block
13+
//~| borrow later used by call
1314
//~| NOTE: for more information, see
1415
}
1516

1617
fn should_lint_with_unsafe_block() {
1718
fn f(_: usize) {}
1819
f(unsafe { String::new().as_str() }.len());
19-
//~^ ERROR: a temporary value will be dropped here
20+
//~^ ERROR: relative drop order changing
2021
//~| WARN: this changes meaning in Rust 2024
21-
//~| NOTE: consider using a `let` binding
22+
//~| NOTE: this temporary value will be dropped at the end of the block
23+
//~| borrow later used by call
2224
//~| NOTE: for more information, see
2325
}
2426

@@ -27,11 +29,23 @@ fn should_lint_with_big_block() {
2729
fn f<T>(_: T) {}
2830
f({
2931
&mut || 0
30-
//~^ ERROR: a temporary value will be dropped here
32+
//~^ ERROR: relative drop order changing
3133
//~| WARN: this changes meaning in Rust 2024
32-
//~| NOTE: consider using a `let` binding
34+
//~| NOTE: this temporary value will be dropped at the end of the block
35+
//~| borrow later used here
3336
//~| NOTE: for more information, see
3437
})
3538
}
3639

40+
fn another_temp_that_is_copy_in_arg() {
41+
fn f() {}
42+
fn g(_: &()) {}
43+
g({ &f() });
44+
//~^ ERROR: relative drop order changing
45+
//~| WARN: this changes meaning in Rust 2024
46+
//~| NOTE: this temporary value will be dropped at the end of the block
47+
//~| borrow later used by call
48+
//~| NOTE: for more information, see
49+
}
50+
3751
fn main() {}
+25-13
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error: a temporary value will be dropped here before the execution exits the block in Edition 2024, which will raise borrow checking error
2-
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:9:36
1+
error: relative drop order changing in Rust 2024
2+
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:9:15
33
|
44
LL | let _ = { String::new().as_str() }.len();
5-
| ------------- ^
5+
| ^^^^^^^^^^^^^ --- borrow later used by call
66
| |
7-
| consider using a `let` binding to create a longer lived value; or replacing the `{ .. }` block with curly brackets `( .. )`; or folding the rest of the expression into the surrounding `unsafe { .. }`
7+
| this temporary value will be dropped at the end of the block
88
|
99
= warning: this changes meaning in Rust 2024
1010
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
@@ -14,27 +14,39 @@ note: the lint level is defined here
1414
LL | #![deny(tail_expr_drop_order)]
1515
| ^^^^^^^^^^^^^^^^^^^^
1616

17-
error: a temporary value will be dropped here before the execution exits the block in Edition 2024, which will raise borrow checking error
18-
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:18:37
17+
error: relative drop order changing in Rust 2024
18+
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:19:16
1919
|
2020
LL | f(unsafe { String::new().as_str() }.len());
21-
| ------------- ^
21+
| ^^^^^^^^^^^^^ --- borrow later used by call
2222
| |
23-
| consider using a `let` binding to create a longer lived value; or replacing the `{ .. }` block with curly brackets `( .. )`; or folding the rest of the expression into the surrounding `unsafe { .. }`
23+
| this temporary value will be dropped at the end of the block
2424
|
2525
= warning: this changes meaning in Rust 2024
2626
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
2727

28-
error: a temporary value will be dropped here before the execution exits the block in Edition 2024, which will raise borrow checking error
29-
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:29:17
28+
error: relative drop order changing in Rust 2024
29+
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:31:9
3030
|
3131
LL | &mut || 0
32-
| --------^
32+
| ^^^^^^^^^
3333
| |
34-
| consider using a `let` binding to create a longer lived value; or replacing the `{ .. }` block with curly brackets `( .. )`; or folding the rest of the expression into the surrounding `unsafe { .. }`
34+
| this temporary value will be dropped at the end of the block
35+
| borrow later used here
3536
|
3637
= warning: this changes meaning in Rust 2024
3738
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
3839

39-
error: aborting due to 3 previous errors
40+
error: relative drop order changing in Rust 2024
41+
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:43:9
42+
|
43+
LL | g({ &f() });
44+
| - ^^^^ this temporary value will be dropped at the end of the block
45+
| |
46+
| borrow later used by call
47+
|
48+
= warning: this changes meaning in Rust 2024
49+
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
50+
51+
error: aborting due to 4 previous errors
4052

0 commit comments

Comments
 (0)