Skip to content

Commit 956e563

Browse files
committed
Auto merge of rust-lang#140547 - Zalathar:rollup-mvyz11i, r=Zalathar
Rollup of 10 pull requests Successful merges: - rust-lang#134034 (handle paren in macro expand for let-init-else expr) - rust-lang#138703 (chore: remove redundant words in comment) - rust-lang#139186 (Refactor `diy_float`) - rust-lang#139343 (Change signature of File::try_lock and File::try_lock_shared) - rust-lang#139780 (docs: Add example to `Iterator::take` with `by_ref`) - rust-lang#139802 (Fix some grammar errors and hyperlinks in doc for `trait Allocator`) - rust-lang#140034 (simd_select_bitmask: the 'padding' bits in the mask are just ignored) - rust-lang#140062 (std: mention `remove_dir_all` can emit `DirectoryNotEmpty` when concurrently written into) - rust-lang#140485 (Optimize the codegen for `Span::from_expansion`) - rust-lang#140521 (interpret: better error message for out-of-bounds pointer arithmetic and accesses) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0e517d3 + 582dbdd commit 956e563

File tree

106 files changed

+552
-375
lines changed

Some content is hidden

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

106 files changed

+552
-375
lines changed

compiler/rustc_const_eval/messages.ftl

+35-35
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,27 @@ const_eval_already_reported =
1212
const_eval_assume_false =
1313
`assume` called with `false`
1414
15+
const_eval_bad_pointer_op = {$operation ->
16+
[MemoryAccess] memory access failed
17+
[InboundsPointerArithmetic] in-bounds pointer arithmetic failed
18+
*[Dereferenceable] pointer not dereferenceable
19+
}
20+
const_eval_bad_pointer_op_attempting = {const_eval_bad_pointer_op}: {$operation ->
21+
[MemoryAccess] attempting to access {$inbounds_size ->
22+
[1] 1 byte
23+
*[x] {$inbounds_size} bytes
24+
}
25+
[InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
26+
[1] 1 byte
27+
*[x] {$inbounds_size} bytes
28+
}
29+
*[Dereferenceable] pointer must {$inbounds_size ->
30+
[0] point to some allocation
31+
[1] be dereferenceable for 1 byte
32+
*[x] be dereferenceable for {$inbounds_size} bytes
33+
}
34+
}
35+
1536
const_eval_bounds_check_failed =
1637
indexing out of bounds: the len is {$len} but the index is {$index}
1738
const_eval_call_nonzero_intrinsic =
@@ -39,9 +60,9 @@ const_eval_copy_nonoverlapping_overlapping =
3960
`copy_nonoverlapping` called on overlapping ranges
4061
4162
const_eval_dangling_int_pointer =
42-
{$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got {$pointer} which is a dangling pointer (it has no provenance)
63+
{const_eval_bad_pointer_op_attempting}, but got {$pointer} which is a dangling pointer (it has no provenance)
4364
const_eval_dangling_null_pointer =
44-
{$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got a null pointer
65+
{const_eval_bad_pointer_op_attempting}, but got null pointer
4566
4667
const_eval_dangling_ptr_in_final = encountered dangling pointer in final value of {const_eval_intern_kind}
4768
const_eval_dead_local =
@@ -77,21 +98,6 @@ const_eval_error = {$error_kind ->
7798
const_eval_exact_div_has_remainder =
7899
exact_div: {$a} cannot be divided by {$b} without remainder
79100
80-
const_eval_expected_inbounds_pointer =
81-
expected a pointer to {$inbounds_size_abs ->
82-
[0] some allocation
83-
*[x] {$inbounds_size_is_neg ->
84-
[false] {$inbounds_size_abs ->
85-
[1] 1 byte of memory
86-
*[x] {$inbounds_size_abs} bytes of memory
87-
}
88-
*[true] the end of {$inbounds_size_abs ->
89-
[1] 1 byte of memory
90-
*[x] {$inbounds_size_abs} bytes of memory
91-
}
92-
}
93-
}
94-
95101
const_eval_extern_static =
96102
cannot access extern static `{$did}`
97103
const_eval_extern_type_field = `extern type` field does not have a known offset
@@ -111,7 +117,6 @@ const_eval_frame_note_inner = inside {$where_ ->
111117
112118
const_eval_frame_note_last = the failure occurred here
113119
114-
const_eval_in_bounds_test = out-of-bounds pointer use
115120
const_eval_incompatible_calling_conventions =
116121
calling a function with calling convention {$callee_conv} using calling convention {$caller_conv}
117122
@@ -206,7 +211,6 @@ const_eval_long_running =
206211
207212
const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant {$global_const_id}
208213
209-
const_eval_memory_access_test = memory access failed
210214
const_eval_memory_exhausted =
211215
tried to allocate more memory than available to compiler
212216
@@ -287,8 +291,6 @@ const_eval_offset_from_out_of_bounds =
287291
`{$name}` called on two different pointers where the memory range between them is not in-bounds of an allocation
288292
const_eval_offset_from_overflow =
289293
`{$name}` called when first pointer is too far ahead of second
290-
const_eval_offset_from_test =
291-
out-of-bounds `offset_from` origin
292294
const_eval_offset_from_underflow =
293295
`{$name}` called when first pointer is too far before second
294296
const_eval_offset_from_unsigned_overflow =
@@ -312,27 +314,25 @@ const_eval_partial_pointer_overwrite =
312314
unable to overwrite parts of a pointer in memory at {$ptr}
313315
const_eval_pointer_arithmetic_overflow =
314316
overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`
315-
const_eval_pointer_arithmetic_test = out-of-bounds pointer arithmetic
317+
316318
const_eval_pointer_out_of_bounds =
317-
{$bad_pointer_message}: {const_eval_expected_inbounds_pointer}, but got {$pointer} {$ptr_offset_is_neg ->
318-
[true] which points to before the beginning of the allocation
319-
*[false] {$inbounds_size_is_neg ->
320-
[true] {$ptr_offset_abs ->
321-
[0] which is at the beginning of the allocation
322-
*[other] which does not have enough space to the beginning of the allocation
323-
}
324-
*[false] {$alloc_size_minus_ptr_offset ->
325-
[0] which is at or beyond the end of the allocation of size {$alloc_size ->
319+
{const_eval_bad_pointer_op_attempting}, but got {$pointer} which {$inbounds_size_is_neg ->
320+
[false] {$alloc_size_minus_ptr_offset ->
321+
[0] is at or beyond the end of the allocation of size {$alloc_size ->
326322
[1] 1 byte
327323
*[x] {$alloc_size} bytes
328324
}
329-
[1] which is only 1 byte from the end of the allocation
330-
*[x] which is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation
325+
[1] is only 1 byte from the end of the allocation
326+
*[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation
327+
}
328+
*[true] {$ptr_offset_abs ->
329+
[0] is at the beginning of the allocation
330+
*[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation
331331
}
332-
}
333332
}
333+
334334
const_eval_pointer_use_after_free =
335-
{$bad_pointer_message}: {$alloc_id} has been freed, so this pointer is dangling
335+
{const_eval_bad_pointer_op}: {$alloc_id} has been freed, so this pointer is dangling
336336
const_eval_ptr_as_bytes_1 =
337337
this code performed an operation that depends on the underlying bytes representing a pointer
338338
const_eval_ptr_as_bytes_2 =

compiler/rustc_const_eval/src/errors.rs

+10-23
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ use either::Either;
55
use rustc_abi::WrappingRange;
66
use rustc_errors::codes::*;
77
use rustc_errors::{
8-
Diag, DiagArgValue, DiagCtxtHandle, DiagMessage, Diagnostic, EmissionGuarantee, Level,
9-
MultiSpan, Subdiagnostic,
8+
Diag, DiagArgValue, DiagMessage, Diagnostic, EmissionGuarantee, Level, MultiSpan, Subdiagnostic,
109
};
1110
use rustc_hir::ConstContext;
1211
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
1312
use rustc_middle::mir::interpret::{
14-
CheckInAllocMsg, CtfeProvenance, ExpectedKind, InterpErrorKind, InvalidMetaKind,
15-
InvalidProgramInfo, Misalignment, Pointer, PointerKind, ResourceExhaustionInfo,
16-
UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
13+
CtfeProvenance, ExpectedKind, InterpErrorKind, InvalidMetaKind, InvalidProgramInfo,
14+
Misalignment, Pointer, PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo,
15+
UnsupportedOpInfo, ValidationErrorInfo,
1716
};
1817
use rustc_middle::ty::{self, Mutability, Ty};
1918
use rustc_span::{Span, Symbol};
@@ -498,19 +497,6 @@ pub trait ReportErrorExt {
498497
}
499498
}
500499

501-
fn bad_pointer_message(msg: CheckInAllocMsg, dcx: DiagCtxtHandle<'_>) -> String {
502-
use crate::fluent_generated::*;
503-
504-
let msg = match msg {
505-
CheckInAllocMsg::MemoryAccessTest => const_eval_memory_access_test,
506-
CheckInAllocMsg::PointerArithmeticTest => const_eval_pointer_arithmetic_test,
507-
CheckInAllocMsg::OffsetFromTest => const_eval_offset_from_test,
508-
CheckInAllocMsg::InboundsTest => const_eval_in_bounds_test,
509-
};
510-
511-
dcx.eagerly_translate_to_string(msg, [].into_iter())
512-
}
513-
514500
impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
515501
fn diagnostic_message(&self) -> DiagMessage {
516502
use UndefinedBehaviorInfo::*;
@@ -564,7 +550,6 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
564550

565551
fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
566552
use UndefinedBehaviorInfo::*;
567-
let dcx = diag.dcx;
568553
match self {
569554
Ub(_) => {}
570555
Custom(custom) => {
@@ -612,12 +597,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
612597
diag.arg("vtable_dyn_type", vtable_dyn_type.to_string());
613598
}
614599
PointerUseAfterFree(alloc_id, msg) => {
615-
diag.arg("alloc_id", alloc_id)
616-
.arg("bad_pointer_message", bad_pointer_message(msg, dcx));
600+
diag.arg("alloc_id", alloc_id).arg("operation", format!("{:?}", msg));
617601
}
618602
PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, inbounds_size, msg } => {
619603
diag.arg("alloc_size", alloc_size.bytes());
620-
diag.arg("bad_pointer_message", bad_pointer_message(msg, dcx));
621604
diag.arg("pointer", {
622605
let mut out = format!("{:?}", alloc_id);
623606
if ptr_offset > 0 {
@@ -627,14 +610,17 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
627610
}
628611
out
629612
});
613+
diag.arg("inbounds_size", inbounds_size);
630614
diag.arg("inbounds_size_is_neg", inbounds_size < 0);
631615
diag.arg("inbounds_size_abs", inbounds_size.unsigned_abs());
616+
diag.arg("ptr_offset", ptr_offset);
632617
diag.arg("ptr_offset_is_neg", ptr_offset < 0);
633618
diag.arg("ptr_offset_abs", ptr_offset.unsigned_abs());
634619
diag.arg(
635620
"alloc_size_minus_ptr_offset",
636621
alloc_size.bytes().saturating_sub(ptr_offset as u64),
637622
);
623+
diag.arg("operation", format!("{:?}", msg));
638624
}
639625
DanglingIntPointer { addr, inbounds_size, msg } => {
640626
if addr != 0 {
@@ -644,9 +630,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
644630
);
645631
}
646632

633+
diag.arg("inbounds_size", inbounds_size);
647634
diag.arg("inbounds_size_is_neg", inbounds_size < 0);
648635
diag.arg("inbounds_size_abs", inbounds_size.unsigned_abs());
649-
diag.arg("bad_pointer_message", bad_pointer_message(msg, dcx));
636+
diag.arg("operation", format!("{:?}", msg));
650637
}
651638
AlignmentCheckFailed(Misalignment { required, has }, msg) => {
652639
diag.arg("required", required.bytes());

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
348348

349349
// Check that the memory between them is dereferenceable at all, starting from the
350350
// origin pointer: `dist` is `a - b`, so it is based on `b`.
351-
self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest)
351+
self.check_ptr_access_signed(b, dist, CheckInAllocMsg::Dereferenceable)
352352
.map_err_kind(|_| {
353353
// This could mean they point to different allocations, or they point to the same allocation
354354
// but not the entire range between the pointers is in-bounds.
@@ -372,7 +372,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
372372
self.check_ptr_access_signed(
373373
a,
374374
dist.checked_neg().unwrap(), // i64::MIN is impossible as no allocation can be that large
375-
CheckInAllocMsg::OffsetFromTest,
375+
CheckInAllocMsg::Dereferenceable,
376376
)
377377
.map_err_kind(|_| {
378378
// Make the error more specific.
@@ -651,7 +651,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
651651
offset_bytes: i64,
652652
) -> InterpResult<'tcx, Pointer<Option<M::Provenance>>> {
653653
// The offset must be in bounds starting from `ptr`.
654-
self.check_ptr_access_signed(ptr, offset_bytes, CheckInAllocMsg::PointerArithmeticTest)?;
654+
self.check_ptr_access_signed(
655+
ptr,
656+
offset_bytes,
657+
CheckInAllocMsg::InboundsPointerArithmetic,
658+
)?;
655659
// This also implies that there is no overflow, so we are done.
656660
interp_ok(ptr.wrapping_signed_offset(offset_bytes, self))
657661
}

compiler/rustc_const_eval/src/interpret/memory.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
351351
kind = "static_mem"
352352
)
353353
}
354-
None => err_ub!(PointerUseAfterFree(alloc_id, CheckInAllocMsg::MemoryAccessTest)),
354+
None => err_ub!(PointerUseAfterFree(alloc_id, CheckInAllocMsg::MemoryAccess)),
355355
})
356356
.into();
357357
};
@@ -414,10 +414,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
414414
self,
415415
ptr,
416416
size,
417-
CheckInAllocMsg::MemoryAccessTest,
417+
CheckInAllocMsg::MemoryAccess,
418418
|this, alloc_id, offset, prov| {
419-
let (size, align) = this
420-
.get_live_alloc_size_and_align(alloc_id, CheckInAllocMsg::MemoryAccessTest)?;
419+
let (size, align) =
420+
this.get_live_alloc_size_and_align(alloc_id, CheckInAllocMsg::MemoryAccess)?;
421421
interp_ok((size, align, (alloc_id, offset, prov)))
422422
},
423423
)
@@ -613,7 +613,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
613613
}
614614
Some(GlobalAlloc::Function { .. }) => throw_ub!(DerefFunctionPointer(id)),
615615
Some(GlobalAlloc::VTable(..)) => throw_ub!(DerefVTablePointer(id)),
616-
None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccessTest)),
616+
None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccess)),
617617
Some(GlobalAlloc::Static(def_id)) => {
618618
assert!(self.tcx.is_static(def_id));
619619
// Thread-local statics do not have a constant address. They *must* be accessed via
@@ -707,7 +707,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
707707
self,
708708
ptr,
709709
size_i64,
710-
CheckInAllocMsg::MemoryAccessTest,
710+
CheckInAllocMsg::MemoryAccess,
711711
|this, alloc_id, offset, prov| {
712712
let alloc = this.get_alloc_raw(alloc_id)?;
713713
interp_ok((alloc.size(), alloc.align, (alloc_id, offset, prov, alloc)))
@@ -809,7 +809,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
809809
self,
810810
ptr,
811811
size_i64,
812-
CheckInAllocMsg::MemoryAccessTest,
812+
CheckInAllocMsg::MemoryAccess,
813813
|this, alloc_id, offset, prov| {
814814
let (alloc, machine) = this.get_alloc_raw_mut(alloc_id)?;
815815
interp_ok((alloc.size(), alloc.align, (alloc_id, offset, prov, alloc, machine)))
@@ -1615,7 +1615,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
16151615
err_ub!(DanglingIntPointer {
16161616
addr: offset,
16171617
inbounds_size: size,
1618-
msg: CheckInAllocMsg::InboundsTest
1618+
msg: CheckInAllocMsg::Dereferenceable
16191619
})
16201620
})
16211621
.into()

compiler/rustc_const_eval/src/interpret/validity.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
510510
self.ecx.check_ptr_access(
511511
place.ptr(),
512512
size,
513-
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
513+
CheckInAllocMsg::Dereferenceable, // will anyway be replaced by validity message
514514
),
515515
self.path,
516516
Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind },

compiler/rustc_error_codes/src/error_codes/E0207.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ impl<'a> Contains for Foo {
195195
Please note that unconstrained lifetime parameters are not supported if they are
196196
being used by an associated type.
197197

198-
In cases where the associated type's lifetime is meant to be tied to the the
198+
In cases where the associated type's lifetime is meant to be tied to the
199199
self type, and none of the methods on the trait need ownership or different
200200
mutability, then an option is to implement the trait on a borrowed type:
201201

compiler/rustc_lint/src/unused.rs

+16
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,22 @@ trait UnusedDelimLint {
942942
match s.kind {
943943
StmtKind::Let(ref local) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
944944
if let Some((init, els)) = local.kind.init_else_opt() {
945+
if els.is_some()
946+
&& let ExprKind::Paren(paren) = &init.kind
947+
&& !init.span.eq_ctxt(paren.span)
948+
{
949+
// This branch prevents cases where parentheses wrap an expression
950+
// resulting from macro expansion, such as:
951+
// ```
952+
// macro_rules! x {
953+
// () => { None::<i32> };
954+
// }
955+
// let Some(_) = (x!{}) else { return };
956+
// // -> let Some(_) = (None::<i32>) else { return };
957+
// // ~ ~ No Lint
958+
// ```
959+
return;
960+
}
945961
let ctx = match els {
946962
None => UnusedDelimsCtx::AssignedValue,
947963
Some(_) => UnusedDelimsCtx::AssignedValueLetElse,

compiler/rustc_middle/src/mir/interpret/error.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,11 @@ pub enum InvalidProgramInfo<'tcx> {
221221
#[derive(Debug, Copy, Clone)]
222222
pub enum CheckInAllocMsg {
223223
/// We are access memory.
224-
MemoryAccessTest,
224+
MemoryAccess,
225225
/// We are doing pointer arithmetic.
226-
PointerArithmeticTest,
227-
/// We are doing pointer offset_from.
228-
OffsetFromTest,
226+
InboundsPointerArithmetic,
229227
/// None of the above -- generic/unspecific inbounds test.
230-
InboundsTest,
228+
Dereferenceable,
231229
}
232230

233231
/// Details of which pointer is not aligned.

compiler/rustc_span/src/span_encoding.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,21 @@ impl Span {
306306
/// Returns `true` if this span comes from any kind of macro, desugaring or inlining.
307307
#[inline]
308308
pub fn from_expansion(self) -> bool {
309-
// If the span is fully inferred then ctxt > MAX_CTXT
310-
self.inline_ctxt().map_or(true, |ctxt| !ctxt.is_root())
309+
let ctxt = match_span_kind! {
310+
self,
311+
// All branches here, except `InlineParent`, actually return `span.ctxt_or_parent_or_marker`.
312+
// Since `Interned` is selected if the field contains `CTXT_INTERNED_MARKER` returning that value
313+
// as the context allows the compiler to optimize out the branch that selects between either
314+
// `Interned` and `PartiallyInterned`.
315+
//
316+
// Interned contexts can never be the root context and `CTXT_INTERNED_MARKER` has a different value
317+
// than the root context so this works for checking is this is an expansion.
318+
InlineCtxt(span) => SyntaxContext::from_u16(span.ctxt),
319+
InlineParent(_span) => SyntaxContext::root(),
320+
PartiallyInterned(span) => SyntaxContext::from_u16(span.ctxt),
321+
Interned(_span) => SyntaxContext::from_u16(CTXT_INTERNED_MARKER),
322+
};
323+
!ctxt.is_root()
311324
}
312325

313326
/// Returns `true` if this is a dummy span with any hygienic context.

0 commit comments

Comments
 (0)