Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a955f1c

Browse files
committed
Auto merge of #144440 - matthiaskrgr:rollup-peb88gb, r=matthiaskrgr
Rollup of 12 pull requests Successful merges: - #142569 (Suggest clone in user-write-code instead of inside macro) - #143401 (tests: Don't check for self-printed output in std-backtrace.rs test) - #143424 (clippy fix: rely on autoderef) - #143970 (Update core::mem::copy documentation) - #143979 (Test fixes for Arm64EC Windows) - #144200 (Tweak output for non-`Clone` values moved into closures) - #144209 (Don't emit two `assume`s in transmutes when one is a subset of the other) - #144314 (Hint that choose_pivot returns index in bounds) - #144340 (UI test suite clarity changes: Rename `tests/ui/SUMMARY.md` and update rustc dev guide on `error-pattern`) - #144368 (resolve: Remove `Scope::CrateRoot`) - #144390 (Remove dead code and extend test coverage and diagnostics around it) - #144392 (rustc_public: Remove movability from `RigidTy/AggregateKind::Coroutine`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents b56aaec + 1caf701 commit a955f1c

File tree

50 files changed

+511
-261
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+511
-261
lines changed

‎compiler/rustc_abi/src/layout.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
313313
scalar_valid_range: (Bound<u128>, Bound<u128>),
314314
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
315315
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
316-
dont_niche_optimize_enum: bool,
317316
always_sized: bool,
318317
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
319318
let (present_first, present_second) = {
@@ -352,13 +351,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
352351
// structs. (We have also handled univariant enums
353352
// that allow representation optimization.)
354353
assert!(is_enum);
355-
self.layout_of_enum(
356-
repr,
357-
variants,
358-
discr_range_of_repr,
359-
discriminants,
360-
dont_niche_optimize_enum,
361-
)
354+
self.layout_of_enum(repr, variants, discr_range_of_repr, discriminants)
362355
}
363356
}
364357

@@ -599,7 +592,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
599592
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
600593
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
601594
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
602-
dont_niche_optimize_enum: bool,
603595
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
604596
// Until we've decided whether to use the tagged or
605597
// niche filling LayoutData, we don't want to intern the
@@ -618,7 +610,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
618610
}
619611

