Skip to content

Rollup of 9 pull requests #99023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0503bc0
Implement ExitCodeExt for Windows
AronParker Jun 9, 2022
5d32f31
Fix copy paste error
AronParker Jun 10, 2022
eb783d9
Incorporate warning for potential exit code ambiguities
AronParker Jun 10, 2022
b13af73
Make "windows_process_exit_code_from" unstable
AronParker Jun 10, 2022
071f7b8
Remove unsupported options in configure.py
jyn514 Jun 22, 2022
27b7b3d
interpret: use AllocRange in UninitByteAccess
RalfJung Jul 6, 2022
deaa92b
Fix missing word in comment
pierwill Jul 6, 2022
2a0e659
add a test for #80471
TaKO8Ki Jul 7, 2022
2f0ccdf
suggest adding a derive for #[default] applied to variants
fee1-dead Jul 7, 2022
a80bb5b
add a test for #70408
TaKO8Ki Jul 7, 2022
111df9e
Reword comments and rename HIR visiting methods.
cjgillot Jul 3, 2022
d96d541
Replace boolean argument for print_where_clause with an enum to make …
GuillaumeGomez Jul 7, 2022
8d00ca2
Rollup merge of #97917 - AronParker:master, r=ChrisDenton
matthiaskrgr Jul 7, 2022
c4002f0
Rollup merge of #98369 - jyn514:configure.py, r=Mark-Simulacrum
matthiaskrgr Jul 7, 2022
76d5c96
Rollup merge of #98844 - cjgillot:deep-visit, r=jyn514
matthiaskrgr Jul 7, 2022
4d69884
Rollup merge of #98979 - RalfJung:more-alloc-range, r=oli-obk
matthiaskrgr Jul 7, 2022
ffe849d
Rollup merge of #98986 - pierwill:patch-5, r=oli-obk
matthiaskrgr Jul 7, 2022
55da63f
Rollup merge of #98995 - TaKO8Ki:add-test-for-80471, r=Mark-Simulacrum
matthiaskrgr Jul 7, 2022
e39f9bc
Rollup merge of #99002 - fee1-dead-contrib:sugg_derive, r=michaelwoer…
matthiaskrgr Jul 7, 2022
3d9993e
Rollup merge of #99004 - TaKO8Ki:add-test-for-70408, r=Mark-Simulacrum
matthiaskrgr Jul 7, 2022
28da75b
Rollup merge of #99017 - GuillaumeGomez:rustdoc-ending-enum, r=notriddle
matthiaskrgr Jul 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
err_ub!(DanglingIntPointer(0, _)) =>
{ "a null {kind}" },
err_ub!(DanglingIntPointer(i, _)) =>
{ "a dangling {kind} (address 0x{i:x} is unallocated)" },
{ "a dangling {kind} (address {i:#x} is unallocated)" },
err_ub!(PointerOutOfBounds { .. }) =>
{ "a dangling {kind} (going beyond the bounds of its allocation)" },
// This cannot happen during const-eval (because interning already detects
Expand Down Expand Up @@ -941,7 +941,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// element that byte belongs to so we can
// provide an index.
let i = usize::try_from(
access.uninit_offset.bytes() / layout.size.bytes(),
access.uninit.start.bytes() / layout.size.bytes(),
)
.unwrap();
self.path.push(PathElem::ArrayElem(i));
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! - Example: Examine each expression to look for its type and do some check or other.
//! - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
//! `nested_filter::OnlyBodies` (and implement `nested_visit_map`), and use
//! `tcx.hir().deep_visit_all_item_likes(&mut visitor)`. Within your
//! `tcx.hir().visit_all_item_likes_in_crate(&mut visitor)`. Within your
//! `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke
//! `intravisit::walk_expr()` to keep walking the subparts).
//! - Pro: Visitor methods for any kind of HIR node, not just item-like things.
Expand Down Expand Up @@ -190,7 +190,7 @@ use nested_filter::NestedFilter;
/// (this is why the module is called `intravisit`, to distinguish it
/// from the AST's `visit` module, which acts differently). If you
/// simply want to visit all items in the crate in some order, you
/// should call `Crate::visit_all_items`. Otherwise, see the comment
/// should call `tcx.hir().visit_all_item_likes_in_crate`. Otherwise, see the comment
/// on `visit_nested_item` for details on how to visit nested items.
///
/// If you want to ensure that your code handles every variant
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_incremental/src/assert_dep_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn assert_dep_graph(tcx: TyCtxt<'_>) {
let mut visitor =
IfThisChanged { tcx, if_this_changed: vec![], then_this_would_need: vec![] };
visitor.process_attrs(hir::CRATE_HIR_ID);
tcx.hir().deep_visit_all_item_likes(&mut visitor);
tcx.hir().visit_all_item_likes_in_crate(&mut visitor);
(visitor.if_this_changed, visitor.then_this_would_need)
};

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
return;
}

