Skip to content

Commit 08ec439

Browse files
reduce false positives of tail-expr-drop-order from consumed values
1 parent 8ed95d1 commit 08ec439

File tree

37 files changed

+801
-373
lines changed

37 files changed

+801
-373
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4090,6 +4090,7 @@ dependencies = [
40904090
"rustc_hir",
40914091
"rustc_index",
40924092
"rustc_infer",
4093+
"rustc_lint",
40934094
"rustc_macros",
40944095
"rustc_middle",
40954096
"rustc_mir_build",

compiler/rustc_borrowck/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
690690
TerminatorKind::SwitchInt { discr, targets: _ } => {
691691
self.consume_operand(loc, (discr, span), state);
692692
}
693-
TerminatorKind::Drop { place, target: _, unwind: _, replace } => {
693+
TerminatorKind::Drop { place, target: _, scope: _, unwind: _, replace } => {
694694
debug!(
695695
"visit_terminator_drop \
696696
loc: {:?} term: {:?} place: {:?} span: {:?}",

compiler/rustc_borrowck/src/polonius/loan_invalidations.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
103103
TerminatorKind::SwitchInt { discr, targets: _ } => {
104104
self.consume_operand(location, discr);
105105
}
106-
TerminatorKind::Drop { place: drop_place, target: _, unwind: _, replace } => {
106+
TerminatorKind::Drop { place: drop_place, target: _, scope: _, unwind: _, replace } => {
107107
let write_kind =
108108
if *replace { WriteKind::Replace } else { WriteKind::StorageDeadOrDrop };
109109
self.access_place(

compiler/rustc_codegen_cranelift/src/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
549549
| TerminatorKind::CoroutineDrop => {
550550
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
551551
}
552-
TerminatorKind::Drop { place, target, unwind: _, replace: _ } => {
552+
TerminatorKind::Drop { place, target, unwind: _, scope: _, replace: _ } => {
553553
let drop_place = codegen_place(fx, *place);
554554
crate::abi::codegen_drop(fx, source_info, drop_place, *target);
555555
}

compiler/rustc_codegen_ssa/src/mir/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13221322
MergingSucc::False
13231323
}
13241324

1325-
mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => self
1325+
mir::TerminatorKind::Drop { place, target, unwind, scope: _, replace: _ } => self
13261326
.codegen_drop_terminator(
13271327
helper,
13281328
bx,

compiler/rustc_const_eval/src/interpret/step.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
528528
}
529529
}
530530

531-
Drop { place, target, unwind, replace: _ } => {
531+
Drop { place, target, unwind, scope: _, replace: _ } => {
532532
let place = self.eval_place(place)?;
533533
let instance = Instance::resolve_drop_in_place(*self.tcx, place.layout.ty);
534534
if let ty::InstanceKind::DropGlue(_, None) = instance.def {

compiler/rustc_hir_typeck/src/expr_use_visitor.rs

+44
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,50 @@ pub trait TypeInformationCtxt<'tcx> {
150150
fn tcx(&self) -> TyCtxt<'tcx>;
151151
}
152152

153+
impl<'tcx> TypeInformationCtxt<'tcx> for (TyCtxt<'tcx>, LocalDefId) {
154+
type TypeckResults<'a> = &'tcx ty::TypeckResults<'tcx>
155+
where
156+
Self: 'a;
157+
158+
type Error = !;
159+
160+
fn typeck_results(&self) -> Self::TypeckResults<'_> {
161+
self.0.typeck(self.1)
162+
}
163+
164+
fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
165+
t
166+
}
167+
168+
fn try_structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
169+
ty
170+
}
171+
172+
fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error {
173+
span_bug!(span, "{}", msg.to_string())
174+
}
175+
176+
fn error_reported_in_ty(&self, _ty: Ty<'tcx>) -> Result<(), Self::Error> {
177+
Ok(())
178+
}
179+
180+
fn tainted_by_errors(&self) -> Result<(), Self::Error> {
181+
Ok(())
182+
}
183+
184+
fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
185+
ty.is_copy_modulo_regions(self.0, self.0.param_env(self.1))
186+
}
187+
188+
fn body_owner_def_id(&self) -> LocalDefId {
189+
self.1
190+
}
191+
192+
fn tcx(&self) -> TyCtxt<'tcx> {
193+
self.0
194+
}
195+
}
196+
153197
impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
154198
type TypeckResults<'a> = Ref<'a, ty::TypeckResults<'tcx>>
155199
where

compiler/rustc_hir_typeck/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mod fallback;
3030
mod fn_ctxt;
3131
mod gather_locals;
3232
mod intrinsicck;
33+
mod lint;
3334
mod method;
3435
mod op;
3536
mod pat;
@@ -506,5 +507,6 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! {
506507

507508
pub fn provide(providers: &mut Providers) {
508509
method::provide(providers);
510+
lint::provide(providers);
509511
*providers = Providers { typeck, diagnostic_only_typeck, used_trait_imports, ..*providers };
510512
}

compiler/rustc_hir_typeck/src/lint.rs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use rustc_hir::def_id::DefId;
2+
use rustc_hir::{HirId, HirIdSet};
3+
use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId};
4+
use rustc_middle::mir::FakeReadCause;
5+
use rustc_middle::query::Providers;
6+
use rustc_middle::ty::{self, TyCtxt};
7+
use tracing::instrument;
8+
9+
use crate::expr_use_visitor::{Delegate, ExprUseVisitor};
10+
11+
#[derive(Default)]
12+
struct ExtractConsumingNodeDelegate {
13+
nodes: HirIdSet,
14+
}
15+
16+
impl<'tcx> Delegate<'tcx> for ExtractConsumingNodeDelegate {
17+
#[instrument(level = "debug", skip(self))]
18+
fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, _: HirId) {
19+
match place_with_id.place.base {
20+
PlaceBase::Rvalue => {
21+
self.nodes.insert(place_with_id.hir_id);
22+
}
23+
PlaceBase::Local(id) => {
24+
self.nodes.insert(id);
25+
}
26+
PlaceBase::Upvar(upvar) => {
27+
self.nodes.insert(upvar.var_path.hir_id);
28+
}
29+
PlaceBase::StaticItem => {}
30+
}
31+
}
32+
33+
fn borrow(
34+
&mut self,
35+
_place_with_id: &PlaceWithHirId<'tcx>,
36+
_diag_expr_id: HirId,
37+
_bk: ty::BorrowKind,
38+
) {
39+
// do nothing
40+
}
41+
42+
fn mutate(&mut self, _assignee_place: &PlaceWithHirId<'tcx>, _diag_expr_id: HirId) {
43+
// do nothing
44+
}
45+
46+
fn fake_read(
47+
&mut self,
48+
_place_with_id: &PlaceWithHirId<'tcx>,
49+
_cause: FakeReadCause,
50+
_diag_expr_id: HirId,
51+
) {
52+
// do nothing
53+
}
54+
}
55+
56+
fn extract_tail_expr_consuming_nodes<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx HirIdSet {
57+
let hir = tcx.hir();
58+
let body = hir.body_owned_by(def_id.expect_local());
59+
let mut delegate = ExtractConsumingNodeDelegate::default();
60+
let euv = ExprUseVisitor::new((tcx, def_id.expect_local()), &mut delegate);
61+
let _ = euv.walk_expr(body.value);
62+
tcx.arena.alloc(delegate.nodes)
63+
}
64+
65+
pub(crate) fn provide(providers: &mut Providers) {
66+
providers.extract_tail_expr_consuming_nodes = extract_tail_expr_consuming_nodes;
67+
}

compiler/rustc_lint/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -789,9 +789,6 @@ lint_suspicious_double_ref_clone =
789789
lint_suspicious_double_ref_deref =
790790
using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type
791791
792-
lint_tail_expr_drop_order = these values and local bindings have significant drop implementation that will have a different drop order from that of Edition 2021
793-
.label = these values have significant drop implementation and will observe changes in drop order under Edition 2024
794-
795792
lint_trailing_semi_macro = trailing semicolon in macro used in expression position
796793
.note1 = macro invocations at the end of a block are treated as expressions
797794
.note2 = to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}`

compiler/rustc_lint/src/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ mod redundant_semicolon;
8282
mod reference_casting;
8383
mod shadowed_into_iter;
8484
mod static_mut_refs;
85-
mod tail_expr_drop_order;
8685
mod traits;
8786
mod types;
8887
mod unit_bindings;
@@ -122,7 +121,6 @@ use rustc_middle::ty::TyCtxt;
122121
use shadowed_into_iter::ShadowedIntoIter;
123122
pub use shadowed_into_iter::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER};
124123
use static_mut_refs::*;
125-
use tail_expr_drop_order::TailExprDropOrder;
126124
use traits::*;
127125
use types::*;
128126
use unit_bindings::*;
@@ -246,7 +244,6 @@ late_lint_methods!(
246244
AsyncFnInTrait: AsyncFnInTrait,
247245
NonLocalDefinitions: NonLocalDefinitions::default(),
248246
ImplTraitOvercaptures: ImplTraitOvercaptures,
249-
TailExprDropOrder: TailExprDropOrder,
250247
IfLetRescope: IfLetRescope::default(),
251248
StaticMutRefs: StaticMutRefs,
252249
]

0 commit comments

Comments
 (0)