620612
let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx, VariantIdx>> {
621-
if dont_niche_optimize_enum {
613+
if repr.inhibit_enum_layout_opt() {
622614
return None;
623615
}
624616

‎compiler/rustc_abi/src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,28 @@ impl WrappingRange {
13761376
}
13771377
}
13781378

1379+
/// Returns `true` if all the values in `other` are contained in this range,
1380+
/// when the values are considered as having width `size`.
1381+
#[inline(always)]
1382+
pub fn contains_range(&self, other: Self, size: Size) -> bool {
1383+
if self.is_full_for(size) {
1384+
true
1385+
} else {
1386+
let trunc = |x| size.truncate(x);
1387+
1388+
let delta = self.start;
1389+
let max = trunc(self.end.wrapping_sub(delta));
1390+
1391+
let other_start = trunc(other.start.wrapping_sub(delta));
1392+
let other_end = trunc(other.end.wrapping_sub(delta));
1393+
1394+
// Having shifted both input ranges by `delta`, now we only need to check
1395+
// whether `0..=max` contains `other_start..=other_end`, which can only
1396+
// happen if the other doesn't wrap since `self` isn't everything.
1397+
(other_start <= other_end) && (other_end <= max)
1398+
}
1399+
}
1400+
13791401
/// Returns `self` with replaced `start`
13801402
#[inline(always)]
13811403
fn with_start(mut self, start: u128) -> Self {

‎compiler/rustc_abi/src/tests.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,66 @@ fn align_constants() {
55
assert_eq!(Align::ONE, Align::from_bytes(1).unwrap());
66
assert_eq!(Align::EIGHT, Align::from_bytes(8).unwrap());
77
}
8+
9+
#[test]
10+
fn wrapping_range_contains_range() {
11+
let size16 = Size::from_bytes(16);
12+
13+
let a = WrappingRange { start: 10, end: 20 };
14+
assert!(a.contains_range(a, size16));
15+
assert!(a.contains_range(WrappingRange { start: 11, end: 19 }, size16));
16+
assert!(a.contains_range(WrappingRange { start: 10, end: 10 }, size16));
17+
assert!(a.contains_range(WrappingRange { start: 20, end: 20 }, size16));
18+
assert!(!a.contains_range(WrappingRange { start: 10, end: 21 }, size16));
19+
assert!(!a.contains_range(WrappingRange { start: 9, end: 20 }, size16));
20+
assert!(!a.contains_range(WrappingRange { start: 4, end: 6 }, size16));
21+
assert!(!a.contains_range(WrappingRange { start: 24, end: 26 }, size16));
22+
23+
assert!(!a.contains_range(WrappingRange { start: 16, end: 14 }, size16));
24+
25+
let b = WrappingRange { start: 20, end: 10 };
26+
assert!(b.contains_range(b, size16));
27+
assert!(b.contains_range(WrappingRange { start: 20, end: 20 }, size16));
28+
assert!(b.contains_range(WrappingRange { start: 10, end: 10 }, size16));
29+
assert!(b.contains_range(WrappingRange { start: 0, end: 10 }, size16));
30+
assert!(b.contains_range(WrappingRange { start: 20, end: 30 }, size16));
31+
assert!(b.contains_range(WrappingRange { start: 20, end: 9 }, size16));
32+
assert!(b.contains_range(WrappingRange { start: 21, end: 10 }, size16));
33+
assert!(b.contains_range(WrappingRange { start: 999, end: 9999 }, size16));
34+
assert!(b.contains_range(WrappingRange { start: 999, end: 9 }, size16));
35+
assert!(!b.contains_range(WrappingRange { start: 19, end: 19 }, size16));
36+
assert!(!b.contains_range(WrappingRange { start: 11, end: 11 }, size16));
37+
assert!(!b.contains_range(WrappingRange { start: 19, end: 11 }, size16));
38+
assert!(!b.contains_range(WrappingRange { start: 11, end: 19 }, size16));
39+
40+
let f = WrappingRange { start: 0, end: u128::MAX };
41+
assert!(f.contains_range(WrappingRange { start: 10, end: 20 }, size16));
42+
assert!(f.contains_range(WrappingRange { start: 20, end: 10 }, size16));
43+
44+
let g = WrappingRange { start: 2, end: 1 };
45+
assert!(g.contains_range(WrappingRange { start: 10, end: 20 }, size16));
46+
assert!(g.contains_range(WrappingRange { start: 20, end: 10 }, size16));
47+
48+
let size1 = Size::from_bytes(1);
49+
let u8r = WrappingRange { start: 0, end: 255 };
50+
let i8r = WrappingRange { start: 128, end: 127 };
51+
assert!(u8r.contains_range(i8r, size1));
52+
assert!(i8r.contains_range(u8r, size1));
53+
assert!(!u8r.contains_range(i8r, size16));
54+
assert!(i8r.contains_range(u8r, size16));
55+
56+
let boolr = WrappingRange { start: 0, end: 1 };
57+
assert!(u8r.contains_range(boolr, size1));
58+
assert!(i8r.contains_range(boolr, size1));
59+
assert!(!boolr.contains_range(u8r, size1));
60+
assert!(!boolr.contains_range(i8r, size1));
61+
62+
let cmpr = WrappingRange { start: 255, end: 1 };
63+
assert!(u8r.contains_range(cmpr, size1));
64+
assert!(i8r.contains_range(cmpr, size1));
65+
assert!(!cmpr.contains_range(u8r, size1));
66+
assert!(!cmpr.contains_range(i8r, size1));
67+
68+
assert!(!boolr.contains_range(cmpr, size1));
69+
assert!(cmpr.contains_range(boolr, size1));
70+
}

‎compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 83 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
115115
fn append_to_grouped_errors(
116116
&self,
117117
grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
118-
error: MoveError<'tcx>,
118+
MoveError{place: original_path, location, kind }: MoveError<'tcx>,
119119
) {
120-
let MoveError { place: original_path, location, kind } = error;
121-
122120
// Note: that the only time we assign a place isn't a temporary
123121
// to a user variable is when initializing it.
124122
// If that ever stops being the case, then the ever initialized
@@ -251,54 +249,47 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
251249
}
252250

253251
fn report(&mut self, error: GroupedMoveError<'tcx>) {
254-
let (mut err, err_span) = {
255-
let (span, use_spans, original_path, kind) = match error {
256-
GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
257-
| GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
258-
(span, None, original_path, kind)
259-
}
260-
GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
261-
(use_spans.args_or_use(), Some(use_spans), original_path, kind)
262-
}
263-
};
264-
debug!(
265-
"report: original_path={:?} span={:?}, kind={:?} \
266-
original_path.is_upvar_field_projection={:?}",
267-
original_path,
268-
span,
269-
kind,
270-
self.is_upvar_field_projection(original_path.as_ref())
271-
);
272-
if self.has_ambiguous_copy(original_path.ty(self.body, self.infcx.tcx).ty) {
273-
// If the type may implement Copy, skip the error.
274-
// It's an error with the Copy implementation (e.g. duplicate Copy) rather than borrow check
275-
self.dcx().span_delayed_bug(
252+
let (span, use_spans, original_path, kind) = match error {
253+
GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
254+
| GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
255+
(span, None, original_path, kind)
256+
}
257+
GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
258+
(use_spans.args_or_use(), Some(use_spans), original_path, kind)
259+
}
260+
};
261+
debug!(
262+
"report: original_path={:?} span={:?}, kind={:?} \
263+
original_path.is_upvar_field_projection={:?}",
264+
original_path,
265+
span,
266+
kind,
267+
self.is_upvar_field_projection(original_path.as_ref())
268+
);
269+
if self.has_ambiguous_copy(original_path.ty(self.body, self.infcx.tcx).ty) {
270+
// If the type may implement Copy, skip the error.
271+
// It's an error with the Copy implementation (e.g. duplicate Copy) rather than borrow check
272+
self.dcx()
273+
.span_delayed_bug(span, "Type may implement copy, but there is no other error.");
274+
return;
275+
}
276+
let mut err = match kind {
277+
&IllegalMoveOriginKind::BorrowedContent { target_place } => self
278+
.report_cannot_move_from_borrowed_content(
279+
original_path,
280+
target_place,
276281
span,
277-
"Type may implement copy, but there is no other error.",
278-
);
279-
return;
282+
use_spans,
283+
),
284+
&IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
285+
self.cannot_move_out_of_interior_of_drop(span, ty)
286+
}
287+
&IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
288+
self.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index))
280289
}
281-
(
282-
match kind {
283-
&IllegalMoveOriginKind::BorrowedContent { target_place } => self
284-
.report_cannot_move_from_borrowed_content(
285-
original_path,
286-
target_place,
287-
span,
288-
use_spans,
289-
),
290-
&IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
291-
self.cannot_move_out_of_interior_of_drop(span, ty)
292-
}
293-
&IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
294-
self.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index))
295-
}
296-
},
297-
span,
298-
)
299290
};
300291

