Skip to content

Commit

Permalink
Try to explain borrow for tail expr temporary drop order change in 2024
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jan 6, 2025
1 parent 16d16b0 commit 1c69947
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 35 deletions.
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,9 @@ borrowck_suggest_create_fresh_reborrow =
borrowck_suggest_iterate_over_slice =
consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop
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
.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 {"{"} .. {"}"}`
borrowck_tail_expr_drop_order = relative drop order changing in Rust 2024
.label = this temporary value will be dropped at the end of the block
.note = consider using a `let` binding to ensure the value will live long enough
borrowck_ty_no_impl_copy =
{$is_partial_move ->
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use std::assert_matches::assert_matches;

use rustc_errors::{Applicability, Diag};
use rustc_errors::{Applicability, Diag, EmissionGuarantee};
use rustc_hir as hir;
use rustc_hir::intravisit::Visitor;
use rustc_index::IndexSlice;
Expand Down Expand Up @@ -61,12 +61,12 @@ impl<'tcx> BorrowExplanation<'tcx> {
pub(crate) fn is_explained(&self) -> bool {
!matches!(self, BorrowExplanation::Unexplained)
}
pub(crate) fn add_explanation_to_diagnostic(
pub(crate) fn add_explanation_to_diagnostic<G: EmissionGuarantee>(
&self,
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
local_names: &IndexSlice<Local, Option<Symbol>>,
err: &mut Diag<'_>,
err: &mut Diag<'_, G>,
borrow_desc: &str,
borrow_span: Option<Span>,
multiple_borrow_span: Option<(Span, Span)>,
Expand Down Expand Up @@ -349,10 +349,10 @@ impl<'tcx> BorrowExplanation<'tcx> {
}
}

fn add_object_lifetime_default_note(
fn add_object_lifetime_default_note<G: EmissionGuarantee>(
&self,
tcx: TyCtxt<'tcx>,
err: &mut Diag<'_>,
err: &mut Diag<'_, G>,
unsize_ty: Ty<'tcx>,
) {
if let ty::Adt(def, args) = unsize_ty.kind() {
Expand Down Expand Up @@ -406,9 +406,9 @@ impl<'tcx> BorrowExplanation<'tcx> {
}
}

fn add_lifetime_bound_suggestion_to_diagnostic(
fn add_lifetime_bound_suggestion_to_diagnostic<G: EmissionGuarantee>(
&self,
err: &mut Diag<'_>,
err: &mut Diag<'_, G>,
category: &ConstraintCategory<'tcx>,
span: Span,
region_name: &RegionName,
Expand All @@ -435,14 +435,14 @@ impl<'tcx> BorrowExplanation<'tcx> {
}
}

fn suggest_rewrite_if_let(
fn suggest_rewrite_if_let<G: EmissionGuarantee>(
tcx: TyCtxt<'_>,
expr: &hir::Expr<'_>,
pat: &str,
init: &hir::Expr<'_>,
conseq: &hir::Expr<'_>,
alt: Option<&hir::Expr<'_>>,
err: &mut Diag<'_>,
err: &mut Diag<'_, G>,
) {
let source_map = tcx.sess.source_map();
err.span_note(
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
kind,
};
}

normal_ret
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/region_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::fmt::{self, Display};
use std::iter;

use rustc_data_structures::fx::IndexEntry;
use rustc_errors::Diag;
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_middle::ty::print::RegionHighlightMode;
Expand Down Expand Up @@ -108,7 +108,7 @@ impl RegionName {
}
}

pub(crate) fn highlight_region_name(&self, diag: &mut Diag<'_>) {
pub(crate) fn highlight_region_name<G: EmissionGuarantee>(&self, diag: &mut Diag<'_, G>) {
match &self.source {
RegionNameSource::NamedLateParamRegion(span)
| RegionNameSource::NamedEarlyParamRegion(span) => {
Expand Down
23 changes: 20 additions & 3 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use std::ops::Deref;
use rustc_abi::FieldIdx;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_errors::LintDiagnostic;
use rustc_hir as hir;
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::def_id::LocalDefId;
Expand Down Expand Up @@ -1195,11 +1196,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
return Control::Continue;
}
let borrowed = this.retrieve_borrow_spans(borrow).var_or_use_path_span();
this.infcx.tcx.emit_node_span_lint(
let explain = this.explain_why_borrow_contains_point(
location,
borrow,
Some((WriteKind::StorageDeadOrDrop, place)),
);
this.infcx.tcx.node_span_lint(
TAIL_EXPR_DROP_ORDER,
CRATE_HIR_ID,
place_span,
session_diagnostics::TailExprDropOrder { borrowed },
borrowed,
|diag| {
session_diagnostics::TailExprDropOrder { borrowed }.decorate_lint(diag);
explain.add_explanation_to_diagnostic(
tcx,
this.body,
&this.local_names,
diag,
"",
None,
None,
);
},
);
// We may stop at the first case
Control::Break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ fn method_1(_1: Guard) -> () {

bb7: {
backward incompatible drop(_2);
backward incompatible drop(_4);
backward incompatible drop(_5);
goto -> bb21;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ fn method_1(_1: Guard) -> () {

bb7: {
backward incompatible drop(_2);
backward incompatible drop(_4);
backward incompatible drop(_5);
goto -> bb21;
}
Expand Down
26 changes: 20 additions & 6 deletions tests/ui/drop/lint-tail-expr-drop-order-borrowck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@

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

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

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

fn another_temp_that_is_copy_in_arg() {
fn f() {}
fn g(_: &()) {}
g({ &f() });
//~^ ERROR: relative drop order changing
//~| WARN: this changes meaning in Rust 2024
//~| NOTE: this temporary value will be dropped at the end of the block
//~| borrow later used by call
//~| NOTE: for more information, see
}

fn main() {}
38 changes: 25 additions & 13 deletions tests/ui/drop/lint-tail-expr-drop-order-borrowck.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
error: a temporary value will be dropped here before the execution exits the block in Edition 2024, which will raise borrow checking error
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:9:36
error: relative drop order changing in Rust 2024
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:9:15
|
LL | let _ = { String::new().as_str() }.len();
| ------------- ^
| ^^^^^^^^^^^^^ --- borrow later used by call
| |
| 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 { .. }`
| this temporary value will be dropped at the end of the block
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
Expand All @@ -14,27 +14,39 @@ note: the lint level is defined here
LL | #![deny(tail_expr_drop_order)]
| ^^^^^^^^^^^^^^^^^^^^

error: a temporary value will be dropped here before the execution exits the block in Edition 2024, which will raise borrow checking error
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:18:37
error: relative drop order changing in Rust 2024
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:19:16
|
LL | f(unsafe { String::new().as_str() }.len());
| ------------- ^
| ^^^^^^^^^^^^^ --- borrow later used by call
| |
| 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 { .. }`
| this temporary value will be dropped at the end of the block
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>

error: a temporary value will be dropped here before the execution exits the block in Edition 2024, which will raise borrow checking error
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:29:17
error: relative drop order changing in Rust 2024
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:31:9
|
LL | &mut || 0
| --------^
| ^^^^^^^^^
| |
| 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 { .. }`
| this temporary value will be dropped at the end of the block
| borrow later used here
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>

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

error: aborting due to 4 previous errors

0 comments on commit 1c69947

Please sign in to comment.