self.tcx.hir().deep_visit_all_item_likes(self);
self.tcx.hir().visit_all_item_likes_in_crate(self);
}

fn encode_def_path_table(&mut self) {
Expand Down
66 changes: 37 additions & 29 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ impl<'hir> Map<'hir> {
}
}

/// Walks the contents of a crate. See also `Crate::visit_all_items`.
/// Walks the contents of the local crate. See also `visit_all_item_likes_in_crate`.
pub fn walk_toplevel_module(self, visitor: &mut impl Visitor<'hir>) {
let (top_mod, span, hir_id) = self.get_module(CRATE_DEF_ID);
visitor.visit_mod(top_mod, span, hir_id);
Expand All @@ -588,53 +588,61 @@ impl<'hir> Map<'hir> {
}
}

/// Visits all items in the crate in some deterministic (but
/// unspecified) order. If you need to process every item,
/// and care about nesting -- usually because your algorithm
/// follows lexical scoping rules -- then this method is the best choice.
/// If you don't care about nesting, you should use the `tcx.hir_crate_items()` query
/// or `items()` instead.
/// Visits all item-likes in the crate in some deterministic (but unspecified) order. If you
/// need to process every item-like, and don't care about visiting nested items in a particular
/// order then this method is the best choice. If you do care about this nesting, you should
/// use the `tcx.hir().walk_toplevel_module`.
///
/// Note that this function will access HIR for all the item-likes in the crate. If you only
/// need to access some of them, it is usually better to manually loop on the iterators
/// provided by `tcx.hir_crate_items(())`.
///
/// Please see the notes in `intravisit.rs` for more information.
pub fn deep_visit_all_item_likes<V>(self, visitor: &mut V)
pub fn visit_all_item_likes_in_crate<V>(self, visitor: &mut V)
where
V: Visitor<'hir>,
{
let krate = self.krate();
for owner in krate.owners.iter().filter_map(|i| i.as_owner()) {
match owner.node() {
OwnerNode::Item(item) => visitor.visit_item(item),
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
OwnerNode::ImplItem(item) => visitor.visit_impl_item(item),
OwnerNode::TraitItem(item) => visitor.visit_trait_item(item),
OwnerNode::Crate(_) => {}
}
let krate = self.tcx.hir_crate_items(());

for id in krate.items() {
visitor.visit_item(self.item(id));
}

for id in krate.trait_items() {
visitor.visit_trait_item(self.trait_item(id));
}

for id in krate.impl_items() {
visitor.visit_impl_item(self.impl_item(id));
}

for id in krate.foreign_items() {
visitor.visit_foreign_item(self.foreign_item(id));
}
}

/// If you don't care about nesting, you should use the
/// `tcx.hir_module_items()` query or `module_items()` instead.
/// Please see notes in `deep_visit_all_item_likes`.
pub fn deep_visit_item_likes_in_module<V>(self, module: LocalDefId, visitor: &mut V)
/// This method is the equivalent of `visit_all_item_likes_in_crate` but restricted to
/// item-likes in a single module.
pub fn visit_item_likes_in_module<V>(self, module: LocalDefId, visitor: &mut V)
where
V: Visitor<'hir>,
{
let module = self.tcx.hir_module_items(module);

for id in module.items.iter() {
visitor.visit_item(self.item(*id));
for id in module.items() {
visitor.visit_item(self.item(id));
}

for id in module.trait_items.iter() {
visitor.visit_trait_item(self.trait_item(*id));
for id in module.trait_items() {
visitor.visit_trait_item(self.trait_item(id));
}

for id in module.impl_items.iter() {
visitor.visit_impl_item(self.impl_item(*id));
for id in module.impl_items() {
visitor.visit_impl_item(self.impl_item(id));
}

for id in module.foreign_items.iter() {
visitor.visit_foreign_item(self.foreign_item(*id));
for id in module.foreign_items() {
visitor.visit_foreign_item(self.foreign_item(id));
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/nested_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_hir::intravisit::nested_filter::NestedFilter;
/// constant arguments of types, e.g. in `let _: [(); /* HERE */];`.
///
/// **This is the most common choice.** A very common pattern is
/// to use `deep_visit_all_item_likes()` as an outer loop,
/// to use `visit_all_item_likes_in_crate()` as an outer loop,
/// and to have the visitor that visits the contents of each item
/// using this setting.
pub struct OnlyBodies(());
Expand Down
21 changes: 12 additions & 9 deletions compiler/rustc_middle/src/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ pub fn alloc_range(start: Size, size: Size) -> AllocRange {
}

impl AllocRange {
#[inline]
pub fn from(r: Range<Size>) -> Self {
alloc_range(r.start, r.end - r.start) // `Size` subtraction (overflow-checked)
}

#[inline(always)]
pub fn end(self) -> Size {
self.start + self.size // This does overflow checking.
Expand Down Expand Up @@ -1095,17 +1100,17 @@ impl InitMask {
/// Returns `Ok(())` if it's initialized. Otherwise returns a range of byte
/// indexes for the first contiguous span of the uninitialized access.
#[inline]
pub fn is_range_initialized(&self, start: Size, end: Size) -> Result<(), Range<Size>> {
pub fn is_range_initialized(&self, start: Size, end: Size) -> Result<(), AllocRange> {
if end > self.len {
return Err(self.len..end);
return Err(AllocRange::from(self.len..end));
}

let uninit_start = self.find_bit(start, end, false);

match uninit_start {
Some(uninit_start) => {
let uninit_end = self.find_bit(uninit_start, end, true).unwrap_or(end);
Err(uninit_start..uninit_end)
Err(AllocRange::from(uninit_start..uninit_end))
}
None => Ok(()),
}
Expand Down Expand Up @@ -1176,19 +1181,17 @@ impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
///
/// Returns `Ok(())` if it's initialized. Otherwise returns the range of byte
/// indexes of the first contiguous uninitialized access.
fn is_init(&self, range: AllocRange) -> Result<(), Range<Size>> {
fn is_init(&self, range: AllocRange) -> Result<(), AllocRange> {
self.init_mask.is_range_initialized(range.start, range.end()) // `Size` addition
}

/// Checks that a range of bytes is initialized. If not, returns the `InvalidUninitBytes`
/// error which will report the first range of bytes which is uninitialized.
fn check_init(&self, range: AllocRange) -> AllocResult {
self.is_init(range).map_err(|idx_range| {
self.is_init(range).map_err(|uninit_range| {
AllocError::InvalidUninitBytes(Some(UninitBytesAccess {
access_offset: range.start,
access_size: range.size,
uninit_offset: idx_range.start,
uninit_size: idx_range.end - idx_range.start, // `Size` subtraction
access: range,
uninit: uninit_range,
}))
})
}
Expand Down
90 changes: 39 additions & 51 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{AllocId, ConstAlloc, Pointer, Scalar};
use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar};

use crate::mir::interpret::ConstValue;
use crate::ty::{layout, query::TyCtxtAt, tls, FnSig, Ty, ValTree};
Expand Down Expand Up @@ -162,9 +162,9 @@ impl fmt::Display for InvalidProgramInfo<'_> {
AlreadyReported(ErrorGuaranteed { .. }) => {
write!(f, "encountered constants with type errors, stopping evaluation")
}
Layout(ref err) => write!(f, "{}", err),
FnAbiAdjustForForeignAbi(ref err) => write!(f, "{}", err),
SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{}`", ty),
Layout(ref err) => write!(f, "{err}"),
FnAbiAdjustForForeignAbi(ref err) => write!(f, "{err}"),
SizeOfUnsizedType(ty) => write!(f, "size_of called on unsized type `{ty}`"),
}
}
}
Expand Down Expand Up @@ -205,14 +205,10 @@ impl fmt::Display for CheckInAllocMsg {
/// Details of an access to uninitialized bytes where it is not allowed.
#[derive(Debug)]
pub struct UninitBytesAccess {
/// Location of the original memory access.
pub access_offset: Size,
/// Size of the original memory access.
pub access_size: Size,
/// Location of the first uninitialized byte that was accessed.
pub uninit_offset: Size,
/// Number of consecutive uninitialized bytes that were accessed.
pub uninit_size: Size,
/// Range of the original memory access.
pub access: AllocRange,
/// Range of the uninit memory that was encountered. (Might not be maximal.)
pub uninit: AllocRange,
}

/// Information about a size mismatch.
Expand Down Expand Up @@ -308,30 +304,28 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use UndefinedBehaviorInfo::*;
match self {
Ub(msg) => write!(f, "{}", msg),
Ub(msg) => write!(f, "{msg}"),
Unreachable => write!(f, "entering unreachable code"),
BoundsCheckFailed { ref len, ref index } => {
write!(f, "indexing out of bounds: the len is {} but the index is {}", len, index)
write!(f, "indexing out of bounds: the len is {len} but the index is {index}")
}
DivisionByZero => write!(f, "dividing by zero"),
RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"),
DivisionOverflow => write!(f, "overflow in signed division (dividing MIN by -1)"),
RemainderOverflow => write!(f, "overflow in signed remainder (dividing MIN by -1)"),
PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"),
InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {}", msg),
InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {msg}"),
InvalidVtableDropFn(sig) => write!(
f,
"invalid drop function signature: got {}, expected exactly one argument which must be a pointer type",
sig
"invalid drop function signature: got {sig}, expected exactly one argument which must be a pointer type",
),
InvalidVtableSize => {
write!(f, "invalid vtable: size is bigger than largest supported object")
}
InvalidVtableAlignment(msg) => write!(f, "invalid vtable: alignment {}", msg),
InvalidVtableAlignment(msg) => write!(f, "invalid vtable: alignment {msg}"),
UnterminatedCString(p) => write!(
f,
"reading a null-terminated string starting at {:?} with no null found before end of allocation",
p,
"reading a null-terminated string starting at {p:?} with no null found before end of allocation",
),
PointerUseAfterFree(a) => {
write!(f, "pointer to {a:?} was dereferenced after this allocation got freed")
Expand Down Expand Up @@ -359,41 +353,36 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
}
AlignmentCheckFailed { required, has } => write!(
f,
"accessing memory with alignment {}, but alignment {} is required",
has.bytes(),
required.bytes()
"accessing memory with alignment {has}, but alignment {required} is required",
has = has.bytes(),
required = required.bytes()
),
WriteToReadOnly(a) => write!(f, "writing to {a:?} which is read-only"),
DerefFunctionPointer(a) => write!(f, "accessing {a:?} which contains a function"),
ValidationFailure { path: None, msg } => {
write!(f, "constructing invalid value: {}", msg)
write!(f, "constructing invalid value: {msg}")
}
ValidationFailure { path: Some(path), msg } => {
write!(f, "constructing invalid value at {}: {}", path, msg)
write!(f, "constructing invalid value at {path}: {msg}")
}
InvalidBool(b) => {
write!(f, "interpreting an invalid 8-bit value as a bool: 0x{:02x}", b)
write!(f, "interpreting an invalid 8-bit value as a bool: 0x{b:02x}")
}
InvalidChar(c) => {
write!(f, "interpreting an invalid 32-bit value as a char: 0x{:08x}", c)
write!(f, "interpreting an invalid 32-bit value as a char: 0x{c:08x}")
}
InvalidTag(val) => write!(f, "enum value has invalid tag: {:x}", val),
InvalidTag(val) => write!(f, "enum value has invalid tag: {val:x}"),
InvalidFunctionPointer(p) => {
write!(f, "using {:?} as function pointer but it does not point to a function", p)
write!(f, "using {p:?} as function pointer but it does not point to a function")
}
InvalidStr(err) => write!(f, "this string is not valid UTF-8: {}", err),
InvalidUninitBytes(Some((alloc, access))) => write!(
InvalidStr(err) => write!(f, "this string is not valid UTF-8: {err}"),
InvalidUninitBytes(Some((alloc, info))) => write!(
f,
"reading {} byte{} of memory starting at {:?}, \
but {} byte{} {} uninitialized starting at {:?}, \
"reading memory at {alloc:?}{access:?}, \
but memory is uninitialized at {uninit:?}, \
and this operation requires initialized memory",
access.access_size.bytes(),
pluralize!(access.access_size.bytes()),
Pointer::new(*alloc, access.access_offset),
access.uninit_size.bytes(),
pluralize!(access.uninit_size.bytes()),
pluralize!("is", access.uninit_size.bytes()),
Pointer::new(*alloc, access.uninit_offset),
access = info.access,
uninit = info.uninit,
),
InvalidUninitBytes(None) => write!(
f,
Expand All @@ -402,8 +391,7 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
DeadLocal => write!(f, "accessing a dead local variable"),
ScalarSizeMismatch(self::ScalarSizeMismatch { target_size, data_size }) => write!(
f,
"scalar size mismatch: expected {} bytes but got {} bytes instead",
target_size, data_size
"scalar size mismatch: expected {target_size} bytes but got {data_size} bytes instead",
),
UninhabitedEnumVariantWritten => {
write!(f, "writing discriminant of an uninhabited enum")
Expand Down Expand Up @@ -437,13 +425,13 @@ impl fmt::Display for UnsupportedOpInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use UnsupportedOpInfo::*;
match self {
Unsupported(ref msg) => write!(f, "{}", msg),
Unsupported(ref msg) => write!(f, "{msg}"),
ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes"),
PartialPointerOverwrite(ptr) => {
write!(f, "unable to overwrite parts of a pointer in memory at {:?}", ptr)
write!(f, "unable to overwrite parts of a pointer in memory at {ptr:?}")
}
ThreadLocalStatic(did) => write!(f, "cannot access thread local static ({:?})", did),
ReadExternStatic(did) => write!(f, "cannot read from extern static ({:?})", did),
ThreadLocalStatic(did) => write!(f, "cannot access thread local static ({did:?})"),
ReadExternStatic(did) => write!(f, "cannot read from extern static ({did:?})"),
}
}
}
Expand Down Expand Up @@ -526,11 +514,11 @@ impl fmt::Display for InterpError<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use InterpError::*;
match *self {
Unsupported(ref msg) => write!(f, "{}", msg),
InvalidProgram(ref msg) => write!(f, "{}", msg),
UndefinedBehavior(ref msg) => write!(f, "{}", msg),
ResourceExhaustion(ref msg) => write!(f, "{}", msg),
MachineStop(ref msg) => write!(f, "{}", msg),
Unsupported(ref msg) => write!(f, "{msg}"),
InvalidProgram(ref msg) => write!(f, "{msg}"),
UndefinedBehavior(ref msg) => write!(f, "{msg}"),
ResourceExhaustion(ref msg) => write!(f, "{msg}"),
MachineStop(ref msg) => write!(f, "{msg}"),
}
}
}
Expand Down
Loading