Auto merge of #99024 - matthiaskrgr:rollup-8ygpcpg, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - #97917 (Implement ExitCodeExt for Windows)
 - #98844 (Reword comments and rename HIR visiting methods.)
 - #98979 (interpret: use AllocRange in UninitByteAccess)
 - #98986 (Fix missing word in comment)
 - #98994 (replace process exit with more detailed exit in src/bootstrap/*.rs)
 - #98995 (Add a test for #80471)
 - #99002 (suggest adding a derive for #[default] applied to variants)
 - #99004 (Add a test for #70408)
 - #99017 (Replace boolean argument for print_where_clause with an enum to make code more clear)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-07-07 20:55:34 +00:00
commit 1517f5de01
47 changed files with 343 additions and 236 deletions

View File

@ -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
@ -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));

View File

@ -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.
@ -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

View File

@ -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)
};

View File

@ -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) {

View File

@ -561,7 +561,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);
@ -581,53 +581,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));
}
}

View File

@ -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(());

View File

@ -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.
@ -1095,9 +1100,9 @@ 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);
@ -1105,7 +1110,7 @@ impl InitMask {
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(()),
}
@ -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,
}))
})
}

View File

@ -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};
@ -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}`"),
}
}
}
@ -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.
@ -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")
@ -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,
@ -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")
@ -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:?})"),
}
}
}
@ -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}"),
}
}
}

View File

@ -153,7 +153,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
_: &mir::Statement<'tcx>,
loc: Location,
) {
// If we move from a place then only stops needing storage *after*
// If we move from a place then it only stops needing storage *after*
// that statement.
self.check_for_move(trans, loc);
}

View File

@ -173,7 +173,7 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
intravisit::walk_struct_def(self, v)
}
}
tcx.hir().deep_visit_all_item_likes(&mut GatherCtors { tcx, set: &mut set });
tcx.hir().visit_all_item_likes_in_crate(&mut GatherCtors { tcx, set: &mut set });
set
}

View File

@ -2428,7 +2428,7 @@ fn check_non_exported_macro_for_invalid_attrs(tcx: TyCtxt<'_>, item: &Item<'_>)
fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
let check_attr_visitor = &mut CheckAttrVisitor { tcx };
tcx.hir().deep_visit_item_likes_in_module(module_def_id, check_attr_visitor);
tcx.hir().visit_item_likes_in_module(module_def_id, check_attr_visitor);
if module_def_id.is_top_level_module() {
check_attr_visitor.check_attributes(CRATE_HIR_ID, DUMMY_SP, Target::Mod, None);
check_invalid_crate_level_attr(tcx, tcx.hir().krate_attrs());

View File

@ -56,7 +56,7 @@ impl NonConstExpr {
fn check_mod_const_bodies(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
let mut vis = CheckConstVisitor::new(tcx);
tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut vis);
tcx.hir().visit_item_likes_in_module(module_def_id, &mut vis);
}
pub(crate) fn provide(providers: &mut Providers) {

View File

@ -28,7 +28,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
errors: &errors,
};
tcx.hir().deep_visit_item_likes_in_module(module_id, &mut v);
tcx.hir().visit_item_likes_in_module(module_id, &mut v);
});
let errors = errors.into_inner();

View File

@ -140,7 +140,7 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
}
fn check_mod_liveness(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut IrMaps::new(tcx));
tcx.hir().visit_item_likes_in_module(module_def_id, &mut IrMaps::new(tcx));
}
pub fn provide(providers: &mut Providers) {

View File

@ -31,7 +31,7 @@ struct CheckLoopVisitor<'a, 'hir> {
}
fn check_mod_loops(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
tcx.hir().deep_visit_item_likes_in_module(
tcx.hir().visit_item_likes_in_module(
module_def_id,
&mut CheckLoopVisitor { sess: &tcx.sess, hir_map: tcx.hir(), cx: Normal },
);

View File

@ -14,7 +14,7 @@ use rustc_span::Span;
use rustc_target::spec::abi::Abi;
fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut CheckNakedFunctions { tcx });
tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckNakedFunctions { tcx });
}
pub(crate) fn provide(providers: &mut Providers) {

View File

@ -660,7 +660,7 @@ fn stability_index(tcx: TyCtxt<'_>, (): ()) -> Index {
/// Cross-references the feature names of unstable APIs with enabled
/// features and possibly prints errors.
fn check_mod_unstable_api_usage(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut Checker { tcx });
tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx });
}
pub(crate) fn provide(providers: &mut Providers) {
@ -890,7 +890,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
let mut missing = MissingStabilityAnnotations { tcx, access_levels };
missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID));
tcx.hir().walk_toplevel_module(&mut missing);
tcx.hir().deep_visit_all_item_likes(&mut missing);
tcx.hir().visit_all_item_likes_in_crate(&mut missing);
}
let declared_lang_features = &tcx.features().declared_lang_features;

View File

@ -1499,10 +1499,16 @@ impl<'a> Resolver<'a> {
&& let ModuleKind::Def(DefKind::Enum, def_id, _) = parent_scope.module.kind
&& let Some(span) = self.opt_span(def_id)
{
err.span_help(
self.session.source_map().guess_head_span(span),
"consider adding `#[derive(Default)]` to this enum",
);
let source_map = self.session.source_map();
let head_span = source_map.guess_head_span(span);
if let Ok(head) = source_map.span_to_snippet(head_span) {
err.span_suggestion(head_span, "consider adding a derive", format!("#[derive(Default)]\n{head}"), Applicability::MaybeIncorrect);
} else {
err.span_help(
head_span,
"consider adding `#[derive(Default)]` to this enum",
);
}
}
for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] {
if let Ok(binding) = self.early_resolve_ident_in_lexical_scope(

View File

@ -59,7 +59,7 @@ struct OnlySelfBounds(bool);
// Main entry point
fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx });
tcx.hir().visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx });
}
pub fn provide(providers: &mut Providers) {

View File

@ -234,3 +234,26 @@ impl ChildExt for process::Child {
self.handle.main_thread_handle()
}
}
/// Windows-specific extensions to [`process::ExitCode`].
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[unstable(feature = "windows_process_exit_code_from", issue = "none")]
pub trait ExitCodeExt: Sealed {
/// Creates a new `ExitCode` from the raw underlying `u32` return value of
/// a process.
///
/// The exit code should not be 259, as this conflicts with the `STILL_ACTIVE`
/// macro returned from the `GetExitCodeProcess` function to signal that the
/// process has yet to run to completion.
#[unstable(feature = "windows_process_exit_code_from", issue = "none")]
fn from_raw(raw: u32) -> Self;
}
#[unstable(feature = "windows_process_exit_code_from", issue = "none")]
impl ExitCodeExt for process::ExitCode {
fn from_raw(raw: u32) -> Self {
process::ExitCode::from_inner(From::from(raw))
}
}