301-
self.add_move_hints(error, &mut err, err_span);
292+
self.add_move_hints(error, &mut err, span);
302293
self.buffer_error(err);
303294
}
304295

@@ -483,7 +474,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
483474
self.cannot_move_out_of_interior_noncopy(span, ty, None)
484475
}
485476
ty::Closure(def_id, closure_args)
486-
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
477+
if def_id.as_local() == Some(self.mir_def_id())
478+
&& let Some(upvar_field) = upvar_field =>
487479
{
488480
let closure_kind_ty = closure_args.as_closure().kind_ty();
489481
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
@@ -496,7 +488,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
496488
let capture_description =
497489
format!("captured variable in an `{closure_kind}` closure");
498490

499-
let upvar = &self.upvars[upvar_field.unwrap().index()];
491+
let upvar = &self.upvars[upvar_field.index()];
500492
let upvar_hir_id = upvar.get_root_variable();
501493
let upvar_name = upvar.to_string(tcx);
502494
let upvar_span = tcx.hir_span(upvar_hir_id);
@@ -606,7 +598,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
606598
}
607599
// No binding. Nothing to suggest.
608600
GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
609-
let use_span = use_spans.var_or_use();
601+
let mutuse_span = use_spans.var_or_use();
610602
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
611603
let place_desc = match self.describe_place(original_path.as_ref()) {
612604
Some(desc) => format!("`{desc}`"),
@@ -623,19 +615,59 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
623615
);
624616
}
625617

