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 2d5ffc5

Browse files
committed
Auto merge of #140596 - matthiaskrgr:rollup-s7tzr34, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #140485 (Optimize the codegen for `Span::from_expansion`) - #140509 (transmutability: merge contiguous runs with a common destination) - #140519 (Use select in projection lookup in `report_projection_error`) - #140521 (interpret: better error message for out-of-bounds pointer arithmetic and accesses) - #140536 (Rename `*Guard::try_map` to `filter_map`.) - #140550 (Stabilize `select_unpredictable`) - #140563 (extend the list of registered dylibs on `test::prepare_cargo_test`) - #140572 (Add useful comments on `ExprKind::If` variants.) - #140574 (Add regression test for 133065) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4824c2b + 6f7f3ce commit 2d5ffc5

File tree

100 files changed

+403
-309
lines changed

Some content is hidden

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

100 files changed

+403
-309
lines changed

‎compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,6 +1633,9 @@ pub enum ExprKind {
16331633
/// An `if` block, with an optional `else` block.
16341634
///
16351635
/// `if expr { block } else { expr }`
1636+
///
1637+
/// If present, the "else" expr is always `ExprKind::Block` (for `else`) or
1638+
/// `ExprKind::If` (for `else if`).
16361639
If(P<Expr>, P<Block>, Option<P<Expr>>),
16371640
/// A while loop, with an optional label.
16381641
///

‎compiler/rustc_const_eval/messages.ftl

Lines changed: 35 additions & 35 deletions
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

Lines changed: 10 additions & 23 deletions
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

Lines changed: 7 additions & 3 deletions
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

Lines changed: 8 additions & 8 deletions
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

Lines changed: 1 addition & 1 deletion
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_hir/src/hir.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,6 +2741,9 @@ pub enum ExprKind<'hir> {
27412741
/// An `if` block, with an optional else block.
27422742
///
27432743
/// I.e., `if <expr> { <expr> } else { <expr> }`.
2744+
///
2745+
/// The "then" expr is always `ExprKind::Block`. If present, the "else" expr is always
2746+
/// `ExprKind::Block` (for `else`) or `ExprKind::If` (for `else if`).
27442747
If(&'hir Expr<'hir>, &'hir Expr<'hir>, Option<&'hir Expr<'hir>>),
27452748
/// A conditionless loop (can be exited with `break`, `continue`, or `return`).
27462749
///

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

Lines changed: 3 additions & 5 deletions
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_middle/src/thir.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,10 @@ pub enum ExprKind<'tcx> {
292292
If {
293293
if_then_scope: region::Scope,
294294
cond: ExprId,
295+
/// `then` is always `ExprKind::Block`.
295296
then: ExprId,
297+
/// If present, the `else_opt` expr is always `ExprKind::Block` (for
298+
/// `else`) or `ExprKind::If` (for `else if`).
296299
else_opt: Option<ExprId>,
297300
},
298301
/// A function call. Method calls and overloaded operators are converted to plain function calls.

‎compiler/rustc_span/src/span_encoding.rs

Lines changed: 15 additions & 2 deletions
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)

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