View File

@ -1724,6 +1724,10 @@ impl crate::error::Error for ExitStatusError {}
#[stable(feature = "process_exitcode", since = "1.61.0")]
pub struct ExitCode(imp::ExitCode);
/// Allows extension traits within `std`.
#[unstable(feature = "sealed", issue = "none")]
impl crate::sealed::Sealed for ExitCode {}
#[stable(feature = "process_exitcode", since = "1.61.0")]
impl ExitCode {
/// The canonical `ExitCode` for successful termination on this platform.
@ -1814,6 +1818,18 @@ impl From<u8> for ExitCode {
}
}
impl AsInner<imp::ExitCode> for ExitCode {
fn as_inner(&self) -> &imp::ExitCode {
&self.0
}
}
impl FromInner<imp::ExitCode> for ExitCode {
fn from_inner(s: imp::ExitCode) -> ExitCode {
ExitCode(s)
}
}
impl Child {
/// Forces the child process to exit. If the child has already exited, an [`InvalidInput`]
/// error is returned.

View File

@ -707,6 +707,12 @@ impl From<u8> for ExitCode {
}
}
impl From<u32> for ExitCode {
fn from(code: u32) -> Self {
ExitCode(c::DWORD::from(code))
}
}
fn zeroed_startupinfo() -> c::STARTUPINFO {
c::STARTUPINFO {
cb: 0,

View File

@ -346,11 +346,7 @@ impl StepDescription {
eprintln!(
"note: if you are adding a new Step to bootstrap itself, make sure you register it with `describe!`"
);
#[cfg(not(test))]
std::process::exit(1);
#[cfg(test)]
// so we can use #[should_panic]
panic!()
crate::detail_exit(1);
}
}
}
@ -1008,7 +1004,7 @@ impl<'a> Builder<'a> {
if !help_on_error.is_empty() {
eprintln!("{}", help_on_error);
}
std::process::exit(1);
crate::detail_exit(1);
}
}
@ -1437,7 +1433,7 @@ impl<'a> Builder<'a> {
"error: `x.py clippy` requires a host `rustc` toolchain with the `clippy` component"
);
eprintln!("help: try `rustup component add clippy`");
std::process::exit(1);
crate::detail_exit(1);
});
if !t!(std::str::from_utf8(&output.stdout)).contains("nightly") {
rustflags.arg("--cfg=bootstrap");

View File

@ -13,7 +13,7 @@ use std::fs;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::{Path, PathBuf};
use std::process::{exit, Command, Stdio};
use std::process::{Command, Stdio};
use std::str;
use serde::Deserialize;
@ -1377,7 +1377,7 @@ pub fn run_cargo(
});
if !ok {
exit(1);
crate::detail_exit(1);
}
// Ok now we need to actually find all the files listed in `toplevel`. We've

View File

@ -11,7 +11,7 @@ use std::ffi::OsStr;
use std::fmt;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{exit, Command};
use std::process::Command;
use std::str::FromStr;
use crate::builder::{Builder, TaskPath};
@ -805,8 +805,6 @@ impl Config {
let get_toml = |_| TomlConfig::default();
#[cfg(not(test))]
let get_toml = |file: &Path| {
use std::process;
let contents =
t!(fs::read_to_string(file), format!("config file {} not found", file.display()));
// Deserialize to Value and then TomlConfig to prevent the Deserialize impl of
@ -817,7 +815,7 @@ impl Config {
Ok(table) => table,
Err(err) => {
eprintln!("failed to parse TOML configuration '{}': {}", file.display(), err);
process::exit(2);
crate::detail_exit(2);
}
}
};
@ -1487,7 +1485,7 @@ fn download_ci_rustc_commit(
println!("help: maybe your repository history is too shallow?");
println!("help: consider disabling `download-rustc`");
println!("help: or fetch enough history to include one upstream commit");
exit(1);
crate::detail_exit(1);
}
// Warn if there were changes to the compiler or standard library since the ancestor commit.

View File

@ -4,7 +4,6 @@
//! has various flags to configure how it's run.
use std::path::PathBuf;
use std::process;
use getopts::Options;
@ -261,7 +260,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
// subcommand.
println!("{}\n", subcommand_help);
let exit_code = if args.is_empty() { 0 } else { 1 };
process::exit(exit_code);
crate::detail_exit(exit_code);
}
};
@ -347,7 +346,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
} else if verbose {
panic!("No paths available for subcommand `{}`", subcommand.as_str());
}
process::exit(exit_code);
crate::detail_exit(exit_code);
};
// Done specifying what options are possible, so do the getopts parsing
@ -379,7 +378,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
"Sorry, I couldn't figure out which subcommand you were trying to specify.\n\
You may need to move some options to after the subcommand.\n"
);
process::exit(1);
crate::detail_exit(1);
}
// Extra help text for some commands
match subcommand {
@ -600,7 +599,7 @@ Arguments:
eprintln!("error: {}", err);
eprintln!("help: the available profiles are:");
eprint!("{}", Profile::all_for_help("- "));
std::process::exit(1);
crate::detail_exit(1);
})
} else {
t!(crate::setup::interactive_path())
@ -614,7 +613,7 @@ Arguments:
|| matches.opt_str("keep-stage-std").is_some()
{
eprintln!("--keep-stage not yet supported for x.py check");
process::exit(1);
crate::detail_exit(1);
}
}
@ -805,7 +804,7 @@ fn parse_deny_warnings(matches: &getopts::Matches) -> Option<bool> {
Some("warn") => Some(false),
Some(value) => {
eprintln!(r#"invalid value for --warnings: {:?}, expected "warn" or "deny""#, value,);
process::exit(1);
crate::detail_exit(1);
}
None => None,
}

View File

@ -32,7 +32,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F
code, run `./x.py fmt` instead.",
cmd_debug,
);
std::process::exit(1);
crate::detail_exit(1);
}
}
}
@ -114,7 +114,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| {
eprintln!("./x.py fmt is not supported on this channel");
std::process::exit(1);
crate::detail_exit(1);
});
assert!(rustfmt_path.exists(), "{}", rustfmt_path.display());
let src = build.src.clone();

View File

@ -109,7 +109,7 @@ use std::env;
use std::fs::{self, File};
use std::io;
use std::path::{Path, PathBuf};
use std::process::{self, Command};
use std::process::Command;
use std::str;
use filetime::FileTime;
@ -711,7 +711,7 @@ impl Build {
for failure in failures.iter() {
eprintln!(" - {}\n", failure);
}
process::exit(1);
detail_exit(1);
}
#[cfg(feature = "build-metrics")]
@ -1617,7 +1617,7 @@ Alternatively, set `download-ci-llvm = true` in that `[llvm]` section
to download LLVM rather than building it.
"
);
std::process::exit(1);
detail_exit(1);
}
}
@ -1646,6 +1646,20 @@ fn chmod(path: &Path, perms: u32) {
#[cfg(windows)]
fn chmod(_path: &Path, _perms: u32) {}
/// If code is not 0 (successful exit status), exit status is 101 (rust's default error code.)
/// If the test is running and code is an error code, it will cause a panic.
fn detail_exit(code: i32) -> ! {
// Successful exit
if code == 0 {
std::process::exit(0);
}
if cfg!(test) {
panic!("status code: {}", code);
} else {
std::panic::resume_unwind(Box::new(code));
}
}
impl Compiler {
pub fn with_stage(mut self, stage: u32) -> Compiler {
self.stage = stage;

View File

@ -104,7 +104,7 @@ You should install cmake, or set `download-ci-llvm = true` in the
than building it.
"
);
std::process::exit(1);
crate::detail_exit(1);
}
}

View File