618+
if let Some(upvar_field) = self
619+
.prefixes(original_path.as_ref(), PrefixSet::All)
620+
.find_map(|p| self.is_upvar_field_projection(p))
621+
{
622+
// Look for the introduction of the original binding being moved.
623+
let upvar = &self.upvars[upvar_field.index()];
624+
let upvar_hir_id = upvar.get_root_variable();
625+
use_span = match self.infcx.tcx.parent_hir_node(upvar_hir_id) {
626+
hir::Node::Param(param) => {
627+
// Instead of pointing at the path where we access the value within a
628+
// closure, we point at the type of the outer `fn` argument.
629+
param.ty_span
630+
}
631+
hir::Node::LetStmt(stmt) => match (stmt.ty, stmt.init) {
632+
// We point at the type of the outer let-binding.
633+
(Some(ty), _) => ty.span,
634+
// We point at the initializer of the outer let-binding, but only if it
635+
// isn't something that spans multiple lines, like a closure, as the
636+
// ASCII art gets messy.
637+
(None, Some(init))
638+
if !self.infcx.tcx.sess.source_map().is_multiline(init.span) =>
639+
{
640+
init.span
641+
}
642+
_ => use_span,
643+
},
644+
_ => use_span,
645+
};
646+
}
647+
626648
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
627649
is_partial_move: false,
628650
ty: place_ty,
629651
place: &place_desc,
630652
span: use_span,
631653
});
632654

655+
let mut pointed_at_span = false;
633656
use_spans.args_subdiag(err, |args_span| {
657+
if args_span == span || args_span == use_span {
658+
pointed_at_span = true;
659+
}
634660
crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
635-
place: place_desc,
661+
place: place_desc.clone(),
636662
args_span,
637663
}
638664
});
665+
if !pointed_at_span && use_span != span {
666+
err.subdiagnostic(crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
667+
place: place_desc,
668+
args_span: span,
669+
});
670+
}
639671

640672
self.add_note_for_packed_struct_derive(err, original_path.local);
641673
}

‎compiler/rustc_codegen_ssa/src/mir/rvalue.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
288288
// valid ranges. For example, `char`s are passed as just `i32`, with no
289289
// way for LLVM to know that they're 0x10FFFF at most. Thus we assume
290290
// the range of the input value too, not just the output range.
291-
assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
291+
assume_scalar_range(bx, imm, from_scalar, from_backend_ty,None);
292292

293293
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
294294
(Int(_, is_signed), Int(..)) => bx.intcast(imm, to_backend_ty, is_signed),
@@ -1064,7 +1064,7 @@ pub(super) fn transmute_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
10641064
// That said, last time we tried removing this, it didn't actually help
10651065
// the rustc-perf results, so might as well keep doing it
10661066
// <https://github.com/rust-lang/rust/pull/135610#issuecomment-2599275182>
1067-
assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
1067+
assume_scalar_range(bx, imm, from_scalar, from_backend_ty,Some(&to_scalar));
10681068

10691069
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
10701070
(Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty),
@@ -1092,22 +1092,42 @@ pub(super) fn transmute_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
10921092
// since it's never passed to something with parameter metadata (especially
10931093
// after MIR inlining) so the only way to tell the backend about the
10941094
// constraint that the `transmute` introduced is to `assume` it.
1095-
assume_scalar_range(bx, imm, to_scalar, to_backend_ty);
1095+
assume_scalar_range(bx, imm, to_scalar, to_backend_ty,Some(&from_scalar));
10961096

10971097
imm = bx.to_immediate_scalar(imm, to_scalar);
10981098
imm
10991099
}
11001100

1101+
/// Emits an `assume` call that `imm`'s value is within the known range of `scalar`.
1102+
///
1103+
/// If `known` is `Some`, only emits the assume if it's more specific than
1104+
/// whatever is already known from the range of *that* scalar.
11011105
fn assume_scalar_range<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
11021106
bx: &mut Bx,
11031107
imm: Bx::Value,
11041108
scalar: abi::Scalar,
11051109
backend_ty: Bx::Type,
1110+
known: Option<&abi::Scalar>,
11061111
) {
1107-
if matches!(bx.cx().sess().opts.optimize, OptLevel::No) || scalar.is_always_valid(bx.cx()){
1112+
if matches!(bx.cx().sess().opts.optimize, OptLevel::No) {
11081113
return;
11091114
}
11101115

1116+
match (scalar, known) {
1117+
(abi::Scalar::Union { .. }, _) => return,
1118+
(_, None) => {
1119+
if scalar.is_always_valid(bx.cx()) {
1120+
return;
1121+
}
1122+
}
1123+
(abi::Scalar::Initialized { valid_range, .. }, Some(known)) => {
1124+
let known_range = known.valid_range(bx.cx());
1125+
if valid_range.contains_range(known_range, scalar.size(bx.cx())) {
1126+
return;
1127+
}
1128+
}
1129+
}
1130+
11111131
match scalar.primitive() {
11121132
abi::Primitive::Int(..) => {
11131133
let range = scalar.valid_range(bx.cx());

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /