diff options
| author | bors <bors@rust-lang.org> | 2022-03-05 04:56:35 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-03-05 04:56:35 +0000 |
| commit | be72308b7dfcb83925674b68e280f5f625b3100d (patch) | |
| tree | 8cad004b408f8bf8d3ccd173ac2adb251581045e /compiler | |
| parent | 8c93948d6e9e09abfffc53d0b863ece16cde7286 (diff) | |
| parent | e8a0a4e2affe1897ac09255735d3ce3b8d89d5fa (diff) | |
| download | rust-be72308b7dfcb83925674b68e280f5f625b3100d.tar.gz rust-be72308b7dfcb83925674b68e280f5f625b3100d.zip | |
Auto merge of #94634 - Dylan-DPC:rollup-8wx1yrj, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #94446 (UNIX `remove_dir_all()`: Try recursing first on the slow path) - #94460 (Reenable generator drop tracking tests and fix mutation handling) - #94620 (Edit docs on consistency of `PartialOrd` and `PartialEq`) - #94624 (Downgrade `#[test]` on macro call to warning) - #94626 (Add known-bug directive to issue #47511 test case) - #94631 (Fix typo in c-variadic) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
3 files changed, 46 insertions, 22 deletions
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index e658631d090..0c2d20b8f2d 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -105,14 +105,18 @@ pub fn expand_test_or_bench( // Note: non-associated fn items are already handled by `expand_test_or_bench` if !matches!(item.kind, ast::ItemKind::Fn(_)) { - cx.sess - .parse_sess - .span_diagnostic - .struct_span_err( - attr_sp, - "the `#[test]` attribute may only be used on a non-associated function", - ) - .note("the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions") + let diag = &cx.sess.parse_sess.span_diagnostic; + let msg = "the `#[test]` attribute may only be used on a non-associated function"; + let mut err = match item.kind { + // These were a warning before #92959 and need to continue being that to avoid breaking + // stable user code (#94508). + ast::ItemKind::MacCall(_) => diag.struct_span_warn(attr_sp, msg), + // `.forget_guarantee()` needed to get these two arms to match types. Because of how + // locally close the `.emit()` call is I'm comfortable with it, but if it can be + // reworked in the future to not need it, it'd be nice. + _ => diag.struct_span_err(attr_sp, msg).forget_guarantee(), + }; + err.span_label(attr_sp, "the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions") .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr())) .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", String::from("#[cfg(test)]"), Applicability::MaybeIncorrect) .emit(); diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs index 03d3b23bb23..40ee6d863b5 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -6,14 +6,14 @@ use crate::{ use hir::{def_id::DefId, Body, HirId, HirIdMap}; use rustc_data_structures::stable_set::FxHashSet; use rustc_hir as hir; -use rustc_middle::hir::map::Map; +use rustc_middle::ty::{ParamEnv, TyCtxt}; pub(super) fn find_consumed_and_borrowed<'a, 'tcx>( fcx: &'a FnCtxt<'a, 'tcx>, def_id: DefId, body: &'tcx Body<'tcx>, ) -> ConsumedAndBorrowedPlaces { - let mut expr_use_visitor = ExprUseDelegate::new(fcx.tcx.hir()); + let mut expr_use_visitor = ExprUseDelegate::new(fcx.tcx, fcx.param_env); expr_use_visitor.consume_body(fcx, def_id, body); expr_use_visitor.places } @@ -36,14 +36,16 @@ pub(super) struct ConsumedAndBorrowedPlaces { /// Interesting values are those that are either dropped or borrowed. For dropped values, we also /// record the parent expression, which is the point where the drop actually takes place. struct ExprUseDelegate<'tcx> { - hir: Map<'tcx>, + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, places: ConsumedAndBorrowedPlaces, } impl<'tcx> ExprUseDelegate<'tcx> { - fn new(hir: Map<'tcx>) -> Self { + fn new(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self { Self { - hir, + tcx, + param_env, places: ConsumedAndBorrowedPlaces { consumed: <_>::default(), borrowed: <_>::default(), @@ -77,7 +79,7 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>, diag_expr_id: HirId, ) { - let parent = match self.hir.find_parent_node(place_with_id.hir_id) { + let parent = match self.tcx.hir().find_parent_node(place_with_id.hir_id) { Some(parent) => parent, None => place_with_id.hir_id, }; @@ -107,11 +109,22 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>, diag_expr_id: HirId, ) { - debug!("mutate {:?}; diag_expr_id={:?}", assignee_place, diag_expr_id); - // Count mutations as a borrow. - self.places - .borrowed - .insert(TrackedValue::from_place_with_projections_allowed(assignee_place)); + debug!("mutate {assignee_place:?}; diag_expr_id={diag_expr_id:?}"); + // If the type being assigned needs dropped, then the mutation counts as a borrow + // since it is essentially doing `Drop::drop(&mut x); x = new_value;`. + if assignee_place.place.base_ty.needs_drop(self.tcx, self.param_env) { + self.places + .borrowed + .insert(TrackedValue::from_place_with_projections_allowed(assignee_place)); + } + } + + fn bind( + &mut self, + binding_place: &expr_use_visitor::PlaceWithHirId<'tcx>, + diag_expr_id: HirId, + ) { + debug!("bind {binding_place:?}; diag_expr_id={diag_expr_id:?}"); } fn fake_read( diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index db1c80ae433..8c19bbd3214 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -51,6 +51,15 @@ pub trait Delegate<'tcx> { /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId); + /// The path at `binding_place` is a binding that is being initialized. + /// + /// This covers cases such as `let x = 42;` + fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + // Bindings can normally be treated as a regular assignment, so by default we + // forward this to the mutate callback. + self.mutate(binding_place, diag_expr_id) + } + /// The `place` should be a fake read because of specified `cause`. fn fake_read(&mut self, place: Place<'tcx>, cause: FakeReadCause, diag_expr_id: hir::HirId); } @@ -648,11 +657,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { let pat_ty = return_if_err!(mc.node_ty(pat.hir_id)); debug!("walk_pat: pat_ty={:?}", pat_ty); - // Each match binding is effectively an assignment to the - // binding being produced. let def = Res::Local(canonical_id); if let Ok(ref binding_place) = mc.cat_res(pat.hir_id, pat.span, pat_ty, def) { - delegate.mutate(binding_place, binding_place.hir_id); + delegate.bind(binding_place, binding_place.hir_id); } // It is also a borrow or copy/move of the value being matched. |