@ -94,7 +94,7 @@ pub fn setup(config: &Config, profile: Profile) {
"note: this will use the configuration in {}",
profile.include_path(&config.src).display()
);
std::process::exit(1);
crate::detail_exit(1);
}
let settings = format!(
@ -287,7 +287,7 @@ pub fn interactive_path() -> io::Result<Profile> {
io::stdin().read_line(&mut input)?;
if input.is_empty() {
eprintln!("EOF on stdin, when expecting answer to question. Giving up.");
std::process::exit(1);
crate::detail_exit(1);
}
break match parse_with_abbrev(&input) {
Ok(profile) => profile,

View File

@ -673,7 +673,7 @@ impl Step for Clippy {
}
if !builder.config.cmd.bless() {
std::process::exit(1);
crate::detail_exit(1);
}
let mut cargo = builder.cargo(compiler, Mode::ToolRustc, SourceType::InTree, host, "run");
@ -1021,7 +1021,7 @@ help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy`
PATH = inferred_rustfmt_dir.display(),
CHAN = builder.config.channel,
);
std::process::exit(1);
crate::detail_exit(1);
}
crate::format::format(&builder, !builder.config.cmd.bless(), &[]);
}
@ -1251,7 +1251,7 @@ help: to test the compiler, use `--stage 1` instead
help: to test the standard library, use `--stage 0 library/std` instead
note: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `COMPILETEST_FORCE_STAGE0=1`."
);
std::process::exit(1);
crate::detail_exit(1);
}
let compiler = self.compiler;

View File

@ -2,7 +2,7 @@ use std::collections::HashSet;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{exit, Command};
use std::process::Command;
use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step};
use crate::channel::GitInfo;
@ -204,7 +204,7 @@ impl Step for ToolBuild {
if !is_expected {
if !is_optional_tool {
exit(1);
crate::detail_exit(1);
} else {
None
}

View File

@ -93,7 +93,7 @@ fn print_error(tool: &str, submodule: &str) {
eprintln!("If you do NOT intend to update '{}', please ensure you did not accidentally", tool);
eprintln!("change the submodule at '{}'. You may ask your reviewer for the", submodule);
eprintln!("proper steps.");
std::process::exit(3);
crate::detail_exit(3);
}
fn check_changed_files(toolstates: &HashMap<Box<str>, ToolState>) {
@ -108,7 +108,7 @@ fn check_changed_files(toolstates: &HashMap<Box<str>, ToolState>) {
Ok(o) => o,
Err(e) => {
eprintln!("Failed to get changed files: {:?}", e);
std::process::exit(1);
crate::detail_exit(1);
}
};
@ -179,7 +179,7 @@ impl Step for ToolStateCheck {
}
if did_error {
std::process::exit(1);
crate::detail_exit(1);
}
check_changed_files(&toolstates);
@ -225,7 +225,7 @@ impl Step for ToolStateCheck {
}
if did_error {
std::process::exit(1);
crate::detail_exit(1);
}
if builder.config.channel == "nightly" && env::var_os("TOOLSTATE_PUBLISH").is_some() {

View File

@ -336,7 +336,7 @@ pub fn is_valid_test_suite_arg<'a, P: AsRef<Path>>(
pub fn run(cmd: &mut Command, print_cmd_on_fail: bool) {
if !try_run(cmd, print_cmd_on_fail) {
std::process::exit(1);
crate::detail_exit(1);
}
}
@ -375,7 +375,7 @@ pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
pub fn run_suppressed(cmd: &mut Command) {
if !try_run_suppressed(cmd) {
std::process::exit(1);
crate::detail_exit(1);
}
}
@ -465,7 +465,7 @@ fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool {
fn fail(s: &str) -> ! {
eprintln!("\n\n{}\n\n", s);
std::process::exit(1);
crate::detail_exit(1);
}
/// Copied from `std::path::absolute` until it stabilizes.

View File

@ -268,6 +268,12 @@ impl clean::Generics {
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) enum Ending {
Newline,
NoNewline,
}
/// * The Generics from which to emit a where-clause.
/// * The number of spaces to indent each line with.
/// * Whether the where-clause needs to add a comma and newline after the last bound.
@ -275,7 +281,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
gens: &'a clean::Generics,
cx: &'a Context<'tcx>,
indent: usize,
end_newline: bool,
ending: Ending,
) -> impl fmt::Display + 'a + Captures<'tcx> {
use fmt::Write;
@ -342,7 +348,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
let where_preds = comma_sep(where_predicates, false);
let clause = if f.alternate() {
if end_newline {
if ending == Ending::Newline {
// add a space so stripping <br> tags and breaking spaces still renders properly
format!(" where{where_preds}, ")
} else {
@ -356,7 +362,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
}
let where_preds = where_preds.to_string().replace("<br>", &br_with_padding);
if end_newline {
if ending == Ending::Newline {
let mut clause = "&nbsp;".repeat(indent.saturating_sub(1));
// add a space so stripping <br> tags and breaking spaces still renders properly
write!(
@ -1167,7 +1173,7 @@ impl clean::Impl {
fmt_type(&self.for_, f, use_absolute, cx)?;
}
fmt::Display::fmt(&print_where_clause(&self.generics, cx, 0, true), f)?;
fmt::Display::fmt(&print_where_clause(&self.generics, cx, 0, Ending::Newline), f)?;
Ok(())
})
}

View File

@ -70,7 +70,7 @@ use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
use crate::html::format::{
href, join_with_double_colon, print_abi_with_space, print_constness_with_space,
print_default_space, print_generic_bounds, print_where_clause, Buffer, HrefError,
print_default_space, print_generic_bounds, print_where_clause, Buffer, Ending, HrefError,
PrintWithSpace,
};
use crate::html::highlight;
@ -747,7 +747,7 @@ fn assoc_type(
if !bounds.is_empty() {
write!(w, ": {}", print_generic_bounds(bounds, cx))
}
write!(w, "{}", print_where_clause(generics, cx, indent, false));
write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline));
if let Some(default) = default {
write!(w, " = {}", default.print(cx))
}
@ -796,10 +796,10 @@ fn assoc_method(
header_len += 4;
let indent_str = " ";
render_attributes_in_pre(w, meth, indent_str);
(4, indent_str, false)
(4, indent_str, Ending::NoNewline)
} else {
render_attributes_in_code(w, meth);
(0, "", true)
(0, "", Ending::Newline)
};
w.reserve(header_len + "<a href=\"\" class=\"fnname\">{".len() + "</a>".len());
write!(

View File

@ -29,7 +29,7 @@ use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape;
use crate::html::format::{
join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause,
Buffer, PrintWithSpace,
Buffer, Ending, PrintWithSpace,
};
use crate::html::highlight;
use crate::html::layout::Page;
@ -69,7 +69,7 @@ fn print_where_clause_and_check<'a, 'tcx: 'a>(
cx: &'a Context<'tcx>,
) -> bool {
let len_before = buffer.len();
write!(buffer, "{}", print_where_clause(gens, cx, 0, true));
write!(buffer, "{}", print_where_clause(gens, cx, 0, Ending::Newline));
len_before != buffer.len()
}
@ -519,7 +519,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
abi = abi,
name = name,
generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx, 0, true),
where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline),
decl = f.decl.full_print(header_len, 0, header.asyncness, cx),
notable_traits = notable_traits_decl(&f.decl, cx),
);
@ -556,7 +556,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
);
if !t.generics.where_predicates.is_empty() {
write!(w, "{}", print_where_clause(&t.generics, cx, 0, true));
write!(w, "{}", print_where_clause(&t.generics, cx, 0, Ending::Newline));
} else {
w.write_str(" ");
}
@ -1025,7 +1025,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &
"trait {}{}{} = {};",
it.name.unwrap(),
t.generics.print(cx),
print_where_clause(&t.generics, cx, 0, true),
print_where_clause(&t.generics, cx, 0, Ending::Newline),
bounds(&t.bounds, true, cx)
);
});
@ -1049,7 +1049,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &cl
"type {}{}{where_clause} = impl {bounds};",
it.name.unwrap(),
t.generics.print(cx),
where_clause = print_where_clause(&t.generics, cx, 0, true),
where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
bounds = bounds(&t.bounds, false, cx),
);
});
@ -1074,7 +1074,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea
"type {}{}{where_clause} = {type_};",
it.name.unwrap(),
t.generics.print(cx),
where_clause = print_where_clause(&t.generics, cx, 0, true),
where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
type_ = t.type_.print(cx),
);
});
@ -1784,7 +1784,7 @@ fn render_struct(
}
w.write_str(")");
if let Some(g) = g {
write!(w, "{}", print_where_clause(g, cx, 0, false));
write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline));
}
// We only want a ";" when we are displaying a tuple struct, not a variant tuple struct.
if structhead {
@ -1794,7 +1794,7 @@ fn render_struct(
CtorKind::Const => {
// Needed for PhantomData.
if let Some(g) = g {
write!(w, "{}", print_where_clause(g, cx, 0, false));
write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline));
}
w.write_str(";");
}

View File

@ -303,7 +303,7 @@ pub(crate) fn run(
// Run call-finder on all items
let mut calls = FxHashMap::default();
let mut finder = FindCalls { calls: &mut calls, tcx, map: tcx.hir(), cx, target_crates };
tcx.hir().deep_visit_all_item_likes(&mut finder);
tcx.hir().visit_all_item_likes_in_crate(&mut finder);
// Sort call locations within a given file in document order
for fn_calls in calls.values_mut() {

View File

@ -0,0 +1,13 @@
// build-pass
#![feature(adt_const_params)]
#![allow(incomplete_features)]
pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
BYTES
}
pub fn main() {
assert_eq!(function_with_bytes::<b"AAAA">(), &[0x41, 0x41, 0x41, 0x41]);
assert_eq!(function_with_bytes::<{ &[0x41, 0x41, 0x41, 0x41] }>(), b"AAAA");
}

View File

@ -0,0 +1,13 @@
#![feature(adt_const_params)]
//~^ WARN the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features]
#[derive(PartialEq, Eq)]
enum Nat {
Z,
S(Box<Nat>),
}
fn foo<const N: Nat>() {}
//~^ ERROR `Box<Nat>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
fn main() {}

View File

@ -0,0 +1,18 @@
warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-80471.rs:1:12
|
LL | #![feature(adt_const_params)]
| ^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
error[E0741]: `Box<Nat>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
--> $DIR/issue-80471.rs:10:17
|
LL | fn foo<const N: Nat>() {}
| ^^^
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0741`.

View File

@ -16,12 +16,6 @@ error: no path from `WillChange` to `trait_def`
LL | #[rustc_then_this_would_need(trait_def)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:32:9
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:36:5
|
@ -52,36 +46,12 @@ error: OK
LL | #[rustc_then_this_would_need(type_of)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:48:9
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:49:9
|
LL | #[rustc_then_this_would_need(typeck)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:53:5
|
LL | #[rustc_then_this_would_need(type_of)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:55:9
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:56:9
|
LL | #[rustc_then_this_would_need(typeck)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:61:9
|
@ -106,12 +76,6 @@ error: no path from `WillChange` to `type_of`
LL | #[rustc_then_this_would_need(type_of)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: no path from `WillChange` to `fn_sig`
--> $DIR/dep-graph-struct-signature.rs:77:9
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: no path from `WillChange` to `fn_sig`
--> $DIR/dep-graph-struct-signature.rs:81:5
|
@ -130,5 +94,41 @@ error: no path from `WillChange` to `typeck`
LL | #[rustc_then_this_would_need(typeck)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:32:9
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: no path from `WillChange` to `fn_sig`
--> $DIR/dep-graph-struct-signature.rs:77:9
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:48:9
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:49:9
|
LL | #[rustc_then_this_would_need(typeck)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:55:9
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:56:9
|
LL | #[rustc_then_this_would_need(typeck)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 22 previous errors

View File

@ -28,30 +28,12 @@ error: no path from `TypeAlias` to `type_of`
LL | #[rustc_then_this_would_need(type_of)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:36:5
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: no path from `TypeAlias` to `type_of`
--> $DIR/dep-graph-type-alias.rs:42:1
|
LL | #[rustc_then_this_would_need(type_of)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:44:5
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:45:5
|
LL | #[rustc_then_this_would_need(typeck)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:49:1
|
@ -70,5 +52,23 @@ error: OK
LL | #[rustc_then_this_would_need(typeck)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:36:5
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:44:5
|
LL | #[rustc_then_this_would_need(fn_sig)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:45:5
|
LL | #[rustc_then_this_would_need(typeck)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 12 previous errors

View File

@ -1,4 +1,4 @@
pub enum Test { //~ HELP consider adding `#[derive(Default)]` to this enum
pub enum Test { //~ HELP consider adding a derive
#[default]
//~^ ERROR cannot find attribute `default` in this scope
First,

View File

@ -4,11 +4,11 @@ error: cannot find attribute `default` in this scope
LL | #[default]
| ^^^^^^^
|
help: consider adding `#[derive(Default)]` to this enum
--> $DIR/suggest-default-attribute.rs:1:1
help: consider adding a derive
|
LL + #[derive(Default)]
LL ~ pub enum Test {
|
LL | pub enum Test {
| ^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed
--> $DIR/intrinsic-raw_eq-const-padding.rs:6:5
|
LL | std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading 4 bytes of memory starting at alloc3, but 1 byte is uninitialized starting at alloc3+0x1, and this operation requires initialized memory
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at alloc3[0x0..0x4], but memory is uninitialized at [0x1..0x2], and this operation requires initialized memory
error: aborting due to previous error

View File

@ -4,12 +4,6 @@ error: function has missing const stability attribute
LL | pub const fn foo() {}
| ^^^^^^^^^^^^^^^^^^^^^
error: associated function has missing const stability attribute
--> $DIR/missing-const-stability.rs:15:5
|
LL | pub const fn foo() {}
| ^^^^^^^^^^^^^^^^^^^^^
error: implementation has missing const stability attribute
--> $DIR/missing-const-stability.rs:27:1
|
@ -19,5 +13,11 @@ LL | | fn fun() {}
LL | | }
| |_^
error: associated function has missing const stability attribute
--> $DIR/missing-const-stability.rs:15:5
|
LL | pub const fn foo() {}
| ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors