Skip to content

Commit be72308

Browse files
committed
Auto merge of rust-lang#94634 - Dylan-DPC:rollup-8wx1yrj, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - rust-lang#94446 (UNIX `remove_dir_all()`: Try recursing first on the slow path) - rust-lang#94460 (Reenable generator drop tracking tests and fix mutation handling) - rust-lang#94620 (Edit docs on consistency of `PartialOrd` and `PartialEq`) - rust-lang#94624 (Downgrade `#[test]` on macro call to warning) - rust-lang#94626 (Add known-bug directive to issue rust-lang#47511 test case) - rust-lang#94631 (Fix typo in c-variadic) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 8c93948 + e8a0a4e commit be72308

File tree

18 files changed

+194
-236
lines changed

18 files changed

+194
-236
lines changed

compiler/rustc_builtin_macros/src/test.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,18 @@ pub fn expand_test_or_bench(
105105

106106
// Note: non-associated fn items are already handled by `expand_test_or_bench`
107107
if !matches!(item.kind, ast::ItemKind::Fn(_)) {
108-
cx.sess
109-
.parse_sess
110-
.span_diagnostic
111-
.struct_span_err(
112-
attr_sp,
113-
"the `#[test]` attribute may only be used on a non-associated function",
114-
)
115-
.note("the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions")
108+
let diag = &cx.sess.parse_sess.span_diagnostic;
109+
let msg = "the `#[test]` attribute may only be used on a non-associated function";
110+
let mut err = match item.kind {
111+
// These were a warning before #92959 and need to continue being that to avoid breaking
112+
// stable user code (#94508).
113+
ast::ItemKind::MacCall(_) => diag.struct_span_warn(attr_sp, msg),
114+
// `.forget_guarantee()` needed to get these two arms to match types. Because of how
115+
// locally close the `.emit()` call is I'm comfortable with it, but if it can be
116+
// reworked in the future to not need it, it'd be nice.
117+
_ => diag.struct_span_err(attr_sp, msg).forget_guarantee(),
118+
};
119+
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")
116120
.span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr()))
117121
.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)
118122
.emit();

compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs

+24-11
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ use crate::{
66
use hir::{def_id::DefId, Body, HirId, HirIdMap};
77
use rustc_data_structures::stable_set::FxHashSet;
88
use rustc_hir as hir;
9-
use rustc_middle::hir::map::Map;
9+
use rustc_middle::ty::{ParamEnv, TyCtxt};
1010

1111
pub(super) fn find_consumed_and_borrowed<'a, 'tcx>(
1212
fcx: &'a FnCtxt<'a, 'tcx>,
1313
def_id: DefId,
1414
body: &'tcx Body<'tcx>,
1515
) -> ConsumedAndBorrowedPlaces {
16-
let mut expr_use_visitor = ExprUseDelegate::new(fcx.tcx.hir());
16+
let mut expr_use_visitor = ExprUseDelegate::new(fcx.tcx, fcx.param_env);
1717
expr_use_visitor.consume_body(fcx, def_id, body);
1818
expr_use_visitor.places
1919
}
@@ -36,14 +36,16 @@ pub(super) struct ConsumedAndBorrowedPlaces {
3636
/// Interesting values are those that are either dropped or borrowed. For dropped values, we also
3737
/// record the parent expression, which is the point where the drop actually takes place.
3838
struct ExprUseDelegate<'tcx> {
39-
hir: Map<'tcx>,
39+
tcx: TyCtxt<'tcx>,
40+
param_env: ParamEnv<'tcx>,
4041
places: ConsumedAndBorrowedPlaces,
4142
}
4243

4344
impl<'tcx> ExprUseDelegate<'tcx> {
44-
fn new(hir: Map<'tcx>) -> Self {
45+
fn new(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
4546
Self {
46-
hir,
47+
tcx,
48+
param_env,
4749
places: ConsumedAndBorrowedPlaces {
4850
consumed: <_>::default(),
4951
borrowed: <_>::default(),
@@ -77,7 +79,7 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
7779
place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
7880
diag_expr_id: HirId,
7981
) {
80-
let parent = match self.hir.find_parent_node(place_with_id.hir_id) {
82+
let parent = match self.tcx.hir().find_parent_node(place_with_id.hir_id) {
8183
Some(parent) => parent,
8284
None => place_with_id.hir_id,
8385
};
@@ -107,11 +109,22 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
107109
assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
108110
diag_expr_id: HirId,
109111
) {
110-
debug!("mutate {:?}; diag_expr_id={:?}", assignee_place, diag_expr_id);
111-
// Count mutations as a borrow.
112-
self.places
113-
.borrowed
114-
.insert(TrackedValue::from_place_with_projections_allowed(assignee_place));
112+
debug!("mutate {assignee_place:?}; diag_expr_id={diag_expr_id:?}");
113+
// If the type being assigned needs dropped, then the mutation counts as a borrow
114+
// since it is essentially doing `Drop::drop(&mut x); x = new_value;`.
115+
if assignee_place.place.base_ty.needs_drop(self.tcx, self.param_env) {
116+
self.places
117+
.borrowed
118+
.insert(TrackedValue::from_place_with_projections_allowed(assignee_place));
119+
}
120+
}
121+
122+
fn bind(
123+
&mut self,
124+
binding_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
125+
diag_expr_id: HirId,
126+
) {
127+
debug!("bind {binding_place:?}; diag_expr_id={diag_expr_id:?}");
115128
}
116129

117130
fn fake_read(

compiler/rustc_typeck/src/expr_use_visitor.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ pub trait Delegate<'tcx> {
5151
/// `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
5252
fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId);
5353

54+
/// The path at `binding_place` is a binding that is being initialized.
55+
///
56+
/// This covers cases such as `let x = 42;`
57+
fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) {
58+
// Bindings can normally be treated as a regular assignment, so by default we
59+
// forward this to the mutate callback.
60+
self.mutate(binding_place, diag_expr_id)
61+
}
62+
5463
/// The `place` should be a fake read because of specified `cause`.
5564
fn fake_read(&mut self, place: Place<'tcx>, cause: FakeReadCause, diag_expr_id: hir::HirId);
5665
}
@@ -648,11 +657,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
648657
let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
649658
debug!("walk_pat: pat_ty={:?}", pat_ty);
650659

651-
// Each match binding is effectively an assignment to the
652-
// binding being produced.
653660
let def = Res::Local(canonical_id);
654661
if let Ok(ref binding_place) = mc.cat_res(pat.hir_id, pat.span, pat_ty, def) {
655-
delegate.mutate(binding_place, binding_place.hir_id);
662+
delegate.bind(binding_place, binding_place.hir_id);
656663
}
657664

658665
// It is also a borrow or copy/move of the value being matched.

library/core/src/cmp.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -885,19 +885,18 @@ impl PartialOrd for Ordering {
885885
/// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using
886886
/// the `<`, `<=`, `>`, and `>=` operators, respectively.
887887
///
888-
/// The methods of this trait must be consistent with each other and with those of `PartialEq` in
889-
/// the following sense:
890-
///
891-
/// - `a == b` if and only if `partial_cmp(a, b) == Some(Equal)`.
892-
/// - `a < b` if and only if `partial_cmp(a, b) == Some(Less)`
893-
/// (ensured by the default implementation).
894-
/// - `a > b` if and only if `partial_cmp(a, b) == Some(Greater)`
895-
/// (ensured by the default implementation).
896-
/// - `a <= b` if and only if `a < b || a == b`
897-
/// (ensured by the default implementation).
898-
/// - `a >= b` if and only if `a > b || a == b`
899-
/// (ensured by the default implementation).
900-
/// - `a != b` if and only if `!(a == b)` (already part of `PartialEq`).
888+
/// The methods of this trait must be consistent with each other and with those of [`PartialEq`].
889+
/// The following conditions must hold:
890+
///
891+
/// 1. `a == b` if and only if `partial_cmp(a, b) == Some(Equal)`.
892+
/// 2. `a < b` if and only if `partial_cmp(a, b) == Some(Less)`
893+
/// 3. `a > b` if and only if `partial_cmp(a, b) == Some(Greater)`
894+
/// 4. `a <= b` if and only if `a < b || a == b`
895+
/// 5. `a >= b` if and only if `a > b || a == b`
896+
/// 6. `a != b` if and only if `!(a == b)`.
897+
///
898+
/// Conditions 2–5 above are ensured by the default implementation.
899+
/// Condition 6 is already ensured by [`PartialEq`].
901900
///
902901
/// If [`Ord`] is also implemented for `Self` and `Rhs`, it must also be consistent with
903902
/// `partial_cmp` (see the documentation of that trait for the exact requirements). It's

0 commit comments

Comments
 (0)