Auto merge of #127777 - matthiaskrgr:rollup-qp2vkan, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #124921 (offset_from: always allow pointers to point to the same address)
 - #127407 (Make parse error suggestions verbose and fix spans)
 - #127684 (consolidate miri-unleashed tests for mutable refs into one file)
 - #127729 (Stop using the `gen` identifier in the compiler)
 - #127736 (Add myself to the review rotation)
 - #127758 (coverage: Restrict `ExpressionUsed` simplification to `Code` mappings)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-15 19:44:22 +00:00
commit 24d2ac0b56
199 changed files with 3638 additions and 1362 deletions

View File

@ -553,7 +553,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> {
panic!("could not find BorrowIndex for location {location:?}");
});
trans.gen(index);
trans.gen_(index);
}
// Make sure there are no remaining borrows for variables

View File

@ -66,8 +66,15 @@ impl<'tcx> FunctionCoverageCollector<'tcx> {
// For each expression ID that is directly used by one or more mappings,
// mark it as not-yet-seen. This indicates that we expect to see a
// corresponding `ExpressionUsed` statement during MIR traversal.
for term in function_coverage_info.mappings.iter().flat_map(|m| m.kind.terms()) {
if let CovTerm::Expression(id) = term {
for mapping in function_coverage_info.mappings.iter() {
// Currently we only worry about ordinary code mappings.
// For branch and MC/DC mappings, expressions might not correspond
// to any particular point in the control-flow graph.
// (Keep this in sync with the injection of `ExpressionUsed`
// statements in the `InstrumentCoverage` MIR pass.)
if let MappingKind::Code(term) = mapping.kind
&& let CovTerm::Expression(id) = term
{
expressions_seen.remove(id);
}
}

View File

@ -20,7 +20,7 @@ use super::{
err_inval, err_ub_custom, err_unsup_format, memory::MemoryKind, throw_inval, throw_ub_custom,
throw_ub_format, util::ensure_monomorphic_enough, Allocation, CheckInAllocMsg, ConstAllocation,
GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Pointer, PointerArithmetic,
Scalar,
Provenance, Scalar,
};
use crate::fluent_generated as fluent;
@ -259,25 +259,28 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// This will always return 0.
(a, b)
}
(Err(_), _) | (_, Err(_)) => {
// We managed to find a valid allocation for one pointer, but not the other.
// That means they are definitely not pointing to the same allocation.
_ if M::Provenance::OFFSET_IS_ADDR && a.addr() == b.addr() => {
// At least one of the pointers has provenance, but they also point to
// the same address so it doesn't matter; this is fine. `(0, 0)` means
// we pass all the checks below and return 0.
(0, 0)
}
// From here onwards, the pointers are definitely for different addresses
// (or we can't determine their absolute address).
(Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _)))
if a_alloc_id == b_alloc_id =>
{
// Found allocation for both, and it's the same.
// Use these offsets for distance calculation.
(a_offset.bytes(), b_offset.bytes())
}
_ => {
// Not into the same allocation -- this is UB.
throw_ub_custom!(
fluent::const_eval_offset_from_different_allocations,
name = intrinsic_name,
);
}
(Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _))) => {
// Found allocation for both. They must be into the same allocation.
if a_alloc_id != b_alloc_id {
throw_ub_custom!(
fluent::const_eval_offset_from_different_allocations,
name = intrinsic_name,
);
}
// Use these offsets for distance calculation.
(a_offset.bytes(), b_offset.bytes())
}
};
// Compute distance.

View File

@ -3218,10 +3218,10 @@ impl<'hir> Item<'hir> {
ItemKind::Static(ty, mutbl, body), (ty, *mutbl, *body);
expect_const, (&'hir Ty<'hir>, &'hir Generics<'hir>, BodyId),
ItemKind::Const(ty, gen, body), (ty, gen, *body);
ItemKind::Const(ty, generics, body), (ty, generics, *body);
expect_fn, (&FnSig<'hir>, &'hir Generics<'hir>, BodyId),
ItemKind::Fn(sig, gen, body), (sig, gen, *body);
ItemKind::Fn(sig, generics, body), (sig, generics, *body);
expect_macro, (&ast::MacroDef, MacroKind), ItemKind::Macro(def, mk), (def, *mk);
@ -3233,25 +3233,25 @@ impl<'hir> Item<'hir> {
expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm(asm), asm;
expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
ItemKind::TyAlias(ty, gen), (ty, gen);
ItemKind::TyAlias(ty, generics), (ty, generics);
expect_opaque_ty, &OpaqueTy<'hir>, ItemKind::OpaqueTy(ty), ty;
expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, gen), (def, gen);
expect_enum, (&EnumDef<'hir>, &'hir Generics<'hir>), ItemKind::Enum(def, generics), (def, generics);
expect_struct, (&VariantData<'hir>, &'hir Generics<'hir>),
ItemKind::Struct(data, gen), (data, gen);
ItemKind::Struct(data, generics), (data, generics);
expect_union, (&VariantData<'hir>, &'hir Generics<'hir>),
ItemKind::Union(data, gen), (data, gen);
ItemKind::Union(data, generics), (data, generics);
expect_trait,
(IsAuto, Safety, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemRef]),
ItemKind::Trait(is_auto, safety, gen, bounds, items),
(*is_auto, *safety, gen, bounds, items);
ItemKind::Trait(is_auto, safety, generics, bounds, items),
(*is_auto, *safety, generics, bounds, items);
expect_trait_alias, (&'hir Generics<'hir>, GenericBounds<'hir>),
ItemKind::TraitAlias(gen, bounds), (gen, bounds);
ItemKind::TraitAlias(generics, bounds), (generics, bounds);
expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp;
}

View File

@ -2554,7 +2554,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.and_then(|node| node.generics())
.into_iter()
.flat_map(|generics| generics.params)
.find(|gen| &gen.def_id.to_def_id() == res_def_id)
.find(|param| &param.def_id.to_def_id() == res_def_id)
} else {
None
}

View File

@ -71,6 +71,8 @@ impl<'a> DiagnosticDerive<'a> {
});
// A lifetime of `'a` causes conflicts, but `_sess` is fine.
// FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here?
#[allow(keyword_idents_2024)]
let mut imp = structure.gen_impl(quote! {
gen impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for @Self
where G: rustc_errors::EmissionGuarantee
@ -148,6 +150,8 @@ impl<'a> LintDiagnosticDerive<'a> {
}
});
// FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here?
#[allow(keyword_idents_2024)]
let mut imp = structure.gen_impl(quote! {
gen impl<'__a> rustc_errors::LintDiagnostic<'__a, ()> for @Self {
#[track_caller]

View File

@ -86,6 +86,9 @@ impl SubdiagnosticDerive {
let diag = &self.diag;
let f = &self.f;
// FIXME(edition_2024): Fix the `keyword_idents_2024` lint to not trigger here?
#[allow(keyword_idents_2024)]
let ret = structure.gen_impl(quote! {
gen impl rustc_errors::Subdiagnostic for @Self {
fn add_to_diag_with<__G, __F>(
@ -100,6 +103,7 @@ impl SubdiagnosticDerive {
}
}
});
ret
}
}

View File

@ -220,19 +220,6 @@ pub enum MappingKind {
}
impl MappingKind {
/// Iterator over all coverage terms in this mapping kind.
pub fn terms(&self) -> impl Iterator<Item = CovTerm> {
let zero = || None.into_iter().chain(None);
let one = |a| Some(a).into_iter().chain(None);
let two = |a, b| Some(a).into_iter().chain(Some(b));
match *self {
Self::Code(term) => one(term),
Self::Branch { true_term, false_term } => two(true_term, false_term),
Self::MCDCBranch { true_term, false_term, .. } => two(true_term, false_term),
Self::MCDCDecision(_) => zero(),
}
}
/// Returns a copy of this mapping kind, in which all coverage terms have
/// been replaced with ones returned by the given function.
pub fn map_terms(&self, map_fn: impl Fn(CovTerm) -> CovTerm) -> Self {

View File

@ -1016,14 +1016,14 @@ macro_rules! extra_body_methods {
macro_rules! super_body {
($self:ident, $body:ident, $($mutability:ident, $invalidate:tt)?) => {
let span = $body.span;
if let Some(gen) = &$($mutability)? $body.coroutine {
if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
if let Some(coroutine) = &$($mutability)? $body.coroutine {
if let Some(yield_ty) = $(& $mutability)? coroutine.yield_ty {
$self.visit_ty(
yield_ty,
TyContext::YieldTy(SourceInfo::outermost(span))
);
}
if let Some(resume_ty) = $(& $mutability)? gen.resume_ty {
if let Some(resume_ty) = $(& $mutability)? coroutine.resume_ty {
$self.visit_ty(
resume_ty,
TyContext::ResumeTy(SourceInfo::outermost(span))

View File

@ -402,7 +402,7 @@ where
/// building up a `GenKillSet` and then throwing it away.
pub trait GenKill<T> {
/// Inserts `elem` into the state vector.
fn gen(&mut self, elem: T);
fn gen_(&mut self, elem: T);
/// Removes `elem` from the state vector.
fn kill(&mut self, elem: T);
@ -410,7 +410,7 @@ pub trait GenKill<T> {
/// Calls `gen` for each element in `elems`.
fn gen_all(&mut self, elems: impl IntoIterator<Item = T>) {
for elem in elems {
self.gen(elem);
self.gen_(elem);
}
}
@ -424,12 +424,12 @@ pub trait GenKill<T> {
/// Stores a transfer function for a gen/kill problem.
///
/// Calling `gen`/`kill` on a `GenKillSet` will "build up" a transfer function so that it can be
/// applied multiple times efficiently. When there are multiple calls to `gen` and/or `kill` for
/// Calling `gen_`/`kill` on a `GenKillSet` will "build up" a transfer function so that it can be
/// applied multiple times efficiently. When there are multiple calls to `gen_` and/or `kill` for
/// the same element, the most recent one takes precedence.
#[derive(Clone)]
pub struct GenKillSet<T> {
gen: HybridBitSet<T>,
gen_: HybridBitSet<T>,
kill: HybridBitSet<T>,
}
@ -437,31 +437,31 @@ impl<T: Idx> GenKillSet<T> {
/// Creates a new transfer function that will leave the dataflow state unchanged.
pub fn identity(universe: usize) -> Self {
GenKillSet {
gen: HybridBitSet::new_empty(universe),
gen_: HybridBitSet::new_empty(universe),
kill: HybridBitSet::new_empty(universe),
}
}
pub fn apply(&self, state: &mut impl BitSetExt<T>) {
state.union(&self.gen);
state.union(&self.gen_);
state.subtract(&self.kill);
}
}
impl<T: Idx> GenKill<T> for GenKillSet<T> {
fn gen(&mut self, elem: T) {
self.gen.insert(elem);
fn gen_(&mut self, elem: T) {
self.gen_.insert(elem);
self.kill.remove(elem);
}
fn kill(&mut self, elem: T) {
self.kill.insert(elem);
self.gen.remove(elem);
self.gen_.remove(elem);
}
}
impl<T: Idx> GenKill<T> for BitSet<T> {
fn gen(&mut self, elem: T) {
fn gen_(&mut self, elem: T) {
self.insert(elem);
}
@ -471,7 +471,7 @@ impl<T: Idx> GenKill<T> for BitSet<T> {
}
impl<T: Idx> GenKill<T> for ChunkedBitSet<T> {
fn gen(&mut self, elem: T) {
fn gen_(&mut self, elem: T) {
self.insert(elem);
}
@ -481,11 +481,11 @@ impl<T: Idx> GenKill<T> for ChunkedBitSet<T> {
}
impl<T, S: GenKill<T>> GenKill<T> for MaybeReachable<S> {
fn gen(&mut self, elem: T) {
fn gen_(&mut self, elem: T) {
match self {
// If the state is not reachable, adding an element does nothing.
MaybeReachable::Unreachable => {}
MaybeReachable::Reachable(set) => set.gen(elem),
MaybeReachable::Reachable(set) => set.gen_(elem),
}
}
@ -499,7 +499,7 @@ impl<T, S: GenKill<T>> GenKill<T> for MaybeReachable<S> {
}
impl<T: Idx> GenKill<T> for lattice::Dual<BitSet<T>> {
fn gen(&mut self, elem: T) {
fn gen_(&mut self, elem: T) {
self.0.insert(elem);
}

View File

@ -97,7 +97,7 @@ where
Rvalue::AddressOf(_, borrowed_place)
| Rvalue::Ref(_, BorrowKind::Mut { .. } | BorrowKind::Shared, borrowed_place) => {
if !borrowed_place.is_indirect() {
self.trans.gen(borrowed_place.local);
self.trans.gen_(borrowed_place.local);
}
}
@ -131,7 +131,7 @@ where
//
// [#61069]: https://github.com/rust-lang/rust/pull/61069
if !dropped_place.is_indirect() {
self.trans.gen(dropped_place.local);
self.trans.gen_(dropped_place.local);
}
}
@ -159,8 +159,8 @@ pub fn borrowed_locals(body: &Body<'_>) -> BitSet<Local> {
impl GenKill<Local> for Borrowed {
#[inline]
fn gen(&mut self, elem: Local) {
self.0.gen(elem)
fn gen_(&mut self, elem: Local) {
self.0.gen_(elem)
}
#[inline]
fn kill(&mut self, _: Local) {

View File

@ -283,7 +283,7 @@ impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
) {
match state {
DropFlagState::Absent => trans.kill(path),
DropFlagState::Present => trans.gen(path),
DropFlagState::Present => trans.gen_(path),
}
}
}
@ -295,7 +295,7 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, '_, 'tcx> {
state: DropFlagState,
) {
match state {
DropFlagState::Absent => trans.gen(path),
DropFlagState::Absent => trans.gen_(path),
DropFlagState::Present => trans.kill(path),
}
}
@ -309,7 +309,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
) {
match state {
DropFlagState::Absent => trans.kill(path),
DropFlagState::Present => trans.gen(path),
DropFlagState::Present => trans.gen_(path),
}
}
}
@ -331,7 +331,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
MaybeReachable::Reachable(ChunkedBitSet::new_empty(self.move_data().move_paths.len()));
drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| {
assert!(s == DropFlagState::Present);
state.gen(path);
state.gen_(path);
});
}
}
@ -362,7 +362,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
&& let LookupResult::Exact(mpi) = self.move_data().rev_lookup.find(place.as_ref())
{
on_all_children_bits(self.move_data(), mpi, |child| {
trans.gen(child);
trans.gen_(child);
})
}
}
@ -400,7 +400,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
self.move_data(),
self.move_data().rev_lookup.find(place.as_ref()),
|mpi| {
trans.gen(mpi);
trans.gen_(mpi);
},
);
});
@ -572,7 +572,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
self.move_data(),
enum_place,
variant,
|mpi| trans.gen(mpi),
|mpi| trans.gen_(mpi),
);
});
}
@ -643,7 +643,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
self.move_data(),
self.move_data().rev_lookup.find(place.as_ref()),
|mpi| {
trans.gen(mpi);
trans.gen_(mpi);
},
);
});
@ -738,7 +738,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> {
let call_loc = self.body.terminator_loc(block);
for init_index in &init_loc_map[call_loc] {
trans.gen(*init_index);
trans.gen_(*init_index);
}
}
}

View File

@ -116,7 +116,7 @@ where
self.0.kill(place.local);
}
}
Some(DefUse::Use) => self.0.gen(place.local),
Some(DefUse::Use) => self.0.gen_(place.local),
None => {}
}
@ -154,7 +154,7 @@ impl DefUse {
fn apply(trans: &mut impl GenKill<Local>, place: Place<'_>, context: PlaceContext) {
match DefUse::for_place(place, context) {
Some(DefUse::Def) => trans.kill(place.local),
Some(DefUse::Use) => trans.gen(place.local),
Some(DefUse::Use) => trans.gen_(place.local),
None => {}
}
}

View File

@ -54,7 +54,7 @@ impl<'tcx, 'a> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> {
_: Location,
) {
match stmt.kind {
StatementKind::StorageLive(l) => trans.gen(l),
StatementKind::StorageLive(l) => trans.gen_(l),
StatementKind::StorageDead(l) => trans.kill(l),
_ => (),
}
@ -127,7 +127,7 @@ impl<'tcx, 'a> crate::GenKillAnalysis<'tcx> for MaybeStorageDead<'a> {
) {
match stmt.kind {
StatementKind::StorageLive(l) => trans.kill(l),
StatementKind::StorageDead(l) => trans.gen(l),
StatementKind::StorageDead(l) => trans.gen_(l),
_ => (),
}
}
@ -208,7 +208,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
StatementKind::Assign(box (place, _))
| StatementKind::SetDiscriminant { box place, .. }
| StatementKind::Deinit(box place) => {
trans.gen(place.local);
trans.gen_(place.local);
}
// Nothing to do for these. Match exhaustively so this fails to compile when new
@ -250,7 +250,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
match &terminator.kind {
TerminatorKind::Call { destination, .. } => {
trans.gen(destination.local);
trans.gen_(destination.local);
}
// Note that we do *not* gen the `resume_arg` of `Yield` terminators. The reason for
@ -265,7 +265,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
InlineAsmOperand::Out { place, .. }
| InlineAsmOperand::InOut { out_place: place, .. } => {
if let Some(place) = place {
trans.gen(place.local);
trans.gen_(place.local);
}
}
InlineAsmOperand::In { .. }
@ -341,7 +341,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
_block: BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
return_places.for_each(|place| trans.gen(place.local));
return_places.for_each(|place| trans.gen_(place.local));
}
}

View File

@ -56,6 +56,10 @@ pub(super) struct MCDCDecision {
#[derive(Default)]
pub(super) struct ExtractedMappings {
/// Store our own copy of [`CoverageGraph::num_nodes`], so that we don't
/// need access to the whole graph when allocating per-BCB data. This is
/// only public so that other code can still use exhaustive destructuring.
pub(super) num_bcbs: usize,
pub(super) code_mappings: Vec<CodeMapping>,
pub(super) branch_pairs: Vec<BranchPair>,
pub(super) mcdc_bitmap_bytes: u32,
@ -106,6 +110,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
);
ExtractedMappings {
num_bcbs: basic_coverage_blocks.num_nodes(),
code_mappings,
branch_pairs,
mcdc_bitmap_bytes,
@ -115,12 +120,10 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>(
}
impl ExtractedMappings {
pub(super) fn all_bcbs_with_counter_mappings(
&self,
basic_coverage_blocks: &CoverageGraph, // Only used for allocating a correctly-sized set
) -> BitSet<BasicCoverageBlock> {
pub(super) fn all_bcbs_with_counter_mappings(&self) -> BitSet<BasicCoverageBlock> {
// Fully destructure self to make sure we don't miss any fields that have mappings.
let Self {
num_bcbs,
code_mappings,
branch_pairs,
mcdc_bitmap_bytes: _,
@ -129,7 +132,7 @@ impl ExtractedMappings {
} = self;
// Identify which BCBs have one or more mappings.
let mut bcbs_with_counter_mappings = BitSet::new_empty(basic_coverage_blocks.num_nodes());
let mut bcbs_with_counter_mappings = BitSet::new_empty(*num_bcbs);
let mut insert = |bcb| {
bcbs_with_counter_mappings.insert(bcb);
};
@ -156,6 +159,15 @@ impl ExtractedMappings {
bcbs_with_counter_mappings
}
/// Returns the set of BCBs that have one or more `Code` mappings.
pub(super) fn bcbs_with_ordinary_code_mappings(&self) -> BitSet<BasicCoverageBlock> {
let mut bcbs = BitSet::new_empty(self.num_bcbs);
for &CodeMapping { span: _, bcb } in &self.code_mappings {
bcbs.insert(bcb);
}
bcbs
}
}
fn resolve_block_markers(

View File

@ -25,7 +25,7 @@ use rustc_span::source_map::SourceMap;
use rustc_span::{BytePos, Pos, RelativeBytePos, Span, Symbol};
use crate::coverage::counters::{CounterIncrementSite, CoverageCounters};
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
use crate::coverage::graph::CoverageGraph;
use crate::coverage::mappings::ExtractedMappings;
use crate::MirPass;
@ -88,8 +88,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
// every coverage span has a `Counter` or `Expression` assigned to its `BasicCoverageBlock`
// and all `Expression` dependencies (operands) are also generated, for any other
// `BasicCoverageBlock`s not already associated with a coverage span.
let bcbs_with_counter_mappings =
extracted_mappings.all_bcbs_with_counter_mappings(&basic_coverage_blocks);
let bcbs_with_counter_mappings = extracted_mappings.all_bcbs_with_counter_mappings();
if bcbs_with_counter_mappings.is_empty() {
// No relevant spans were found in MIR, so skip instrumenting this function.
return;
@ -109,7 +108,7 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
inject_coverage_statements(
mir_body,
&basic_coverage_blocks,
bcb_has_counter_mappings,
&extracted_mappings,
&coverage_counters,
);
@ -163,6 +162,7 @@ fn create_mappings<'tcx>(
// Fully destructure the mappings struct to make sure we don't miss any kinds.
let ExtractedMappings {
num_bcbs: _,
code_mappings,
branch_pairs,
mcdc_bitmap_bytes: _,
@ -219,7 +219,7 @@ fn create_mappings<'tcx>(
fn inject_coverage_statements<'tcx>(
mir_body: &mut mir::Body<'tcx>,
basic_coverage_blocks: &CoverageGraph,
bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool,
extracted_mappings: &ExtractedMappings,
coverage_counters: &CoverageCounters,
) {
// Inject counter-increment statements into MIR.
@ -252,11 +252,16 @@ fn inject_coverage_statements<'tcx>(
// can check whether the injected statement survived MIR optimization.
// (BCB edges can't have spans, so we only need to process BCB nodes here.)
//
// We only do this for ordinary `Code` mappings, because branch and MC/DC
// mappings might have expressions that don't correspond to any single
// point in the control-flow graph.
//
// See the code in `rustc_codegen_llvm::coverageinfo::map_data` that deals
// with "expressions seen" and "zero terms".
let eligible_bcbs = extracted_mappings.bcbs_with_ordinary_code_mappings();
for (bcb, expression_id) in coverage_counters
.bcb_nodes_with_coverage_expressions()
.filter(|&(bcb, _)| bcb_has_coverage_spans(bcb))
.filter(|&(bcb, _)| eligible_bcbs.contains(bcb))
{
inject_statement(
mir_body,

View File

@ -1,7 +1,7 @@
parse_add_paren = try adding parentheses
parse_ambiguous_range_pattern = the range pattern here has ambiguous interpretation
.suggestion = add parentheses to clarify the precedence
parse_ambiguous_range_pattern_suggestion = add parentheses to clarify the precedence
parse_array_brackets_instead_of_braces = this is a block expression, not an array
.suggestion = to make an array, use square brackets instead of curly braces
@ -323,10 +323,10 @@ parse_incorrect_semicolon =
.suggestion = remove this semicolon
.help = {$name} declarations are not followed by a semicolon
parse_incorrect_use_of_await =
incorrect use of `await`
parse_incorrect_use_of_await = incorrect use of `await`
.parentheses_suggestion = `await` is not a method call, remove the parentheses
.postfix_suggestion = `await` is a postfix operation
parse_incorrect_use_of_await_postfix_suggestion = `await` is a postfix operation
parse_incorrect_visibility_restriction = incorrect visibility restriction
.help = some possible visibility restrictions are:
@ -644,7 +644,7 @@ parse_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call
.suggestion_no_fields_for_fn = if `{$type}` is a function, use the arguments directly
parse_parenthesized_lifetime = parenthesized lifetime bounds are not supported
.suggestion = remove the parentheses
parse_parenthesized_lifetime_suggestion = remove the parentheses
parse_path_single_colon = path separator must be a double colon
.suggestion = use a double colon instead

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,8 @@ use super::{
BlockMode, CommaRecoveryMode, Parser, PathStyle, Restrictions, SemiColonMode, SeqSep, TokenType,
};
use crate::errors::{
AmbiguousPlus, AsyncMoveBlockIn2015, AttributeOnParamType, BadQPathStage2, BadTypePlus,
BadTypePlusSub, ColonAsSemi, ComparisonOperatorsCannotBeChained,
AddParen, AmbiguousPlus, AsyncMoveBlockIn2015, AttributeOnParamType, AwaitSuggestion,
BadQPathStage2, BadTypePlus, BadTypePlusSub, ColonAsSemi, ComparisonOperatorsCannotBeChained,
ComparisonOperatorsCannotBeChainedSugg, ConstGenericWithoutBraces,
ConstGenericWithoutBracesSugg, DocCommentDoesNotDocumentAnything, DocCommentOnParamType,
DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg,
@ -566,7 +566,10 @@ impl<'a> Parser<'a> {
&& expected.iter().any(|tok| matches!(tok, TokenType::Token(TokenKind::Eq)))
{
// Likely typo: `=` → `==` in let expr or enum item
return Err(self.dcx().create_err(UseEqInstead { span: self.token.span }));
return Err(self.dcx().create_err(UseEqInstead {
span: self.token.span,
suggestion: self.token.span.with_lo(self.token.span.lo() + BytePos(1)),
}));
}
if self.token.is_keyword(kw::Move) && self.prev_token.is_keyword(kw::Async) {
@ -1151,7 +1154,7 @@ impl<'a> Parser<'a> {
// Eat from where we started until the end token so that parsing can continue
// as if we didn't have those extra angle brackets.
self.eat_to_tokens(end);
let span = lo.until(self.token.span);
let span = lo.to(self.prev_token.span);
let num_extra_brackets = number_of_gt + number_of_shr * 2;
return Some(self.dcx().emit_err(UnmatchedAngleBrackets { span, num_extra_brackets }));
@ -1539,7 +1542,10 @@ impl<'a> Parser<'a> {
pub(super) fn maybe_report_ambiguous_plus(&mut self, impl_dyn_multi: bool, ty: &Ty) {
if impl_dyn_multi {
self.dcx().emit_err(AmbiguousPlus { sum_ty: pprust::ty_to_string(ty), span: ty.span });
self.dcx().emit_err(AmbiguousPlus {
span: ty.span,
suggestion: AddParen { lo: ty.span.shrink_to_lo(), hi: ty.span.shrink_to_hi() },
});
}
}
@ -1604,25 +1610,14 @@ impl<'a> Parser<'a> {
}
self.bump(); // `+`
let bounds = self.parse_generic_bounds()?;
let _bounds = self.parse_generic_bounds()?;
let sum_span = ty.span.to(self.prev_token.span);
let sub = match &ty.kind {
TyKind::Ref(lifetime, mut_ty) => {
let sum_with_parens = pprust::to_string(|s| {
s.s.word("&");
s.print_opt_lifetime(lifetime);
s.print_mutability(mut_ty.mutbl, false);
s.popen();
s.print_type(&mut_ty.ty);
if !bounds.is_empty() {
s.word(" + ");
s.print_type_bounds(&bounds);
}
s.pclose()
});
BadTypePlusSub::AddParen { sum_with_parens, span: sum_span }
TyKind::Ref(_lifetime, mut_ty) => {
let lo = mut_ty.ty.span.shrink_to_lo();
let hi = self.prev_token.span.shrink_to_hi();
BadTypePlusSub::AddParen { suggestion: AddParen { lo, hi } }
}
TyKind::Ptr(..) | TyKind::BareFn(..) => BadTypePlusSub::ForgotParen { span: sum_span },
_ => BadTypePlusSub::ExpectPath { span: sum_span },
@ -1964,18 +1959,14 @@ impl<'a> Parser<'a> {
is_question: bool,
) -> (Span, ErrorGuaranteed) {
let span = lo.to(hi);
let applicability = match expr.kind {
ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
_ => Applicability::MachineApplicable,
};
let guar = self.dcx().emit_err(IncorrectAwait {
span,
sugg_span: (span, applicability),
expr: self.span_to_snippet(expr.span).unwrap_or_else(|_| pprust::expr_to_string(expr)),
question_mark: if is_question { "?" } else { "" },
suggestion: AwaitSuggestion {
removal: lo.until(expr.span),
dot_await: expr.span.shrink_to_hi(),
question_mark: if is_question { "?" } else { "" },
},
});
(span, guar)
}

View File

@ -714,7 +714,7 @@ impl<'a> Parser<'a> {
type_err.cancel();
self.dcx().emit_err(errors::MalformedLoopLabel {
span: label.ident.span,
correct_label: label.ident,
suggestion: label.ident.span.shrink_to_lo(),
});
return Ok(expr);
}
@ -856,7 +856,7 @@ impl<'a> Parser<'a> {
let hi = self.interpolated_or_expr_span(&expr);
let span = lo.to(hi);
if let Some(lt) = lifetime {
self.error_remove_borrow_lifetime(span, lt.ident.span);
self.error_remove_borrow_lifetime(span, lt.ident.span.until(expr.span));
}
Ok((span, ExprKind::AddrOf(borrow_kind, mutbl, expr)))
}
@ -1653,6 +1653,7 @@ impl<'a> Parser<'a> {
let lo = label_.ident.span;
let label = Some(label_);
let ate_colon = self.eat(&token::Colon);
let tok_sp = self.token.span;
let expr = if self.eat_keyword(kw::While) {
self.parse_expr_while(label, lo)
} else if self.eat_keyword(kw::For) {
@ -1747,7 +1748,7 @@ impl<'a> Parser<'a> {
self.dcx().emit_err(errors::RequireColonAfterLabeledExpression {
span: expr.span,
label: lo,
label_end: lo.shrink_to_hi(),
label_end: lo.between(tok_sp),
});
}
@ -2106,7 +2107,7 @@ impl<'a> Parser<'a> {
self.bump();
self.dcx().emit_err(errors::FloatLiteralRequiresIntegerPart {
span: token.span,
correct: pprust::token_to_string(token).into_owned(),
suggestion: token.span.shrink_to_lo(),
});
}
}
@ -2741,7 +2742,7 @@ impl<'a> Parser<'a> {
if !attrs.is_empty()
&& let [x0 @ xn] | [x0, .., xn] = &*attrs.take_for_recovery(self.psess)
{
let attributes = x0.span.to(xn.span);
let attributes = x0.span.until(branch_span);
let last = xn.span;
let ctx = if is_ctx_else { "else" } else { "if" };
self.dcx().emit_err(errors::OuterAttributeNotAllowedOnIfElse {

View File

@ -2241,9 +2241,13 @@ impl<'a> Parser<'a> {
let kw_token = self.token.clone();
let kw_str = pprust::token_to_string(&kw_token);
let item = self.parse_item(ForceCollect::No)?;
let mut item = item.unwrap().span;
if self.token == token::Comma {
item = item.to(self.token.span);
}
self.dcx().emit_err(errors::NestedAdt {
span: kw_token.span,
item: item.unwrap().span,
item,
kw_str,
keyword: keyword.as_str(),
});

View File

@ -4,11 +4,11 @@ use crate::errors::{
DotDotDotRestPattern, EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt,
ExpectedCommaAfterPatternField, GenericArgsInPatRequireTurbofishSyntax,
InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern,
PatternOnWrongSideOfAt, RemoveLet, RepeatedMutInPattern, SwitchRefBoxOrder,
TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg, TrailingVertNotAllowed,
UnexpectedExpressionInPattern, UnexpectedLifetimeInPattern, UnexpectedParenInRangePat,
UnexpectedParenInRangePatSugg, UnexpectedVertVertBeforeFunctionParam,
UnexpectedVertVertInPattern,
ParenRangeSuggestion, PatternOnWrongSideOfAt, RemoveLet, RepeatedMutInPattern,
SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg,
TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedLifetimeInPattern,
UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens,
};
use crate::parser::expr::{could_be_unclosed_char_literal, LhsExpr};
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
@ -24,7 +24,7 @@ use rustc_errors::{Applicability, Diag, PResult};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{ErrorGuaranteed, Span};
use rustc_span::{BytePos, ErrorGuaranteed, Span};
use thin_vec::{thin_vec, ThinVec};
#[derive(PartialEq, Copy, Clone)]
@ -236,11 +236,15 @@ impl<'a> Parser<'a> {
if let PatKind::Or(pats) = &pat.kind {
let span = pat.span;
let pat = pprust::pat_to_string(&pat);
let sub = if pats.len() == 1 {
Some(TopLevelOrPatternNotAllowedSugg::RemoveLeadingVert { span, pat })
Some(TopLevelOrPatternNotAllowedSugg::RemoveLeadingVert {
span: span.with_hi(span.lo() + BytePos(1)),
})
} else {
Some(TopLevelOrPatternNotAllowedSugg::WrapInParens { span, pat })
Some(TopLevelOrPatternNotAllowedSugg::WrapInParens {
span,
suggestion: WrapInParens { lo: span.shrink_to_lo(), hi: span.shrink_to_hi() },
})
};
let err = self.dcx().create_err(match syntax_loc {
@ -599,7 +603,10 @@ impl<'a> Parser<'a> {
self.bump(); // `...`
// The user probably mistook `...` for a rest pattern `..`.
self.dcx().emit_err(DotDotDotRestPattern { span: lo });
self.dcx().emit_err(DotDotDotRestPattern {
span: lo,
suggestion: lo.with_lo(lo.hi() - BytePos(1)),
});
PatKind::Rest
}
@ -664,8 +671,13 @@ impl<'a> Parser<'a> {
_ => return,
}
self.dcx()
.emit_err(AmbiguousRangePattern { span: pat.span, pat: pprust::pat_to_string(pat) });
self.dcx().emit_err(AmbiguousRangePattern {
span: pat.span,
suggestion: ParenRangeSuggestion {
lo: pat.span.shrink_to_lo(),
hi: pat.span.shrink_to_hi(),
},
});
}
/// Parse `&pat` / `&mut pat`.
@ -674,8 +686,11 @@ impl<'a> Parser<'a> {
if let token::Lifetime(name) = self.token.kind {
self.bump(); // `'a`
self.dcx()
.emit_err(UnexpectedLifetimeInPattern { span: self.prev_token.span, symbol: name });
self.dcx().emit_err(UnexpectedLifetimeInPattern {
span: self.prev_token.span,
symbol: name,
suggestion: self.prev_token.span.until(self.token.span),
});
}
let mutbl = self.parse_mutability();
@ -913,10 +928,13 @@ impl<'a> Parser<'a> {
self.dcx().emit_err(InclusiveRangeExtraEquals { span: span_with_eq })
}
token::Gt if no_space => {
let after_pat = span.with_hi(span.hi() - rustc_span::BytePos(1)).shrink_to_hi();
let after_pat = span.with_hi(span.hi() - BytePos(1)).shrink_to_hi();
self.dcx().emit_err(InclusiveRangeMatchArrow { span, arrow: tok.span, after_pat })
}
_ => self.dcx().emit_err(InclusiveRangeNoEnd { span }),
_ => self.dcx().emit_err(InclusiveRangeNoEnd {
span,
suggestion: span.with_lo(span.hi() - BytePos(1)),
}),
}
}

View File

@ -258,6 +258,7 @@ impl<'a> Parser<'a> {
self.bump(); // bump past the colon
self.dcx().emit_err(PathSingleColon {
span: self.prev_token.span,
suggestion: self.prev_token.span.shrink_to_hi(),
type_ascription: self
.psess
.unstable_features
@ -329,6 +330,7 @@ impl<'a> Parser<'a> {
err.cancel();
err = self.dcx().create_err(PathSingleColon {
span: self.token.span,
suggestion: self.prev_token.span.shrink_to_hi(),
type_ascription: self
.psess
.unstable_features

View File

@ -430,8 +430,10 @@ impl<'a> Parser<'a> {
let eq_consumed = match self.token.kind {
token::BinOpEq(..) => {
// Recover `let x <op>= 1` as `let x = 1`
self.dcx()
.emit_err(errors::CompoundAssignmentExpressionInLet { span: self.token.span });
self.dcx().emit_err(errors::CompoundAssignmentExpressionInLet {
span: self.token.span,
suggestion: self.token.span.with_hi(self.token.span.lo() + BytePos(1)),
});
self.bump();
true
}
@ -717,7 +719,7 @@ impl<'a> Parser<'a> {
e.cancel();
self.dcx().emit_err(MalformedLoopLabel {
span: label.ident.span,
correct_label: label.ident,
suggestion: label.ident.span.shrink_to_lo(),
});
*expr = labeled_expr;
break 'break_recover None;

View File

@ -209,6 +209,7 @@ impl<'a> Parser<'a> {
recover_qpath: RecoverQPath,
recover_return_sign: RecoverReturnSign,
) -> PResult<'a, FnRetTy> {
let lo = self.prev_token.span;
Ok(if self.eat(&token::RArrow) {
// FIXME(Centril): Can we unconditionally `allow_plus`?
let ty = self.parse_ty_common(
@ -224,7 +225,10 @@ impl<'a> Parser<'a> {
// Don't `eat` to prevent `=>` from being added as an expected token which isn't
// actually expected and could only confuse users
self.bump();
self.dcx().emit_err(ReturnTypesUseThinArrow { span: self.prev_token.span });
self.dcx().emit_err(ReturnTypesUseThinArrow {
span: self.prev_token.span,
suggestion: lo.between(self.token.span),
});
let ty = self.parse_ty_common(
allow_plus,
AllowCVariadic::No,
@ -794,8 +798,11 @@ impl<'a> Parser<'a> {
{
if self.token.is_keyword(kw::Dyn) {
// Account for `&dyn Trait + dyn Other`.
self.dcx().emit_err(InvalidDynKeyword { span: self.token.span });
self.bump();
self.dcx().emit_err(InvalidDynKeyword {
span: self.prev_token.span,
suggestion: self.prev_token.span.until(self.token.span),
});
}
bounds.push(self.parse_generic_bound()?);
if allow_plus == AllowPlus::No || !self.eat_plus() {
@ -861,7 +868,7 @@ impl<'a> Parser<'a> {
if has_parens {
// FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
// possibly introducing `GenericBound::Paren(P<GenericBound>)`?
self.recover_paren_lifetime(lo, lt.ident.span)?;
self.recover_paren_lifetime(lo)?;
}
Ok(bound)
}
@ -909,16 +916,12 @@ impl<'a> Parser<'a> {
}
/// Recover on `('lifetime)` with `(` already eaten.
fn recover_paren_lifetime(&mut self, lo: Span, lt_span: Span) -> PResult<'a, ()> {
fn recover_paren_lifetime(&mut self, lo: Span) -> PResult<'a, ()> {
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
let span = lo.to(self.prev_token.span);
let (sugg, snippet) = if let Ok(snippet) = self.span_to_snippet(lt_span) {
(Some(span), snippet)
} else {
(None, String::new())
};
let sugg = errors::RemoveParens { lo, hi: self.prev_token.span };
self.dcx().emit_err(errors::ParenthesizedLifetime { span, sugg, snippet });
self.dcx().emit_err(errors::ParenthesizedLifetime { span, sugg });
Ok(())
}

View File

@ -604,9 +604,9 @@ impl<T: ?Sized> *const T {
///
/// * `self` and `origin` must either
///
/// * point to the same address, or
/// * both be *derived from* a pointer to the same [allocated object], and the memory range between
/// the two pointers must be either empty or in bounds of that object. (See below for an example.)
/// * or both be derived from an integer literal/constant, and point to the same address.
/// the two pointers must be in bounds of that object. (See below for an example.)
///
/// * The distance between the pointers, in bytes, must be an exact multiple
/// of the size of `T`.
@ -653,14 +653,14 @@ impl<T: ?Sized> *const T {
/// let ptr1 = Box::into_raw(Box::new(0u8)) as *const u8;
/// let ptr2 = Box::into_raw(Box::new(1u8)) as *const u8;
/// let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
/// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
/// let ptr2_other = (ptr1 as *const u8).wrapping_offset(diff);
/// // Make ptr2_other an "alias" of ptr2.add(1), but derived from ptr1.
/// let ptr2_other = (ptr1 as *const u8).wrapping_offset(diff).wrapping_offset(1);
/// assert_eq!(ptr2 as usize, ptr2_other as usize);
/// // Since ptr2_other and ptr2 are derived from pointers to different objects,
/// // computing their offset is undefined behavior, even though
/// // they point to the same address!
/// // they point to addresses that are in-bounds of the same object!
/// unsafe {
/// let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
/// let one = ptr2_other.offset_from(ptr2); // Undefined Behavior! ⚠️
/// }
/// ```
#[stable(feature = "ptr_offset_from", since = "1.47.0")]

View File

@ -829,9 +829,9 @@ impl<T: ?Sized> *mut T {
///
/// * `self` and `origin` must either
///
/// * point to the same address, or
/// * both be *derived from* a pointer to the same [allocated object], and the memory range between
/// the two pointers must be either empty or in bounds of that object. (See below for an example.)
/// * or both be derived from an integer literal/constant, and point to the same address.
/// the two pointers must be in bounds of that object. (See below for an example.)
///
/// * The distance between the pointers, in bytes, must be an exact multiple
/// of the size of `T`.
@ -878,14 +878,14 @@ impl<T: ?Sized> *mut T {
/// let ptr1 = Box::into_raw(Box::new(0u8));
/// let ptr2 = Box::into_raw(Box::new(1u8));
/// let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
/// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
/// let ptr2_other = (ptr1 as *mut u8).wrapping_offset(diff);
/// // Make ptr2_other an "alias" of ptr2.add(1), but derived from ptr1.
/// let ptr2_other = (ptr1 as *mut u8).wrapping_offset(diff).wrapping_offset(1);
/// assert_eq!(ptr2 as usize, ptr2_other as usize);
/// // Since ptr2_other and ptr2 are derived from pointers to different objects,
/// // computing their offset is undefined behavior, even though
/// // they point to the same address!
/// // they point to addresses that are in-bounds of the same object!
/// unsafe {
/// let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
/// let one = ptr2_other.offset_from(ptr2); // Undefined Behavior! ⚠️
/// }
/// ```
#[stable(feature = "ptr_offset_from", since = "1.47.0")]

View File

@ -735,9 +735,9 @@ impl<T: ?Sized> NonNull<T> {
///
/// * `self` and `origin` must either
///
/// * point to the same address, or
/// * both be *derived from* a pointer to the same [allocated object], and the memory range between
/// the two pointers must be either empty or in bounds of that object. (See below for an example.)
/// * or both be derived from an integer literal/constant, and point to the same address.
/// the two pointers must be in bounds of that object. (See below for an example.)
///
/// * The distance between the pointers, in bytes, must be an exact multiple
/// of the size of `T`.
@ -789,14 +789,15 @@ impl<T: ?Sized> NonNull<T> {
/// let ptr1 = NonNull::new(Box::into_raw(Box::new(0u8))).unwrap();
/// let ptr2 = NonNull::new(Box::into_raw(Box::new(1u8))).unwrap();
/// let diff = (ptr2.addr().get() as isize).wrapping_sub(ptr1.addr().get() as isize);
/// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
/// let ptr2_other = NonNull::new(ptr1.as_ptr().wrapping_byte_offset(diff)).unwrap();
/// // Make ptr2_other an "alias" of ptr2.add(1), but derived from ptr1.
/// let diff_plus_1 = diff.wrapping_add(1);
/// let ptr2_other = NonNull::new(ptr1.as_ptr().wrapping_byte_offset(diff_plus_1)).unwrap();
/// assert_eq!(ptr2.addr(), ptr2_other.addr());
/// // Since ptr2_other and ptr2 are derived from pointers to different objects,
/// // computing their offset is undefined behavior, even though
/// // they point to the same address!
/// // they point to addresses that are in-bounds of the same object!
///
/// let zero = unsafe { ptr2_other.offset_from(ptr2) }; // Undefined Behavior
/// let one = unsafe { ptr2_other.offset_from(ptr2) }; // Undefined Behavior! ⚠️
/// ```
#[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces

View File

@ -1998,6 +1998,9 @@ impl<'a> Builder<'a> {
if mode == Mode::Rustc {
rustflags.arg("-Zunstable-options");
rustflags.arg("-Wrustc::internal");
// FIXME(edition_2024): Change this to `-Wrust_2024_idioms` when all
// of the individual lints are satisfied.
rustflags.arg("-Wkeyword_idents_2024");
}
if self.config.rust_frame_pointers {

View File

@ -1052,12 +1052,12 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib
for (pos, literal) in meta_item_list.iter().filter_map(|meta| meta.lit()).enumerate() {
match literal.kind {
ast::LitKind::Int(a, _) => {
let gen = func.generics.params.remove(0);
let param = func.generics.params.remove(0);
if let GenericParamDef {
name,
kind: GenericParamDefKind::Const { ty, .. },
..
} = gen
} = param
{
func.decl
.inputs

View File

@ -1051,7 +1051,7 @@ fn simplify_fn_type<'tcx, 'a>(
let mut ty_generics = Vec::new();
let mut ty_constraints = Vec::new();
if let Some(arg_generics) = arg.generic_args() {
for ty in arg_generics.into_iter().filter_map(|gen| match gen {
for ty in arg_generics.into_iter().filter_map(|param| match param {
clean::GenericArg::Type(ty) => Some(ty),
_ => None,
}) {
@ -1172,8 +1172,8 @@ fn simplify_fn_constraint<'tcx, 'a>(
) {
let mut ty_constraints = Vec::new();
let ty_constrained_assoc = RenderTypeId::AssociatedType(constraint.assoc.name);
for gen in &constraint.assoc.args {
match gen {
for param in &constraint.assoc.args {
match param {
clean::GenericArg::Type(arg) => simplify_fn_type(
self_,
generics,

View File

@ -364,8 +364,8 @@ declare_lint_pass!(MiscEarlyLints => [
]);
impl EarlyLintPass for MiscEarlyLints {
fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) {
for param in &gen.params {
fn check_generics(&mut self, cx: &EarlyContext<'_>, generics: &Generics) {
for param in &generics.params {
builtin_type_shadow::check(cx, param);
}
}

View File

@ -102,9 +102,9 @@ impl TraitBounds {
impl_lint_pass!(TraitBounds => [TYPE_REPETITION_IN_BOUNDS, TRAIT_DUPLICATION_IN_BOUNDS]);
impl<'tcx> LateLintPass<'tcx> for TraitBounds {
fn check_generics(&mut self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) {
self.check_type_repetition(cx, gen);
check_trait_bound_duplication(cx, gen);
fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) {
self.check_type_repetition(cx, generics);
check_trait_bound_duplication(cx, generics);
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
@ -238,7 +238,7 @@ impl TraitBounds {
}
#[allow(clippy::mutable_key_type)]
fn check_type_repetition<'tcx>(&self, cx: &LateContext<'tcx>, gen: &'tcx Generics<'_>) {
fn check_type_repetition<'tcx>(&self, cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) {
struct SpanlessTy<'cx, 'tcx> {
ty: &'tcx Ty<'tcx>,
cx: &'cx LateContext<'tcx>,
@ -258,12 +258,12 @@ impl TraitBounds {
}
impl Eq for SpanlessTy<'_, '_> {}
if gen.span.from_expansion() {
if generics.span.from_expansion() {
return;
}
let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
let mut applicability = Applicability::MaybeIncorrect;
for bound in gen.predicates {
for bound in generics.predicates {
if let WherePredicate::BoundPredicate(ref p) = bound
&& p.origin != PredicateOrigin::ImplTrait
&& p.bounds.len() as u64 <= self.max_trait_bounds
@ -301,8 +301,8 @@ impl TraitBounds {
}
}
fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
if gen.span.from_expansion() {
fn check_trait_bound_duplication(cx: &LateContext<'_>, generics: &'_ Generics<'_>) {
if generics.span.from_expansion() {
return;
}
@ -313,7 +313,7 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
// |
// collects each of these where clauses into a set keyed by generic name and comparable trait
// eg. (T, Clone)
let where_predicates = gen
let where_predicates = generics
.predicates
.iter()
.filter_map(|pred| {
@ -342,7 +342,7 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
// |
// compare trait bounds keyed by generic name and comparable trait to collected where
// predicates eg. (T, Clone)
for predicate in gen.predicates.iter().filter(|pred| !pred.in_where_clause()) {
for predicate in generics.predicates.iter().filter(|pred| !pred.in_where_clause()) {
if let WherePredicate::BoundPredicate(bound_predicate) = predicate
&& bound_predicate.origin != PredicateOrigin::ImplTrait
&& !bound_predicate.span.from_expansion()

View File

@ -57,7 +57,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
bound
.bound_generic_params
.iter()
.any(|gen| matches!(gen.kind, GenericParamKind::Lifetime { .. }))
.any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
});
if has_lifetime_parameters {
// complex trait bounds like A<'a, 'b>

View File

@ -39,8 +39,6 @@ fn test_ptr(ptr: *mut ()) {
// Distance.
let ptr = ptr.cast::<i32>();
ptr.offset_from(ptr);
/*
FIXME: this is disabled for now as these cases are not yet allowed.
// Distance from other "bad" pointers that have the same address, but different provenance. Some
// of this is library UB, but we don't want it to be language UB since that would violate
// provenance monotonicity: if we allow computing the distance between two ptrs with no
@ -54,6 +52,5 @@ fn test_ptr(ptr: *mut ()) {
// - Distance from use-after-free pointer
drop(b);
ptr.offset_from(other_ptr.with_addr(ptr.addr()));
*/
}
}

View File

@ -9,9 +9,14 @@ error: expected item, found `;`
--> $DIR/failed-doctest-extra-semicolon-on-item.rs:12:12
|
LL | struct S {}; // unexpected semicolon after struct def
| ^ help: remove this semicolon
| ^
|
= help: braced struct declarations are not followed by a semicolon
help: remove this semicolon
|
LL - struct S {}; // unexpected semicolon after struct def
LL + struct S {} // unexpected semicolon after struct def
|
error: aborting due to 1 previous error

View File

@ -2,115 +2,229 @@ error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:8:13
|
LL | let _ = await bar();
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
| ^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await bar();
LL + let _ = bar().await;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:12:13
|
LL | let _ = await? bar();
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
| ^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await? bar();
LL + let _ = bar().await?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:16:13
|
LL | let _ = await bar()?;
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
| ^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await bar()?;
LL + let _ = bar()?.await;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:20:13
|
LL | let _ = await { bar() };
| ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
| ^^^^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await { bar() };
LL + let _ = { bar() }.await;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:24:13
|
LL | let _ = await(bar());
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await`
| ^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await(bar());
LL + let _ = (bar()).await;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:28:13
|
LL | let _ = await { bar() }?;
| ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
| ^^^^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await { bar() }?;
LL + let _ = { bar() }.await?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:32:14
|
LL | let _ = (await bar())?;
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
| ^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = (await bar())?;
LL + let _ = (bar().await)?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:36:24
|
LL | let _ = bar().await();
| ^^ help: `await` is not a method call, remove the parentheses
| ^^
|
help: `await` is not a method call, remove the parentheses
|
LL - let _ = bar().await();
LL + let _ = bar().await;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:40:24
|
LL | let _ = bar().await()?;
| ^^ help: `await` is not a method call, remove the parentheses
| ^^
|
help: `await` is not a method call, remove the parentheses
|
LL - let _ = bar().await()?;
LL + let _ = bar().await?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:52:13
|
LL | let _ = await bar();
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
| ^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await bar();
LL + let _ = bar().await;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:56:13
|
LL | let _ = await? bar();
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
| ^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await? bar();
LL + let _ = bar().await?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:60:13
|
LL | let _ = await bar()?;
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
| ^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await bar()?;
LL + let _ = bar()?.await;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:64:14
|
LL | let _ = (await bar())?;
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
| ^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = (await bar())?;
LL + let _ = (bar().await)?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:68:24
|
LL | let _ = bar().await();
| ^^ help: `await` is not a method call, remove the parentheses
| ^^
|
help: `await` is not a method call, remove the parentheses
|
LL - let _ = bar().await();
LL + let _ = bar().await;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:73:24
|
LL | let _ = bar().await()?;
| ^^ help: `await` is not a method call, remove the parentheses
| ^^
|
help: `await` is not a method call, remove the parentheses
|
LL - let _ = bar().await()?;
LL + let _ = bar().await?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:101:13
|
LL | let _ = await!(bar());
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
| ^^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await!(bar());
LL + let _ = bar().await);
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:105:13
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
| ^^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await!(bar())?;
LL + let _ = bar().await)?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:110:17
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
| ^^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await!(bar())?;
LL + let _ = bar().await)?;
|
error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:117:17
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
| ^^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - let _ = await!(bar())?;
LL + let _ = bar().await)?;
|
error: expected expression, found `=>`
--> $DIR/incorrect-syntax-suggestions.rs:124:25
@ -124,7 +238,13 @@ error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:124:11
|
LL | match await { await => () }
| ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
| ^^^^^^^^^^^^^^^^^^^^^
|
help: `await` is a postfix operation
|
LL - match await { await => () }
LL + match { await => () }.await
|
error: expected one of `.`, `?`, `{`, or an operator, found `}`
--> $DIR/incorrect-syntax-suggestions.rs:127:1

View File

@ -32,7 +32,12 @@ error: missing type for `static` item
--> $DIR/issue-90873.rs:1:17
|
LL | #![u=||{static d=||1;}]
| ^ help: provide a type for the item: `: <type>`
| ^
|
help: provide a type for the item
|
LL | #![u=||{static d: <type>=||1;}]
| ++++++++
error: aborting due to 6 previous errors

View File

@ -2,9 +2,13 @@ error: malformed `cfg_attr` attribute input
--> $DIR/cfg-attr-parse.rs:4:1
|
LL | #[cfg_attr()]
| ^^^^^^^^^^^^^ help: missing condition and attribute: `#[cfg_attr(condition, attribute, other_attribute, ...)]`
| ^^^^^^^^^^^^^
|
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
help: missing condition and attribute
|
LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: expected `,`, found end of `cfg_attr` input
--> $DIR/cfg-attr-parse.rs:8:17

View File

@ -38,28 +38,43 @@ error: borrow expressions cannot be annotated with lifetimes
--> $DIR/issue-104390.rs:3:25
|
LL | fn f3() -> impl Sized { &'a 2E }
| ^--^^^
| ^---^^
| |
| annotated with lifetime here
| help: remove the lifetime annotation
|
help: remove the lifetime annotation
|
LL - fn f3() -> impl Sized { &'a 2E }
LL + fn f3() -> impl Sized { &2E }
|
error: borrow expressions cannot be annotated with lifetimes
--> $DIR/issue-104390.rs:5:25
|
LL | fn f4() -> impl Sized { &'static 2E }
| ^-------^^^
| ^--------^^
| |
| annotated with lifetime here
| help: remove the lifetime annotation
|
help: remove the lifetime annotation
|
LL - fn f4() -> impl Sized { &'static 2E }
LL + fn f4() -> impl Sized { &2E }
|
error: borrow expressions cannot be annotated with lifetimes
--> $DIR/issue-104390.rs:8:25
|
LL | fn f6() -> impl Sized { &'_ 2E }
| ^--^^^
| ^---^^
| |
| annotated with lifetime here
| help: remove the lifetime annotation
|
help: remove the lifetime annotation
|
LL - fn f6() -> impl Sized { &'_ 2E }
LL + fn f6() -> impl Sized { &2E }
|
error: aborting due to 9 previous errors

View File

@ -2,13 +2,20 @@
//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
#![allow(static_mut_refs)]
#![deny(const_eval_mutable_ptr_in_final_value)]
use std::cell::UnsafeCell;
use std::sync::atomic::*;
// # Plain `&mut` in the final value
// This requires walking nested statics.
static FOO: &&mut u32 = &&mut 42;
//~^ ERROR it is undefined behavior to use this value
//~| pointing to read-only memory
static OH_YES: &mut i32 = &mut 42;
//~^ ERROR it is undefined behavior to use this value
//~| pointing to read-only memory
static BAR: &mut () = &mut ();
//~^ ERROR encountered mutable pointer in final value of static
//~| WARNING this was previously accepted by the compiler
@ -19,15 +26,92 @@ static BOO: &mut Foo<()> = &mut Foo(());
//~^ ERROR encountered mutable pointer in final value of static
//~| WARNING this was previously accepted by the compiler
const BLUNT: &mut i32 = &mut 42;
//~^ ERROR: it is undefined behavior to use this value
//~| pointing to read-only memory
const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
//~^ ERROR: it is undefined behavior to use this value
//~| static
// # Interior mutability
struct Meh {
x: &'static UnsafeCell<i32>,
}
unsafe impl Sync for Meh {}
static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
//~^ ERROR it is undefined behavior to use this value
//~| `UnsafeCell` in read-only memory
// Same with a const:
// the following will never be ok! no interior mut behind consts, because
// all allocs interned here will be marked immutable.
const MUH: Meh = Meh {
//~^ ERROR it is undefined behavior to use this value
//~| `UnsafeCell` in read-only memory
x: &UnsafeCell::new(42),
};
struct Synced {
x: UnsafeCell<i32>,
}
unsafe impl Sync for Synced {}
// Make sure we also catch this behind a type-erased `dyn Trait` reference.
const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
//~^ ERROR: it is undefined behavior to use this value
//~| `UnsafeCell` in read-only memory
// # Check for mutable references to read-only memory
static READONLY: i32 = 0;
static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
//~^ ERROR: it is undefined behavior to use this value
//~| pointing to read-only memory
// # Check for consts pointing to mutable memory
static mut MUTABLE: i32 = 42;
const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; //~ERROR: undefined behavior
//~| encountered reference to mutable memory
static mut MUTABLE_REF: &mut i32 = &mut 42;
const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
//~^ ERROR: evaluation of constant value failed
//~| accesses mutable global memory
const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
//~^ ERROR: mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
//~^ ERROR: mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
//~^ ERROR: mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
struct SyncPtr<T> {
x: *const T,
}
unsafe impl<T> Sync for SyncPtr<T> {}
// These pass the lifetime checks because of the "tail expression" / "outer scope" rule.
// (This relies on `SyncPtr` being a curly brace struct.)
// However, we intern the inner memory as read-only, so this must be rejected.
// (Also see `static-no-inner-mut` for similar tests on `static`.)
const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
//~^ ERROR mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
//~^ ERROR mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
//~^ ERROR mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
static OH_YES: &mut i32 = &mut 42;
//~^ ERROR it is undefined behavior to use this value
fn main() {
unsafe {

View File

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:9:1
--> $DIR/mutable_references.rs:13:1
|
LL | static FOO: &&mut u32 = &&mut 42;
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered mutable reference or box pointing to read-only memory
@ -9,8 +9,19 @@ LL | static FOO: &&mut u32 = &&mut 42;
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:16:1
|
LL | static OH_YES: &mut i32 = &mut 42;
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error: encountered mutable pointer in final value of static
--> $DIR/mutable_references.rs:12:1
--> $DIR/mutable_references.rs:19:1
|
LL | static BAR: &mut () = &mut ();
| ^^^^^^^^^^^^^^^^^^^
@ -18,13 +29,13 @@ LL | static BAR: &mut () = &mut ();
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:5:9
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: encountered mutable pointer in final value of static
--> $DIR/mutable_references.rs:18:1
--> $DIR/mutable_references.rs:25:1
|
LL | static BOO: &mut Foo<()> = &mut Foo(());
| ^^^^^^^^^^^^^^^^^^^^^^^^
@ -33,7 +44,29 @@ LL | static BOO: &mut Foo<()> = &mut Foo(());
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:26:1
--> $DIR/mutable_references.rs:29:1
|
LL | const BLUNT: &mut i32 = &mut 42;
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:33:1
|
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:43:1
|
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
| ^^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory
@ -44,18 +77,111 @@ LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:29:1
--> $DIR/mutable_references.rs:49:1
|
LL | static OH_YES: &mut i32 = &mut 42;
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
LL | const MUH: Meh = Meh {
| ^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:61:1
|
LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>.x: encountered `UnsafeCell` in read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:68:1
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references.rs:75:1
|
LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: evaluation of constant value failed
--> $DIR/mutable_references.rs:78:43
|
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
| ^^^^^^^^^^^^^ constant accesses mutable global memory
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:82:1
|
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:86:1
|
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:90:1
|
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:103:1
|
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:107:1
|
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:111:1
|
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error[E0594]: cannot assign to `*OH_YES`, as `OH_YES` is an immutable static item
--> $DIR/mutable_references.rs:36:5
--> $DIR/mutable_references.rs:120:5
|
LL | *OH_YES = 99;
| ^^^^^^^^^^^^ cannot assign
@ -63,38 +189,113 @@ LL | *OH_YES = 99;
warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:9:26
--> $DIR/mutable_references.rs:13:26
|
LL | static FOO: &&mut u32 = &&mut 42;
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:12:23
--> $DIR/mutable_references.rs:16:27
|
LL | static OH_YES: &mut i32 = &mut 42;
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:19:23
|
LL | static BAR: &mut () = &mut ();
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:18:28
--> $DIR/mutable_references.rs:25:28
|
LL | static BOO: &mut Foo<()> = &mut Foo(());
| ^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:26:28
--> $DIR/mutable_references.rs:29:25
|
LL | const BLUNT: &mut i32 = &mut 42;
| ^^^^^^^
help: skipping check for `const_refs_to_static` feature
--> $DIR/mutable_references.rs:33:68
|
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
| ^^^^^^
help: skipping check for `const_mut_refs` feature
--> $DIR/mutable_references.rs:33:63
|
LL | const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
| ^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:43:28
|
LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
| ^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:29:27
--> $DIR/mutable_references.rs:52:8
|
LL | static OH_YES: &mut i32 = &mut 42;
| ^^^^^^^
LL | x: &UnsafeCell::new(42),
| ^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:61:27
|
LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check for `const_mut_refs` feature
--> $DIR/mutable_references.rs:68:49
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check for `const_mut_refs` feature
--> $DIR/mutable_references.rs:68:49
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check for `const_refs_to_static` feature
--> $DIR/mutable_references.rs:75:43
|
LL | const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE };
| ^^^^^^^
help: skipping check for `const_refs_to_static` feature
--> $DIR/mutable_references.rs:78:45
|
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
| ^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:82:45
|
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:86:46
|
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:90:47
|
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:103:51
|
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
| ^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:107:49
|
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references.rs:111:51
|
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^
error: aborting due to 6 previous errors; 1 warning emitted
error: aborting due to 19 previous errors; 1 warning emitted
Some errors have detailed explanations: E0080, E0594.
For more information about an error, try `rustc --explain E0080`.
Future incompatibility report: Future breakage diagnostic:
error: encountered mutable pointer in final value of static
--> $DIR/mutable_references.rs:12:1
--> $DIR/mutable_references.rs:19:1
|
LL | static BAR: &mut () = &mut ();
| ^^^^^^^^^^^^^^^^^^^
@ -102,14 +303,14 @@ LL | static BAR: &mut () = &mut ();
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:5:9
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of static
--> $DIR/mutable_references.rs:18:1
--> $DIR/mutable_references.rs:25:1
|
LL | static BOO: &mut Foo<()> = &mut Foo(());
| ^^^^^^^^^^^^^^^^^^^^^^^^
@ -117,7 +318,97 @@ LL | static BOO: &mut Foo<()> = &mut Foo(());
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:5:9
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:82:1
|
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:86:1
|
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:90:1
|
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:103:1
|
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:107:1
|
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references.rs:111:1
|
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references.rs:6:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,95 +0,0 @@
//@ compile-flags: -Zunleash-the-miri-inside-of-you
//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
#![allow(invalid_reference_casting, static_mut_refs)]
#![deny(const_eval_mutable_ptr_in_final_value)]
use std::cell::UnsafeCell;
use std::sync::atomic::*;
// this test ensures that our mutability story is sound
struct Meh {
x: &'static UnsafeCell<i32>,
}
unsafe impl Sync for Meh {}
// the following will never be ok! no interior mut behind consts, because
// all allocs interned here will be marked immutable.
const MUH: Meh = Meh {
//~^ ERROR it is undefined behavior to use this value
x: &UnsafeCell::new(42),
};
struct Synced {
x: UnsafeCell<i32>,
}
unsafe impl Sync for Synced {}
// Make sure we also catch this behind a type-erased `dyn Trait` reference.
const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
//~^ ERROR: it is undefined behavior to use this value
// Make sure we also catch mutable references in values that shouldn't have them.
static mut FOO: i32 = 0;
const SUBTLE: &mut i32 = unsafe { &mut FOO };
//~^ ERROR: it is undefined behavior to use this value
//~| static
const BLUNT: &mut i32 = &mut 42;
//~^ ERROR: it is undefined behavior to use this value
// Check for mutable references to read-only memory.
static READONLY: i32 = 0;
static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
//~^ ERROR: it is undefined behavior to use this value
//~| pointing to read-only memory
// Check for consts pointing to mutable memory.
// These are fine as long as they are not being read.
static mut MUTABLE: i32 = 42;
const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE }; //~ERROR: undefined behavior
//~| encountered reference to mutable memory
const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1;
static mut MUTABLE_REF: &mut i32 = &mut 42;
const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
//~^ ERROR: evaluation of constant value failed
//~| accesses mutable global memory
const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
//~^ ERROR: mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
//~^ ERROR: mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
//~^ ERROR: mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
struct SyncPtr<T> {
x: *const T,
}
unsafe impl<T> Sync for SyncPtr<T> {}
// These pass the lifetime checks because of the "tail expression" / "outer scope" rule.
// (This relies on `SyncPtr` being a curly brace struct.)
// However, we intern the inner memory as read-only, so this must be rejected.
// (Also see `static-no-inner-mut` for similar tests on `static`.)
const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
//~^ ERROR mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
//~^ ERROR mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
//~^ ERROR mutable pointer in final value
//~| WARNING this was previously accepted by the compiler
fn main() {
unsafe {
*MUH.x.get() = 99;
}
}

View File

@ -1,308 +0,0 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references_err.rs:18:1
|
LL | const MUH: Meh = Meh {
| ^^^^^^^^^^^^^^ constructing invalid value at .x.<deref>: encountered `UnsafeCell` in read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references_err.rs:29:1
|
LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>.x: encountered `UnsafeCell` in read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references_err.rs:34:1
|
LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references_err.rs:38:1
|
LL | const BLUNT: &mut i32 = &mut 42;
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references_err.rs:43:1
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered mutable reference or box pointing to read-only memory
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mutable_references_err.rs:50:1
|
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered reference to mutable memory in `const`
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
HEX_DUMP
}
note: erroneous constant encountered
--> $DIR/mutable_references_err.rs:52:34
|
LL | const READS_FROM_MUTABLE: i32 = *POINTS_TO_MUTABLE1;
| ^^^^^^^^^^^^^^^^^^
error[E0080]: evaluation of constant value failed
--> $DIR/mutable_references_err.rs:54:43
|
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
| ^^^^^^^^^^^^^ constant accesses mutable global memory
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:58:1
|
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references_err.rs:5:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:62:1
|
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:66:1
|
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:79:1
|
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:83:1
|
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:87:1
|
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
warning: skipping const checks
|
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:20:8
|
LL | x: &UnsafeCell::new(42),
| ^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:29:27
|
LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check for `const_refs_to_static` feature
--> $DIR/mutable_references_err.rs:34:40
|
LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
| ^^^
help: skipping check for `const_mut_refs` feature
--> $DIR/mutable_references_err.rs:34:35
|
LL | const SUBTLE: &mut i32 = unsafe { &mut FOO };
| ^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:38:25
|
LL | const BLUNT: &mut i32 = &mut 42;
| ^^^^^^^
help: skipping check for `const_mut_refs` feature
--> $DIR/mutable_references_err.rs:43:49
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check for `const_mut_refs` feature
--> $DIR/mutable_references_err.rs:43:49
|
LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: skipping check for `const_refs_to_static` feature
--> $DIR/mutable_references_err.rs:50:44
|
LL | const POINTS_TO_MUTABLE1: &i32 = unsafe { &MUTABLE };
| ^^^^^^^
help: skipping check for `const_refs_to_static` feature
--> $DIR/mutable_references_err.rs:54:45
|
LL | const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
| ^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:58:45
|
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:62:46
|
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:66:47
|
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:79:51
|
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
| ^^^^^^^^^^^^^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:83:49
|
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
| ^^^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/mutable_references_err.rs:87:51
|
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^
error: aborting due to 13 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0080`.
Future incompatibility report: Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:58:1
|
LL | const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references_err.rs:5:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:62:1
|
LL | const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references_err.rs:5:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:66:1
|
LL | const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references_err.rs:5:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:79:1
|
LL | const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references_err.rs:5:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:83:1
|
LL | const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references_err.rs:5:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future breakage diagnostic:
error: encountered mutable pointer in final value of constant
--> $DIR/mutable_references_err.rs:87:1
|
LL | const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
note: the lint level is defined here
--> $DIR/mutable_references_err.rs:5:9
|
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -32,12 +32,6 @@ pub const NOT_MULTIPLE_OF_SIZE: isize = {
//~| 1_isize cannot be divided by 2_isize without remainder
};
pub const OFFSET_FROM_NULL: isize = {
let ptr = 0 as *const u8;
// Null isn't special for zero-sized "accesses" (i.e., the range between the two pointers)
unsafe { ptr_offset_from(ptr, ptr) }
};
pub const DIFFERENT_INT: isize = { // offset_from with two different integers: like DIFFERENT_ALLOC
let ptr1 = 8 as *const u8;
let ptr2 = 16 as *const u8;
@ -63,14 +57,6 @@ const OUT_OF_BOUNDS_2: isize = {
//~| pointer to 10 bytes starting at offset 0 is out-of-bounds
};
const OUT_OF_BOUNDS_SAME: isize = {
let start_ptr = &4 as *const _ as *const u8;
let length = 10;
let end_ptr = (start_ptr).wrapping_add(length);
// Out-of-bounds is fine as long as the range between the pointers is empty.
unsafe { ptr_offset_from(end_ptr, end_ptr) }
};
pub const DIFFERENT_ALLOC_UNSIGNED: usize = {
let uninit = std::mem::MaybeUninit::<Struct>::uninit();
let base_ptr: *const Struct = &uninit as *const _ as *const Struct;
@ -130,4 +116,23 @@ pub const OFFSET_VERY_FAR2: isize = {
//~^ inside
};
// If the pointers are the same, OOB/null/UAF is fine.
pub const OFFSET_FROM_NULL_SAME: isize = {
let ptr = 0 as *const u8;
unsafe { ptr_offset_from(ptr, ptr) }
};
const OUT_OF_BOUNDS_SAME: isize = {
let start_ptr = &4 as *const _ as *const u8;
let length = 10;
let end_ptr = (start_ptr).wrapping_add(length);
unsafe { ptr_offset_from(end_ptr, end_ptr) }
};
const UAF_SAME: isize = {
let uaf_ptr = {
let x = 0;
&x as *const i32
};
unsafe { ptr_offset_from(uaf_ptr, uaf_ptr) }
};
fn main() {}

View File

@ -24,55 +24,55 @@ LL | unsafe { ptr_offset_from(field_ptr, base_ptr as *const u16) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exact_div: 1_isize cannot be divided by 2_isize without remainder
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:44:14
--> $DIR/offset_from_ub.rs:38:14
|
LL | unsafe { ptr_offset_from(ptr2, ptr1) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called on different pointers without provenance (i.e., without an associated allocation)
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:53:14
--> $DIR/offset_from_ub.rs:47:14
|
LL | unsafe { ptr_offset_from(end_ptr, start_ptr) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: ALLOC0 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:62:14
--> $DIR/offset_from_ub.rs:56:14
|
LL | unsafe { ptr_offset_from(start_ptr, end_ptr) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: ALLOC1 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:79:14
--> $DIR/offset_from_ub.rs:65:14
|
LL | unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called on pointers into different allocations
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:86:14
--> $DIR/offset_from_ub.rs:72:14
|
LL | unsafe { ptr_offset_from(ptr2, ptr1) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far ahead of second
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:92:14
--> $DIR/offset_from_ub.rs:78:14
|
LL | unsafe { ptr_offset_from(ptr1, ptr2) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:100:14
--> $DIR/offset_from_ub.rs:86:14
|
LL | unsafe { ptr_offset_from(ptr1, ptr2) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from` called when first pointer is too far before second
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:107:14
--> $DIR/offset_from_ub.rs:93:14
|
LL | unsafe { ptr_offset_from_unsigned(p, p.add(2) ) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer has smaller offset than second: 0 < 8
error[E0080]: evaluation of constant value failed
--> $DIR/offset_from_ub.rs:114:14
--> $DIR/offset_from_ub.rs:100:14
|
LL | unsafe { ptr_offset_from_unsigned(ptr2, ptr1) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `ptr_offset_from_unsigned` called when first pointer is too far ahead of second
@ -85,7 +85,7 @@ error[E0080]: evaluation of constant value failed
note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
note: inside `OFFSET_VERY_FAR1`
--> $DIR/offset_from_ub.rs:123:14
--> $DIR/offset_from_ub.rs:109:14
|
LL | unsafe { ptr2.offset_from(ptr1) }
| ^^^^^^^^^^^^^^^^^^^^^^
@ -98,7 +98,7 @@ error[E0080]: evaluation of constant value failed
note: inside `std::ptr::const_ptr::<impl *const u8>::offset_from`
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
note: inside `OFFSET_VERY_FAR2`
--> $DIR/offset_from_ub.rs:129:14
--> $DIR/offset_from_ub.rs:115:14
|
LL | unsafe { ptr1.offset_from(ptr2.wrapping_offset(1)) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -106,10 +106,13 @@ error: expected identifier, found `,`
--> $DIR/bad-syntax.rs:42:12
|
LL | #[coverage(,off)]
| ^
| |
| expected identifier
| help: remove this comma
| ^ expected identifier
|
help: remove this comma
|
LL - #[coverage(,off)]
LL + #[coverage(off)]
|
error: multiple `coverage` attributes
--> $DIR/bad-syntax.rs:7:1

View File

@ -2,19 +2,34 @@ error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
--> $DIR/E0178.rs:6:8
|
LL | w: &'a Foo + Copy,
| ^^^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + Copy)`
| ^^^^^^^^^^^^^^
|
help: try adding parentheses
|
LL | w: &'a (Foo + Copy),
| + +
error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
--> $DIR/E0178.rs:7:8
|
LL | x: &'a Foo + 'a,
| ^^^^^^^^^^^^ help: try adding parentheses: `&'a (Foo + 'a)`
| ^^^^^^^^^^^^
|
help: try adding parentheses
|
LL | x: &'a (Foo + 'a),
| + +
error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo`
--> $DIR/E0178.rs:8:8
|
LL | y: &'a mut Foo + 'a,
| ^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'a mut (Foo + 'a)`
| ^^^^^^^^^^^^^^^^
|
help: try adding parentheses
|
LL | y: &'a mut (Foo + 'a),
| + +
error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo`
--> $DIR/E0178.rs:9:8

View File

@ -2,39 +2,56 @@ error: `~` cannot be used as a unary operator
--> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:4:14
|
LL | let _x = ~1;
| ^ help: use `!` to perform bitwise not
| ^
|
help: use `!` to perform bitwise not
|
LL | let _x = !1;
| ~
error: unexpected `1` after identifier
--> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:5:18
|
LL | let _y = not 1;
| ----^
| |
| help: use `!` to perform bitwise not
| ^
|
help: use `!` to perform bitwise not
|
LL | let _y = !1;
| ~
error: unexpected keyword `false` after identifier
--> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:6:18
|
LL | let _z = not false;
| ----^^^^^
| |
| help: use `!` to perform logical negation
| ^^^^^
|
help: use `!` to perform logical negation
|
LL | let _z = !false;
| ~
error: unexpected keyword `true` after identifier
--> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:7:18
|
LL | let _a = not true;
| ----^^^^
| |
| help: use `!` to perform logical negation
| ^^^^
|
help: use `!` to perform logical negation
|
LL | let _a = !true;
| ~
error: unexpected `v` after identifier
--> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:9:18
|
LL | let _v = not v;
| ----^
| |
| help: use `!` to perform logical negation or bitwise not
| ^
|
help: use `!` to perform logical negation or bitwise not
|
LL | let _v = !v;
| ~
error: aborting due to 5 previous errors

View File

@ -2,25 +2,34 @@ error: unexpected `for_you` after identifier
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:3:12
|
LL | if not for_you {
| ----^^^^^^^
| |
| help: use `!` to perform logical negation or bitwise not
| ^^^^^^^
|
help: use `!` to perform logical negation or bitwise not
|
LL | if !for_you {
| ~
error: unexpected `the_worst` after identifier
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:11:15
|
LL | while not the_worst {
| ----^^^^^^^^^
| |
| help: use `!` to perform logical negation or bitwise not
| ^^^^^^^^^
|
help: use `!` to perform logical negation or bitwise not
|
LL | while !the_worst {
| ~
error: unexpected `println` after identifier
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:9
|
LL | if not // lack of braces is [sic]
| ----- help: use `!` to perform logical negation or bitwise not
LL | println!("Then when?");
| ^^^^^^^
|
help: use `!` to perform logical negation or bitwise not
|
LL | if !// lack of braces is [sic]
| ~
error: expected `{`, found `;`
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:31
@ -40,17 +49,23 @@ error: unexpected `2` after identifier
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:26:24
|
LL | let resource = not 2;
| ----^
| |
| help: use `!` to perform bitwise not
| ^
|
help: use `!` to perform bitwise not
|
LL | let resource = !2;
| ~
error: unexpected `be_smothered_out_before` after identifier
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:32:27
|
LL | let young_souls = not be_smothered_out_before;
| ----^^^^^^^^^^^^^^^^^^^^^^^
| |
| help: use `!` to perform logical negation or bitwise not
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `!` to perform logical negation or bitwise not
|
LL | let young_souls = !be_smothered_out_before;
| ~
error: aborting due to 6 previous errors

View File

@ -2,65 +2,97 @@ error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:7:15
|
LL | let _ = a and b;
| ^^^ help: use `&&` to perform logical conjunction
| ^^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `&&` to perform logical conjunction
|
LL | let _ = a && b;
| ~~
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:9:10
|
LL | if a and b {
| ^^^ help: use `&&` to perform logical conjunction
| ^^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `&&` to perform logical conjunction
|
LL | if a && b {
| ~~
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:20:15
|
LL | let _ = a or b;
| ^^ help: use `||` to perform logical disjunction
| ^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `||` to perform logical disjunction
|
LL | let _ = a || b;
| ~~
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:10
|
LL | if a or b {
| ^^ help: use `||` to perform logical disjunction
| ^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `||` to perform logical disjunction
|
LL | if a || b {
| ~~
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:30:11
|
LL | if (a and b) {
| ^^^ help: use `&&` to perform logical conjunction
| ^^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `&&` to perform logical conjunction
|
LL | if (a && b) {
| ~~
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:38:11
|
LL | if (a or b) {
| ^^ help: use `||` to perform logical disjunction
| ^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `||` to perform logical disjunction
|
LL | if (a || b) {
| ~~
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:46:13
|
LL | while a and b {
| ^^^ help: use `&&` to perform logical conjunction
| ^^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `&&` to perform logical conjunction
|
LL | while a && b {
| ~~
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:54:13
|
LL | while a or b {
| ^^ help: use `||` to perform logical disjunction
| ^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `||` to perform logical disjunction
|
LL | while a || b {
| ~~
error[E0308]: mismatched types
--> $DIR/issue-54109-and_instead_of_ampersands.rs:13:33

View File

@ -2,65 +2,97 @@ error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:13:15
|
LL | let _ = a and b;
| ^^^ help: use `&&` to perform logical conjunction
| ^^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `&&` to perform logical conjunction
|
LL | let _ = a && b;
| ~~
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:15:10
|
LL | if a and b {
| ^^^ help: use `&&` to perform logical conjunction
| ^^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `&&` to perform logical conjunction
|
LL | if a && b {
| ~~
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:24:15
|
LL | let _ = a or b;
| ^^ help: use `||` to perform logical disjunction
| ^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `||` to perform logical disjunction
|
LL | let _ = a || b;
| ~~
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:26:10
|
LL | if a or b {
| ^^ help: use `||` to perform logical disjunction
| ^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `||` to perform logical disjunction
|
LL | if a || b {
| ~~
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:34:11
|
LL | if (a and b) {
| ^^^ help: use `&&` to perform logical conjunction
| ^^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `&&` to perform logical conjunction
|
LL | if (a && b) {
| ~~
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:42:11
|
LL | if (a or b) {
| ^^ help: use `||` to perform logical disjunction
| ^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `||` to perform logical disjunction
|
LL | if (a || b) {
| ~~
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:50:13
|
LL | while a and b {
| ^^^ help: use `&&` to perform logical conjunction
| ^^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `&&` to perform logical conjunction
|
LL | while a && b {
| ~~
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:58:13
|
LL | while a or b {
| ^^ help: use `||` to perform logical disjunction
| ^^
|
= note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators
help: use `||` to perform logical disjunction
|
LL | while a || b {
| ~~
error: aborting due to 8 previous errors

View File

@ -2,7 +2,12 @@ error: can't qualify macro_rules invocation with `pub`
--> $DIR/pub-macro-rules.rs:2:5
|
LL | pub macro_rules! foo {
| ^^^ help: try exporting the macro: `#[macro_export]`
| ^^^
|
help: try exporting the macro
|
LL | #[macro_export] macro_rules! foo {
| ~~~~~~~~~~~~~~~
error: aborting due to 1 previous error

View File

@ -2,13 +2,23 @@ error[E0178]: expected a path on the left-hand side of `+`, not `&Copy`
--> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
|
LL | let _: &Copy + 'static;
| ^^^^^^^^^^^^^^^ help: try adding parentheses: `&(Copy + 'static)`
| ^^^^^^^^^^^^^^^
|
help: try adding parentheses
|
LL | let _: &(Copy + 'static);
| + +
error[E0178]: expected a path on the left-hand side of `+`, not `&'static Copy`
--> $DIR/trait-object-reference-without-parens-suggestion.rs:6:12
|
LL | let _: &'static Copy + 'static;
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try adding parentheses: `&'static (Copy + 'static)`
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: try adding parentheses
|
LL | let _: &'static (Copy + 'static);
| + +
error[E0038]: the trait `Copy` cannot be made into an object
--> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12

View File

@ -2,25 +2,45 @@ error: expected item, found `import`
--> $DIR/use_instead_of_import.rs:3:1
|
LL | import std::{
| ^^^^^^ help: items are imported using the `use` keyword
| ^^^^^^
|
help: items are imported using the `use` keyword
|
LL | use std::{
| ~~~
error: expected item, found `require`
--> $DIR/use_instead_of_import.rs:9:1
|
LL | require std::time::Duration;
| ^^^^^^^ help: items are imported using the `use` keyword
| ^^^^^^^
|
help: items are imported using the `use` keyword
|
LL | use std::time::Duration;
| ~~~
error: expected item, found `include`
--> $DIR/use_instead_of_import.rs:12:1
|
LL | include std::time::Instant;
| ^^^^^^^ help: items are imported using the `use` keyword
| ^^^^^^^
|
help: items are imported using the `use` keyword
|
LL | use std::time::Instant;
| ~~~
error: expected item, found `using`
--> $DIR/use_instead_of_import.rs:15:5
|
LL | pub using std::io;
| ^^^^^ help: items are imported using the `use` keyword
| ^^^^^
|
help: items are imported using the `use` keyword
|
LL | pub use std::io;
| ~~~
error: aborting due to 4 previous errors

View File

@ -1,7 +1,10 @@
enum Foo {
enum Bar { Baz }, //~ ERROR `enum` definition cannot be nested inside `enum`
struct Quux { field: u8 }, //~ ERROR `struct` definition cannot be nested inside `enum`
union Wibble { field: u8 }, //~ ERROR `union` definition cannot be nested inside `enum`
enum Bar { Baz },
//~^ ERROR `enum` definition cannot be nested inside `enum`
struct Quux { field: u8 },
//~^ ERROR `struct` definition cannot be nested inside `enum`
union Wibble { field: u8 },
//~^ ERROR `union` definition cannot be nested inside `enum`
Bat,
}

View File

@ -2,25 +2,34 @@ error: `enum` definition cannot be nested inside `enum`
--> $DIR/nested-enum.rs:2:5
|
LL | enum Bar { Baz },
| ^^^^------------
| |
| help: consider creating a new `enum` definition instead of nesting
| ^^^^
|
help: consider creating a new `enum` definition instead of nesting
|
LL - enum Bar { Baz },
|
error: `struct` definition cannot be nested inside `enum`
--> $DIR/nested-enum.rs:3:5
|
LL | struct Quux { field: u8 },
| ^^^^^^-------------------
| |
| help: consider creating a new `struct` definition instead of nesting
error: `union` definition cannot be nested inside `enum`
--> $DIR/nested-enum.rs:4:5
|
LL | struct Quux { field: u8 },
| ^^^^^^
|
help: consider creating a new `struct` definition instead of nesting
|
LL - struct Quux { field: u8 },
|
error: `union` definition cannot be nested inside `enum`
--> $DIR/nested-enum.rs:6:5
|
LL | union Wibble { field: u8 },
| ^^^^^---------------------
| |
| help: consider creating a new `union` definition instead of nesting
| ^^^^^
|
help: consider creating a new `union` definition instead of nesting
|
LL - union Wibble { field: u8 },
|
error: aborting due to 3 previous errors

View File

@ -2,9 +2,14 @@ error[E0586]: inclusive range with no end
--> $DIR/E0586.rs:3:19
|
LL | let x = &tmp[1..=];
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - let x = &tmp[1..=];
LL + let x = &tmp[1..];
|
error: aborting due to 1 previous error

View File

@ -9,12 +9,17 @@ error: outer attributes are not allowed on `if` and `else` branches
|
LL | } else #[attr] if false {
| _______----_^^^^^^^_-
| | | |
| | | help: remove the attributes
| | |
| | the branch belongs to this `else`
LL | | } else {
LL | | }
| |_____- the attributes are attached to this branch
|
help: remove the attributes
|
LL - } else #[attr] if false {
LL + } else if false {
|
error: expected expression, found keyword `else`
--> $DIR/else-attrs.rs:20:15

View File

@ -2,11 +2,13 @@ error: extern items cannot be `const`
--> $DIR/extern-const.rs:14:11
|
LL | const rust_dbg_static_mut: c_int;
| ------^^^^^^^^^^^^^^^^^^^
| |
| help: try using a static value: `static`
| ^^^^^^^^^^^^^^^^^^^
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
help: try using a static value
|
LL | static rust_dbg_static_mut: c_int;
| ~~~~~~
error: aborting due to 1 previous error

View File

@ -2,7 +2,12 @@ error: incorrect unicode escape sequence
--> $DIR/format-string-error-2.rs:77:20
|
LL | println!("\x7B}\u8 {", 1);
| ^^^ help: format of unicode escape sequences uses braces: `\u{8}`
| ^^^
|
help: format of unicode escape sequences uses braces
|
LL | println!("\x7B}\u{8} {", 1);
| ~~~~~
error: invalid format string: expected `'}'`, found `'a'`
--> $DIR/format-string-error-2.rs:5:5

View File

@ -3,7 +3,7 @@
fn a() -> usize { 0 }
//~^ ERROR return types are denoted using `->`
fn b()-> usize { 0 }
fn b() -> usize { 0 }
//~^ ERROR return types are denoted using `->`
fn bar(_: u32) {}
@ -22,7 +22,7 @@ fn main() {
//~^ ERROR return types are denoted using `->`
dbg!(foo(false));
let bar = |a: bool|-> bool { a };
let bar = |a: bool| -> bool { a };
//~^ ERROR return types are denoted using `->`
dbg!(bar(false));
}

View File

@ -2,25 +2,45 @@ error: return types are denoted using `->`
--> $DIR/fn-recover-return-sign.rs:3:8
|
LL | fn a() => usize { 0 }
| ^^ help: use `->` instead
| ^^
|
help: use `->` instead
|
LL | fn a() -> usize { 0 }
| ~~
error: return types are denoted using `->`
--> $DIR/fn-recover-return-sign.rs:6:7
|
LL | fn b(): usize { 0 }
| ^ help: use `->` instead
| ^
|
help: use `->` instead
|
LL | fn b() -> usize { 0 }
| ~~
error: return types are denoted using `->`
--> $DIR/fn-recover-return-sign.rs:21:25
|
LL | let foo = |a: bool| => bool { a };
| ^^ help: use `->` instead
| ^^
|
help: use `->` instead
|
LL | let foo = |a: bool| -> bool { a };
| ~~
error: return types are denoted using `->`
--> $DIR/fn-recover-return-sign.rs:25:24
|
LL | let bar = |a: bool|: bool { a };
| ^ help: use `->` instead
| ^
|
help: use `->` instead
|
LL | let bar = |a: bool| -> bool { a };
| ~~
error: aborting due to 4 previous errors

View File

@ -2,7 +2,12 @@ error: return types are denoted using `->`
--> $DIR/fn-recover-return-sign2.rs:4:10
|
LL | fn foo() => impl Fn() => bool {
| ^^ help: use `->` instead
| ^^
|
help: use `->` instead
|
LL | fn foo() -> impl Fn() => bool {
| ~~
error: expected one of `+`, `->`, `::`, `where`, or `{`, found `=>`
--> $DIR/fn-recover-return-sign2.rs:4:23

View File

@ -2,9 +2,12 @@ error: expected `:` followed by trait or lifetime
--> $DIR/issue-95208-ignore-qself.rs:6:88
|
LL | impl<T: Iterator> Struct<T> where <T as std:: iter::Iterator>::Item:: std::fmt::Display {
| --- ^
| |
| help: use single colon: `:`
| ^
|
help: use single colon
|
LL | impl<T: Iterator> Struct<T> where <T as std:: iter::Iterator>::Item: std::fmt::Display {
| ~
error: aborting due to 1 previous error

View File

@ -2,9 +2,12 @@ error: expected `:` followed by trait or lifetime
--> $DIR/issue-95208.rs:6:46
|
LL | impl<T> Struct<T> where T:: std::fmt::Display {
| --- ^
| |
| help: use single colon: `:`
| ^
|
help: use single colon
|
LL | impl<T> Struct<T> where T: std::fmt::Display {
| ~
error: aborting due to 1 previous error

View File

@ -4,9 +4,13 @@ error: path separator must be a double colon
LL | pub struct Foo {
| --- while parsing this struct
LL | a: Vec<foo::bar:A>,
| ^ help: use a double colon instead: `::`
| ^
|
= note: if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
help: use a double colon instead
|
LL | a: Vec<foo::bar::A>,
| +
error: aborting due to 1 previous error

View File

@ -2,36 +2,60 @@ error: range-to patterns with `...` are not allowed
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:15:9
|
LL | ...X => {}
| ^^^ help: use `..=` instead
| ^^^
|
help: use `..=` instead
|
LL | ..=X => {}
| ~~~
error: range-to patterns with `...` are not allowed
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:16:9
|
LL | ...0 => {}
| ^^^ help: use `..=` instead
| ^^^
|
help: use `..=` instead
|
LL | ..=0 => {}
| ~~~
error: range-to patterns with `...` are not allowed
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:17:9
|
LL | ...'a' => {}
| ^^^ help: use `..=` instead
| ^^^
|
help: use `..=` instead
|
LL | ..='a' => {}
| ~~~
error: range-to patterns with `...` are not allowed
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:18:9
|
LL | ...0.0f32 => {}
| ^^^ help: use `..=` instead
| ^^^
|
help: use `..=` instead
|
LL | ..=0.0f32 => {}
| ~~~
error: range-to patterns with `...` are not allowed
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:25:17
|
LL | let ...$e;
| ^^^ help: use `..=` instead
| ^^^
...
LL | mac!(0);
| ------- in this macro invocation
|
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: use `..=` instead
|
LL | let ..=$e;
| ~~~
error[E0005]: refutable pattern in local binding
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:25:17

View File

@ -2,57 +2,87 @@ error[E0586]: inclusive range with no end
--> $DIR/half-open-range-pats-inclusive-no-end.rs:8:13
|
LL | if let 0... = 1 {}
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - if let 0... = 1 {}
LL + if let 0.. = 1 {}
|
error[E0586]: inclusive range with no end
--> $DIR/half-open-range-pats-inclusive-no-end.rs:9:13
|
LL | if let 0..= = 1 {}
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - if let 0..= = 1 {}
LL + if let 0.. = 1 {}
|
error[E0586]: inclusive range with no end
--> $DIR/half-open-range-pats-inclusive-no-end.rs:11:13
|
LL | if let X... = 1 {}
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - if let X... = 1 {}
LL + if let X.. = 1 {}
|
error[E0586]: inclusive range with no end
--> $DIR/half-open-range-pats-inclusive-no-end.rs:12:13
|
LL | if let X..= = 1 {}
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - if let X..= = 1 {}
LL + if let X.. = 1 {}
|
error[E0586]: inclusive range with no end
--> $DIR/half-open-range-pats-inclusive-no-end.rs:18:19
|
LL | let $e...;
| ^^^ help: use `..` instead
| ^^^
...
LL | mac!(0);
| ------- in this macro invocation
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: use `..` instead
|
LL - let $e...;
LL + let $e..;
|
error[E0586]: inclusive range with no end
--> $DIR/half-open-range-pats-inclusive-no-end.rs:20:19
|
LL | let $e..=;
| ^^^ help: use `..` instead
| ^^^
...
LL | mac!(0);
| ------- in this macro invocation
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: use `..` instead
|
LL - let $e..=;
LL + let $e..;
|
error[E0005]: refutable pattern in local binding
--> $DIR/half-open-range-pats-inclusive-no-end.rs:18:17

View File

@ -2,53 +2,93 @@ error: the range pattern here has ambiguous interpretation
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:6:10
|
LL | &0.. | _ => {}
| ^^^ help: add parentheses to clarify the precedence: `(0..)`
| ^^^
|
help: add parentheses to clarify the precedence
|
LL | &(0..) | _ => {}
| + +
error[E0586]: inclusive range with no end
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:8:11
|
LL | &0..= | _ => {}
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - &0..= | _ => {}
LL + &0.. | _ => {}
|
error: the range pattern here has ambiguous interpretation
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:8:10
|
LL | &0..= | _ => {}
| ^^^^ help: add parentheses to clarify the precedence: `(0..=)`
| ^^^^
|
help: add parentheses to clarify the precedence
|
LL | &(0..=) | _ => {}
| + +
error[E0586]: inclusive range with no end
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:11:11
|
LL | &0... | _ => {}
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - &0... | _ => {}
LL + &0.. | _ => {}
|
error: the range pattern here has ambiguous interpretation
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:16:10
|
LL | &..0 | _ => {}
| ^^^ help: add parentheses to clarify the precedence: `(..0)`
| ^^^
|
help: add parentheses to clarify the precedence
|
LL | &(..0) | _ => {}
| + +
error: the range pattern here has ambiguous interpretation
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:18:10
|
LL | &..=0 | _ => {}
| ^^^^ help: add parentheses to clarify the precedence: `(..=0)`
| ^^^^
|
help: add parentheses to clarify the precedence
|
LL | &(..=0) | _ => {}
| + +
error: range-to patterns with `...` are not allowed
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:20:10
|
LL | &...0 | _ => {}
| ^^^ help: use `..=` instead
| ^^^
|
help: use `..=` instead
|
LL | &..=0 | _ => {}
| ~~~
error: the range pattern here has ambiguous interpretation
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:20:10
|
LL | &...0 | _ => {}
| ^^^^ help: add parentheses to clarify the precedence: `(..=0)`
| ^^^^
|
help: add parentheses to clarify the precedence
|
LL | &(...0) | _ => {}
| + +
error: aborting due to 8 previous errors

View File

@ -2,13 +2,23 @@ error: ambiguous `+` in a type
--> $DIR/impl-fn-parsing-ambiguities.rs:4:27
|
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
| ^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + '_)`
| ^^^^^^^^^^^^^^^
|
help: try adding parentheses
|
LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
| + +
error: ambiguous `+` in a type
--> $DIR/impl-fn-parsing-ambiguities.rs:10:24
|
LL | fn b() -> impl Fn() -> impl Debug + Send {
| ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`
| ^^^^^^^^^^^^^^^^^
|
help: try adding parentheses
|
LL | fn b() -> impl Fn() -> (impl Debug + Send) {
| + +
error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait`
--> $DIR/impl-fn-parsing-ambiguities.rs:4:40

View File

@ -2,19 +2,34 @@ error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:23:18
|
LL | type A = fn() -> impl A +;
| ^^^^^^^^ help: use parentheses to disambiguate: `(impl A)`
| ^^^^^^^^
|
help: try adding parentheses
|
LL | type A = fn() -> (impl A +);
| + +
error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:25:18
|
LL | type A = fn() -> impl A + B;
| ^^^^^^^^^^ help: use parentheses to disambiguate: `(impl A + B)`
| ^^^^^^^^^^
|
help: try adding parentheses
|
LL | type A = fn() -> (impl A + B);
| + +
error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:27:18
|
LL | type A = fn() -> dyn A + B;
| ^^^^^^^^^ help: use parentheses to disambiguate: `(dyn A + B)`
| ^^^^^^^^^
|
help: try adding parentheses
|
LL | type A = fn() -> (dyn A + B);
| + +
error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> A`
--> $DIR/impl-trait-plus-priority.rs:29:10
@ -26,43 +41,78 @@ error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:32:18
|
LL | type A = Fn() -> impl A +;
| ^^^^^^^^ help: use parentheses to disambiguate: `(impl A)`
| ^^^^^^^^
|
help: try adding parentheses
|
LL | type A = Fn() -> (impl A +);
| + +
error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:34:18
|
LL | type A = Fn() -> impl A + B;
| ^^^^^^^^^^ help: use parentheses to disambiguate: `(impl A + B)`
| ^^^^^^^^^^
|
help: try adding parentheses
|
LL | type A = Fn() -> (impl A + B);
| + +
error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:36:18
|
LL | type A = Fn() -> dyn A + B;
| ^^^^^^^^^ help: use parentheses to disambiguate: `(dyn A + B)`
| ^^^^^^^^^
|
help: try adding parentheses
|
LL | type A = Fn() -> (dyn A + B);
| + +
error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:40:11
|
LL | type A = &impl A +;
| ^^^^^^^^ help: use parentheses to disambiguate: `(impl A)`
| ^^^^^^^^
|
help: try adding parentheses
|
LL | type A = &(impl A +);
| + +
error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:42:11
|
LL | type A = &impl A + B;
| ^^^^^^^^^^ help: use parentheses to disambiguate: `(impl A + B)`
| ^^^^^^^^^^
|
help: try adding parentheses
|
LL | type A = &(impl A + B);
| + +
error: ambiguous `+` in a type
--> $DIR/impl-trait-plus-priority.rs:44:11
|
LL | type A = &dyn A + B;
| ^^^^^^^^^ help: use parentheses to disambiguate: `(dyn A + B)`
| ^^^^^^^^^
|
help: try adding parentheses
|
LL | type A = &(dyn A + B);
| + +
error[E0178]: expected a path on the left-hand side of `+`, not `&A`
--> $DIR/impl-trait-plus-priority.rs:46:10
|
LL | type A = &A + B;
| ^^^^^^ help: try adding parentheses: `&(A + B)`
| ^^^^^^
|
help: try adding parentheses
|
LL | type A = &(A + B);
| + +
error: aborting due to 11 previous errors

View File

@ -2,13 +2,23 @@ error: missing `in` in `for` loop
--> $DIR/issue-40782.rs:4:11
|
LL | for _i 0..2 {
| ^ help: try adding `in` here
| ^
|
help: try adding `in` here
|
LL | for _i in 0..2 {
| ++
error: missing `in` in `for` loop
--> $DIR/issue-40782.rs:6:12
|
LL | for _i of 0..2 {
| ^^ help: try using `in` here instead
| ^^
|
help: try using `in` here instead
|
LL | for _i in 0..2 {
| ~~
error: aborting due to 2 previous errors

View File

@ -2,13 +2,23 @@ error: malformed loop label
--> $DIR/label_misspelled_2.rs:10:5
|
LL | c: for _ in 0..1 {
| ^ help: use the correct loop label format: `'c`
| ^
|
help: use the correct loop label format
|
LL | 'c: for _ in 0..1 {
| +
error: malformed loop label
--> $DIR/label_misspelled_2.rs:13:5
|
LL | d: for _ in 0..1 {
| ^ help: use the correct loop label format: `'d`
| ^
|
help: use the correct loop label format
|
LL | 'd: for _ in 0..1 {
| +
error[E0425]: cannot find value `b` in this scope
--> $DIR/label_misspelled_2.rs:8:15

View File

@ -26,7 +26,12 @@ error: bare CR not allowed in string, use `\r` instead
--> $DIR/lex-bare-cr-string-literal-doc-comment.rs:19:18
|
LL | let _s = "foo bar";
| ^ help: escape the character: `\r`
| ^
|
help: escape the character
|
LL | let _s = "foo\rbar";
| ++
error: bare CR not allowed in raw string
--> $DIR/lex-bare-cr-string-literal-doc-comment.rs:22:19

View File

@ -2,9 +2,12 @@ error: unexpected `1` after identifier
--> $DIR/recovery-allowed.rs:5:23
|
LL | please_recover! { not 1 }
| ----^
| |
| help: use `!` to perform bitwise not
| ^
|
help: use `!` to perform bitwise not
|
LL | please_recover! { !1 }
| ~
error: aborting due to 1 previous error

View File

@ -2,17 +2,25 @@ error: malformed `cfg_attr` attribute input
--> $DIR/malformed-special-attrs.rs:1:1
|
LL | #[cfg_attr]
| ^^^^^^^^^^^ help: missing condition and attribute: `#[cfg_attr(condition, attribute, other_attribute, ...)]`
| ^^^^^^^^^^^
|
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
help: missing condition and attribute
|
LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: malformed `cfg_attr` attribute input
--> $DIR/malformed-special-attrs.rs:4:1
|
LL | #[cfg_attr = ""]
| ^^^^^^^^^^^^^^^^ help: missing condition and attribute: `#[cfg_attr(condition, attribute, other_attribute, ...)]`
| ^^^^^^^^^^^^^^^^
|
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
help: missing condition and attribute
|
LL | #[cfg_attr(condition, attribute, other_attribute, ...)]
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: malformed `derive` attribute input
--> $DIR/malformed-special-attrs.rs:7:1

View File

@ -2,7 +2,12 @@ error: return types are denoted using `->`
--> $DIR/avoid-ice-on-warning.rs:4:23
|
LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
| ^ help: use `->` instead
| ^
|
help: use `->` instead
|
LL | fn call_this<F>(f: F) -> Fn(&str) + call_that {}
| ~~
error[E0405]: cannot find trait `call_that` in this scope
--> $DIR/avoid-ice-on-warning.rs:4:36

View File

@ -2,7 +2,12 @@ error: return types are denoted using `->`
--> $DIR/avoid-ice-on-warning.rs:4:23
|
LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
| ^ help: use `->` instead
| ^
|
help: use `->` instead
|
LL | fn call_this<F>(f: F) -> Fn(&str) + call_that {}
| ~~
error[E0405]: cannot find trait `call_that` in this scope
--> $DIR/avoid-ice-on-warning.rs:4:36

View File

@ -2,7 +2,12 @@ error: invalid comparison operator `<>`
--> $DIR/less-than-greater-than.rs:2:22
|
LL | println!("{}", 1 <> 2);
| ^^ help: `<>` is not a valid comparison operator, use `!=`
| ^^
|
help: `<>` is not a valid comparison operator, use `!=`
|
LL | println!("{}", 1 != 2);
| ~~
error: aborting due to 1 previous error

View File

@ -2,7 +2,12 @@ error: top-level or-patterns are not allowed in function parameters
--> $DIR/fn-param-wrap-parens.rs:13:9
|
LL | fn fun1(A | B: E) {}
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
| ^^^^^
|
help: wrap the pattern in parentheses
|
LL | fn fun1((A | B): E) {}
| + +
error: aborting due to 1 previous error

View File

@ -4,7 +4,13 @@ error: a trailing `|` is not allowed in an or-pattern
LL | E::A |
| ---- while parsing this or-pattern starting here
LL | E::B |
| ^ help: remove the `|`
| ^
|
help: remove the `|`
|
LL - E::B |
LL + E::B
|
error[E0308]: mismatched types
--> $DIR/issue-64879-trailing-before-guard.rs:12:42

View File

@ -2,55 +2,90 @@ error: unexpected token `||` in pattern
--> $DIR/multiple-pattern-typo.rs:7:15
|
LL | 1 | 2 || 3 => (),
| - ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| - ^^
| |
| while parsing this or-pattern starting here
|
help: use a single `|` to separate multiple alternative patterns
|
LL | 1 | 2 | 3 => (),
| ~
error: unexpected token `||` in pattern
--> $DIR/multiple-pattern-typo.rs:12:16
|
LL | (1 | 2 || 3) => (),
| - ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| - ^^
| |
| while parsing this or-pattern starting here
|
help: use a single `|` to separate multiple alternative patterns
|
LL | (1 | 2 | 3) => (),
| ~
error: unexpected token `||` in pattern
--> $DIR/multiple-pattern-typo.rs:17:16
|
LL | (1 | 2 || 3,) => (),
| - ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| - ^^
| |
| while parsing this or-pattern starting here
|
help: use a single `|` to separate multiple alternative patterns
|
LL | (1 | 2 | 3,) => (),
| ~
error: unexpected token `||` in pattern
--> $DIR/multiple-pattern-typo.rs:24:18
|
LL | TS(1 | 2 || 3) => (),
| - ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| - ^^
| |
| while parsing this or-pattern starting here
|
help: use a single `|` to separate multiple alternative patterns
|
LL | TS(1 | 2 | 3) => (),
| ~
error: unexpected token `||` in pattern
--> $DIR/multiple-pattern-typo.rs:31:23
|
LL | NS { f: 1 | 2 || 3 } => (),
| - ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| - ^^
| |
| while parsing this or-pattern starting here
|
help: use a single `|` to separate multiple alternative patterns
|
LL | NS { f: 1 | 2 | 3 } => (),
| ~
error: unexpected token `||` in pattern
--> $DIR/multiple-pattern-typo.rs:36:16
|
LL | [1 | 2 || 3] => (),
| - ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| - ^^
| |
| while parsing this or-pattern starting here
|
help: use a single `|` to separate multiple alternative patterns
|
LL | [1 | 2 | 3] => (),
| ~
error: unexpected token `||` in pattern
--> $DIR/multiple-pattern-typo.rs:41:9
|
LL | || 1 | 2 | 3 => (),
| ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| ^^
|
help: use a single `|` to separate multiple alternative patterns
|
LL | | 1 | 2 | 3 => (),
| ~
error: aborting due to 7 previous errors

View File

@ -2,31 +2,56 @@ error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:19:9
|
LL | let b @ A | B: E = A;
| ^^^^^^^^^ help: wrap the pattern in parentheses: `(b @ A | B)`
| ^^^^^^^^^
|
help: wrap the pattern in parentheses
|
LL | let (b @ A | B): E = A;
| + +
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:34:9
|
LL | let &A(_) | B(_): F = A(3);
| ^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&A(_) | B(_))`
| ^^^^^^^^^^^^
|
help: wrap the pattern in parentheses
|
LL | let (&A(_) | B(_)): F = A(3);
| + +
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:36:9
|
LL | let &&A(_) | B(_): F = A(3);
| ^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&&A(_) | B(_))`
| ^^^^^^^^^^^^^
|
help: wrap the pattern in parentheses
|
LL | let (&&A(_) | B(_)): F = A(3);
| + +
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:38:9
|
LL | let &mut A(_) | B(_): F = A(3);
| ^^^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&mut A(_) | B(_))`
| ^^^^^^^^^^^^^^^^
|
help: wrap the pattern in parentheses
|
LL | let (&mut A(_) | B(_)): F = A(3);
| + +
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/nested-undelimited-precedence.rs:40:9
|
LL | let &&mut A(_) | B(_): F = A(3);
| ^^^^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&&mut A(_) | B(_))`
| ^^^^^^^^^^^^^^^^^
|
help: wrap the pattern in parentheses
|
LL | let (&&mut A(_) | B(_)): F = A(3);
| + +
error[E0408]: variable `b` is not bound in all patterns
--> $DIR/nested-undelimited-precedence.rs:19:17

View File

@ -16,25 +16,45 @@ error: top-level or-patterns are not allowed in function parameters
--> $DIR/or-patterns-syntactic-fail.rs:18:13
|
LL | fn fun1(A | B: E) {}
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
| ^^^^^
|
help: wrap the pattern in parentheses
|
LL | fn fun1((A | B): E) {}
| + +
error: top-level or-patterns are not allowed in function parameters
--> $DIR/or-patterns-syntactic-fail.rs:21:13
|
LL | fn fun2(| A | B: E) {}
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
| ^^^^^^^
|
help: wrap the pattern in parentheses
|
LL | fn fun2((| A | B): E) {}
| + +
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/or-patterns-syntactic-fail.rs:26:9
|
LL | let A | B: E = A;
| ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
| ^^^^^
|
help: wrap the pattern in parentheses
|
LL | let (A | B): E = A;
| + +
error: top-level or-patterns are not allowed in `let` bindings
--> $DIR/or-patterns-syntactic-fail.rs:29:9
|
LL | let | A | B: E = A;
| ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
| ^^^^^^^
|
help: wrap the pattern in parentheses
|
LL | let (| A | B): E = A;
| + +
error: aborting due to 5 previous errors

View File

@ -8,7 +8,7 @@ fn main() {}
#[cfg(FALSE)]
fn leading() {
fn fun1( A: E) {} //~ ERROR top-level or-patterns are not allowed
fn fun1( A: E) {} //~ ERROR top-level or-patterns are not allowed
fn fun2( A: E) {} //~ ERROR unexpected `||` before function parameter
let ( | A): E;
let ( | A): (E); //~ ERROR unexpected token `||` in pattern

View File

@ -2,161 +2,279 @@ error: top-level or-patterns are not allowed in function parameters
--> $DIR/remove-leading-vert.rs:11:14
|
LL | fn fun1( | A: E) {}
| ^^^ help: remove the `|`: `A`
| ^^^
|
help: remove the `|`
|
LL - fn fun1( | A: E) {}
LL + fn fun1( A: E) {}
|
error: unexpected `||` before function parameter
--> $DIR/remove-leading-vert.rs:12:14
|
LL | fn fun2( || A: E) {}
| ^^ help: remove the `||`
| ^^
|
= note: alternatives in or-patterns are separated with `|`, not `||`
help: remove the `||`
|
LL - fn fun2( || A: E) {}
LL + fn fun2( A: E) {}
|
error: unexpected token `||` in pattern
--> $DIR/remove-leading-vert.rs:14:11
|
LL | let ( || A): (E);
| ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| ^^
|
help: use a single `|` to separate multiple alternative patterns
|
LL | let ( | A): (E);
| ~
error: unexpected token `||` in pattern
--> $DIR/remove-leading-vert.rs:17:11
|
LL | let [ || A ]: [E; 1];
| ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| ^^
|
help: use a single `|` to separate multiple alternative patterns
|
LL | let [ | A ]: [E; 1];
| ~
error: unexpected token `||` in pattern
--> $DIR/remove-leading-vert.rs:19:13
|
LL | let TS( || A ): TS;
| ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| ^^
|
help: use a single `|` to separate multiple alternative patterns
|
LL | let TS( | A ): TS;
| ~
error: unexpected token `||` in pattern
--> $DIR/remove-leading-vert.rs:21:17
|
LL | let NS { f: || A }: NS;
| ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| ^^
|
help: use a single `|` to separate multiple alternative patterns
|
LL | let NS { f: | A }: NS;
| ~
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:26:13
|
LL | let ( A | ): E;
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let ( A | ): E;
LL + let ( A ): E;
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:27:12
|
LL | let (a |,): (E,);
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let (a |,): (E,);
LL + let (a ,): (E,);
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:28:17
|
LL | let ( A | B | ): E;
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let ( A | B | ): E;
LL + let ( A | B ): E;
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:29:17
|
LL | let [ A | B | ]: [E; 1];
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let [ A | B | ]: [E; 1];
LL + let [ A | B ]: [E; 1];
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:30:18
|
LL | let S { f: B | };
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let S { f: B | };
LL + let S { f: B };
|
error: unexpected token `||` in pattern
--> $DIR/remove-leading-vert.rs:31:13
|
LL | let ( A || B | ): E;
| - ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| - ^^
| |
| while parsing this or-pattern starting here
|
help: use a single `|` to separate multiple alternative patterns
|
LL | let ( A | B | ): E;
| ~
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:31:18
|
LL | let ( A || B | ): E;
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let ( A || B | ): E;
LL + let ( A || B ): E;
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:34:11
|
LL | A | => {}
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - A | => {}
LL + A => {}
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:35:11
|
LL | A || => {}
| - ^^ help: remove the `||`
| - ^^
| |
| while parsing this or-pattern starting here
|
= note: alternatives in or-patterns are separated with `|`, not `||`
help: remove the `||`
|
LL - A || => {}
LL + A => {}
|
error: unexpected token `||` in pattern
--> $DIR/remove-leading-vert.rs:36:11
|
LL | A || B | => {}
| - ^^ help: use a single `|` to separate multiple alternative patterns: `|`
| - ^^
| |
| while parsing this or-pattern starting here
|
help: use a single `|` to separate multiple alternative patterns
|
LL | A | B | => {}
| ~
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:36:16
|
LL | A || B | => {}
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - A || B | => {}
LL + A || B => {}
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:38:17
|
LL | | A | B | => {}
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - | A | B | => {}
LL + | A | B => {}
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:45:11
|
LL | let a | : u8 = 0;
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let a | : u8 = 0;
LL + let a : u8 = 0;
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:46:11
|
LL | let a | = 0;
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let a | = 0;
LL + let a = 0;
|
error: a trailing `|` is not allowed in an or-pattern
--> $DIR/remove-leading-vert.rs:47:11
|
LL | let a | ;
| - ^ help: remove the `|`
| - ^
| |
| while parsing this or-pattern starting here
|
help: remove the `|`
|
LL - let a | ;
LL + let a ;
|
error: aborting due to 21 previous errors

View File

@ -154,9 +154,14 @@ error: outer attributes are not allowed on `if` and `else` branches
|
LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; }
| -- ^^^^^^^ -- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `if`
|
help: remove the attributes
|
LL - #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; }
LL + #[cfg(FALSE)] fn e() { let _ = if 0 {}; }
|
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:40:38
@ -178,9 +183,14 @@ error: outer attributes are not allowed on `if` and `else` branches
|
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; }
| ---- ^^^^^^^ -- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `else`
|
help: remove the attributes
|
LL - #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] {}; }
LL + #[cfg(FALSE)] fn e() { let _ = if 0 {} else {}; }
|
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:46:46
@ -196,18 +206,28 @@ error: outer attributes are not allowed on `if` and `else` branches
|
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; }
| ---- ^^^^^^^ ------- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `else`
|
help: remove the attributes
|
LL - #[cfg(FALSE)] fn e() { let _ = if 0 {} else #[attr] if 0 {}; }
LL + #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {}; }
|
error: outer attributes are not allowed on `if` and `else` branches
--> $DIR/attr-stmt-expr-attr-bad.rs:50:50
|
LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; }
| -- ^^^^^^^ -- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `if`
|
help: remove the attributes
|
LL - #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; }
LL + #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 {}; }
|
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:52:51
@ -223,9 +243,14 @@ error: outer attributes are not allowed on `if` and `else` branches
|
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; }
| -- ^^^^^^^ -- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `if`
|
help: remove the attributes
|
LL - #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; }
LL + #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {}; }
|
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:56:46
@ -247,9 +272,14 @@ error: outer attributes are not allowed on `if` and `else` branches
|
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; }
| ---- ^^^^^^^ -- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `else`
|
help: remove the attributes
|
LL - #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] {}; }
LL + #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else {}; }
|
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:62:54
@ -265,18 +295,28 @@ error: outer attributes are not allowed on `if` and `else` branches
|
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; }
| ---- ^^^^^^^ --------------- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `else`
|
help: remove the attributes
|
LL - #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else #[attr] if let _ = 0 {}; }
LL + #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {}; }
|
error: outer attributes are not allowed on `if` and `else` branches
--> $DIR/attr-stmt-expr-attr-bad.rs:66:66
|
LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; }
| -- ^^^^^^^ -- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `if`
|
help: remove the attributes
|
LL - #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}; }
LL + #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 {}; }
|
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:68:67
@ -361,9 +401,14 @@ error[E0586]: inclusive range with no end
--> $DIR/attr-stmt-expr-attr-bad.rs:85:35
|
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
LL + #[cfg(FALSE)] fn e() { match 0 { 0..#[attr] 10 => () } }
|
error: expected one of `=>`, `if`, or `|`, found `#`
--> $DIR/attr-stmt-expr-attr-bad.rs:85:38
@ -375,9 +420,14 @@ error[E0586]: inclusive range with no end
--> $DIR/attr-stmt-expr-attr-bad.rs:88:35
|
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
LL + #[cfg(FALSE)] fn e() { match 0 { 0..#[attr] -10 => () } }
|
error: expected one of `=>`, `if`, or `|`, found `#`
--> $DIR/attr-stmt-expr-attr-bad.rs:88:38
@ -395,9 +445,14 @@ error[E0586]: inclusive range with no end
--> $DIR/attr-stmt-expr-attr-bad.rs:93:35
|
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
| ^^^ help: use `..` instead
| ^^^
|
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
help: use `..` instead
|
LL - #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
LL + #[cfg(FALSE)] fn e() { match 0 { 0..#[attr] FOO => () } }
|
error: expected one of `=>`, `if`, or `|`, found `#`
--> $DIR/attr-stmt-expr-attr-bad.rs:93:38

View File

@ -2,7 +2,12 @@ error: character constant must be escaped: `'`
--> $DIR/bad-char-literals.rs:6:6
|
LL | ''';
| ^ help: escape the character: `\'`
| ^
|
help: escape the character
|
LL | '\'';
| ~~
error: character constant must be escaped: `\n`
--> $DIR/bad-char-literals.rs:10:6
@ -10,19 +15,34 @@ error: character constant must be escaped: `\n`
LL | '
| ______^
LL | | ';
| |_ help: escape the character: `\n`
| |_
|
help: escape the character
|
LL | '\n';
| ++
error: character constant must be escaped: `\r`
--> $DIR/bad-char-literals.rs:15:6
|
LL | ' ';
| ^ help: escape the character: `\r`
| ^
|
help: escape the character
|
LL | '\r';
| ++
error: character constant must be escaped: `\t`
--> $DIR/bad-char-literals.rs:18:6
|
LL | ' ';
| ^^^^ help: escape the character: `\t`
| ^^^^
|
help: escape the character
|
LL | '\t';
| ++
error: aborting due to 4 previous errors

View File

@ -5,7 +5,12 @@ LL | pub type T0 = const fn();
| -----^^^^^
| |
| `const` because of this
| help: remove the `const` qualifier
|
help: remove the `const` qualifier
|
LL - pub type T0 = const fn();
LL + pub type T0 = fn();
|
error: an `fn` pointer type cannot be `const`
--> $DIR/bad-fn-ptr-qualifier.rs:6:15
@ -14,7 +19,12 @@ LL | pub type T1 = const extern "C" fn();
| -----^^^^^^^^^^^^^^^^
| |
| `const` because of this
| help: remove the `const` qualifier
|
help: remove the `const` qualifier
|
LL - pub type T1 = const extern "C" fn();
LL + pub type T1 = extern "C" fn();
|
error: an `fn` pointer type cannot be `const`
--> $DIR/bad-fn-ptr-qualifier.rs:7:15
@ -23,7 +33,12 @@ LL | pub type T2 = const unsafe extern fn();
| -----^^^^^^^^^^^^^^^^^^^
| |
| `const` because of this
| help: remove the `const` qualifier
|
help: remove the `const` qualifier
|
LL - pub type T2 = const unsafe extern fn();
LL + pub type T2 = unsafe extern fn();
|
error: an `fn` pointer type cannot be `async`
--> $DIR/bad-fn-ptr-qualifier.rs:8:15
@ -32,7 +47,12 @@ LL | pub type T3 = async fn();
| -----^^^^^
| |
| `async` because of this
| help: remove the `async` qualifier
|
help: remove the `async` qualifier
|
LL - pub type T3 = async fn();
LL + pub type T3 = fn();
|
error: an `fn` pointer type cannot be `async`
--> $DIR/bad-fn-ptr-qualifier.rs:9:15
@ -41,7 +61,12 @@ LL | pub type T4 = async extern fn();
| -----^^^^^^^^^^^^
| |
| `async` because of this
| help: remove the `async` qualifier
|
help: remove the `async` qualifier
|
LL - pub type T4 = async extern fn();
LL + pub type T4 = extern fn();
|
error: an `fn` pointer type cannot be `async`
--> $DIR/bad-fn-ptr-qualifier.rs:10:15
@ -50,7 +75,12 @@ LL | pub type T5 = async unsafe extern "C" fn();
| -----^^^^^^^^^^^^^^^^^^^^^^^
| |
| `async` because of this
| help: remove the `async` qualifier
|
help: remove the `async` qualifier
|
LL - pub type T5 = async unsafe extern "C" fn();
LL + pub type T5 = unsafe extern "C" fn();
|
error: an `fn` pointer type cannot be `const`
--> $DIR/bad-fn-ptr-qualifier.rs:11:15
@ -59,7 +89,12 @@ LL | pub type T6 = const async unsafe extern "C" fn();
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| `const` because of this
| help: remove the `const` qualifier
|
help: remove the `const` qualifier
|
LL - pub type T6 = const async unsafe extern "C" fn();
LL + pub type T6 = async unsafe extern "C" fn();
|
error: an `fn` pointer type cannot be `async`
--> $DIR/bad-fn-ptr-qualifier.rs:11:15
@ -68,7 +103,12 @@ LL | pub type T6 = const async unsafe extern "C" fn();
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
| |
| `async` because of this
| help: remove the `async` qualifier
|
help: remove the `async` qualifier
|
LL - pub type T6 = const async unsafe extern "C" fn();
LL + pub type T6 = const unsafe extern "C" fn();
|
error: an `fn` pointer type cannot be `const`
--> $DIR/bad-fn-ptr-qualifier.rs:15:17
@ -77,7 +117,12 @@ LL | pub type FTT0 = for<'a> const fn();
| ^^^^^^^^-----^^^^^
| |
| `const` because of this
| help: remove the `const` qualifier
|
help: remove the `const` qualifier
|
LL - pub type FTT0 = for<'a> const fn();
LL + pub type FTT0 = for<'a> fn();
|
error: an `fn` pointer type cannot be `const`
--> $DIR/bad-fn-ptr-qualifier.rs:16:17
@ -86,7 +131,12 @@ LL | pub type FTT1 = for<'a> const extern "C" fn();
| ^^^^^^^^-----^^^^^^^^^^^^^^^^
| |
| `const` because of this
| help: remove the `const` qualifier
|
help: remove the `const` qualifier
|
LL - pub type FTT1 = for<'a> const extern "C" fn();
LL + pub type FTT1 = for<'a> extern "C" fn();
|
error: an `fn` pointer type cannot be `const`
--> $DIR/bad-fn-ptr-qualifier.rs:17:17
@ -95,7 +145,12 @@ LL | pub type FTT2 = for<'a> const unsafe extern fn();
| ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^
| |
| `const` because of this
| help: remove the `const` qualifier
|
help: remove the `const` qualifier
|
LL - pub type FTT2 = for<'a> const unsafe extern fn();
LL + pub type FTT2 = for<'a> unsafe extern fn();
|
error: an `fn` pointer type cannot be `async`
--> $DIR/bad-fn-ptr-qualifier.rs:18:17
@ -104,7 +159,12 @@ LL | pub type FTT3 = for<'a> async fn();
| ^^^^^^^^-----^^^^^
| |
| `async` because of this
| help: remove the `async` qualifier
|
help: remove the `async` qualifier
|
LL - pub type FTT3 = for<'a> async fn();
LL + pub type FTT3 = for<'a> fn();
|
error: an `fn` pointer type cannot be `async`
--> $DIR/bad-fn-ptr-qualifier.rs:19:17
@ -113,7 +173,12 @@ LL | pub type FTT4 = for<'a> async extern fn();
| ^^^^^^^^-----^^^^^^^^^^^^
| |
| `async` because of this
| help: remove the `async` qualifier
|
help: remove the `async` qualifier
|
LL - pub type FTT4 = for<'a> async extern fn();
LL + pub type FTT4 = for<'a> extern fn();
|
error: an `fn` pointer type cannot be `async`
--> $DIR/bad-fn-ptr-qualifier.rs:20:17
@ -122,7 +187,12 @@ LL | pub type FTT5 = for<'a> async unsafe extern "C" fn();
| ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
| |
| `async` because of this
| help: remove the `async` qualifier
|
help: remove the `async` qualifier
|
LL - pub type FTT5 = for<'a> async unsafe extern "C" fn();
LL + pub type FTT5 = for<'a> unsafe extern "C" fn();
|
error: an `fn` pointer type cannot be `const`
--> $DIR/bad-fn-ptr-qualifier.rs:22:17
@ -131,7 +201,12 @@ LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn();
| ^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| `const` because of this
| help: remove the `const` qualifier
|
help: remove the `const` qualifier
|
LL - pub type FTT6 = for<'a> const async unsafe extern "C" fn();
LL + pub type FTT6 = for<'a> async unsafe extern "C" fn();
|
error: an `fn` pointer type cannot be `async`
--> $DIR/bad-fn-ptr-qualifier.rs:22:17
@ -140,7 +215,12 @@ LL | pub type FTT6 = for<'a> const async unsafe extern "C" fn();
| ^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^
| |
| `async` because of this
| help: remove the `async` qualifier
|
help: remove the `async` qualifier
|
LL - pub type FTT6 = for<'a> const async unsafe extern "C" fn();
LL + pub type FTT6 = for<'a> const unsafe extern "C" fn();
|
error: aborting due to 16 previous errors

View File

@ -24,13 +24,23 @@ error: byte constant must be escaped: `\t`
--> $DIR/byte-literals.rs:8:7
|
LL | b' ';
| ^^^^ help: escape the character: `\t`
| ^^^^
|
help: escape the character
|
LL | b'\t';
| ++
error: byte constant must be escaped: `'`
--> $DIR/byte-literals.rs:9:7
|
LL | b''';
| ^ help: escape the character: `\'`
| ^
|
help: escape the character
|
LL | b'\'';
| ~~
error: non-ASCII character in byte literal
--> $DIR/byte-literals.rs:10:7

View File

@ -2,15 +2,17 @@ error: character literal may only contain one codepoint
--> $DIR/whitespace-character-literal.rs:5:30
|
LL | let _hair_space_around = 'x';
| ^--^
| |
| help: consider removing the non-printing characters: `x`
| ^^^^
|
note: there are non-printing characters, the full sequence is `\u{200a}x\u{200b}`
--> $DIR/whitespace-character-literal.rs:5:31
|
LL | let _hair_space_around = 'x';
| ^^
help: consider removing the non-printing characters
|
LL | let _hair_space_around = 'x';
| ~
error: aborting due to 1 previous error

View File

@ -154,11 +154,13 @@ error: extern items cannot be `const`
--> $DIR/default-on-wrong-item-kind.rs:38:19
|
LL | default const foo: u8;
| --------------^^^
| |
| help: try using a static value: `static`
| ^^^
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
help: try using a static value
|
LL | static foo: u8;
| ~~~~~~
error: a module cannot be `default`
--> $DIR/default-on-wrong-item-kind.rs:41:5

View File

@ -2,9 +2,13 @@ error: found removed `do catch` syntax
--> $DIR/do-catch-suggests-try.rs:4:25
|
LL | let _: Option<()> = do catch {};
| ^^^^^^^^ help: replace with the new syntax: `try`
| ^^^^^^^^
|
= note: following RFC #2388, the new non-placeholder syntax is `try`
help: replace with the new syntax
|
LL | let _: Option<()> = try {};
| ~~~
error[E0308]: mismatched types
--> $DIR/do-catch-suggests-try.rs:9:33

View File

@ -16,9 +16,14 @@ error: outer attributes are not allowed on `if` and `else` branches
|
LL | if true /*!*/ {}
| -- ^^^^^ -- the attributes are attached to this branch
| | |
| | help: remove the attributes
| |
| the branch belongs to this `if`
|
help: remove the attributes
|
LL - if true /*!*/ {}
LL + if true {}
|
error: aborting due to 2 previous errors

View File

@ -2,41 +2,61 @@ error: `->` used for field access or method call
--> $DIR/expr-rarrow-call.rs:14:10
|
LL | named->foo;
| ^^ help: try using `.` instead
| ^^
|
= help: the `.` operator will dereference the value if needed
help: try using `.` instead
|
LL | named.foo;
| ~
error: `->` used for field access or method call
--> $DIR/expr-rarrow-call.rs:18:12
|
LL | unnamed->0;
| ^^ help: try using `.` instead
| ^^
|
= help: the `.` operator will dereference the value if needed
help: try using `.` instead
|
LL | unnamed.0;
| ~
error: `->` used for field access or method call
--> $DIR/expr-rarrow-call.rs:22:6
|
LL | t->0;
| ^^ help: try using `.` instead
| ^^
|
= help: the `.` operator will dereference the value if needed
help: try using `.` instead
|
LL | t.0;
| ~
error: `->` used for field access or method call
--> $DIR/expr-rarrow-call.rs:23:6
|
LL | t->1;
| ^^ help: try using `.` instead
| ^^
|
= help: the `.` operator will dereference the value if needed
help: try using `.` instead
|
LL | t.1;
| ~
error: `->` used for field access or method call
--> $DIR/expr-rarrow-call.rs:30:8
|
LL | foo->clone();
| ^^ help: try using `.` instead
| ^^
|
= help: the `.` operator will dereference the value if needed
help: try using `.` instead
|
LL | foo.clone();
| ~
error: aborting due to 5 previous errors

View File

@ -2,7 +2,12 @@ error: return types are denoted using `->`
--> $DIR/fn-colon-return-type.rs:1:15
|
LL | fn foo(x: i32): i32 {
| ^ help: use `->` instead
| ^
|
help: use `->` instead
|
LL | fn foo(x: i32) -> i32 {
| ~~
error: aborting due to 1 previous error

View File

@ -2,21 +2,25 @@ error: extern items cannot be `const`
--> $DIR/foreign-const-semantic-fail.rs:4:11
|
LL | const A: isize;
| ------^
| |
| help: try using a static value: `static`
| ^
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
help: try using a static value
|
LL | static A: isize;
| ~~~~~~
error: extern items cannot be `const`
--> $DIR/foreign-const-semantic-fail.rs:6:11
|
LL | const B: isize = 42;
| ------^
| |
| help: try using a static value: `static`
| ^
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
help: try using a static value
|
LL | static B: isize = 42;
| ~~~~~~
error: incorrect `static` inside `extern` block
--> $DIR/foreign-const-semantic-fail.rs:6:11

View File

@ -2,21 +2,25 @@ error: extern items cannot be `const`
--> $DIR/foreign-const-syntactic-fail.rs:7:11
|
LL | const A: isize;
| ------^
| |
| help: try using a static value: `static`
| ^
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
help: try using a static value
|
LL | static A: isize;
| ~~~~~~
error: extern items cannot be `const`
--> $DIR/foreign-const-syntactic-fail.rs:8:11
|
LL | const B: isize = 42;
| ------^
| |
| help: try using a static value: `static`
| ^
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
help: try using a static value
|
LL | static B: isize = 42;
| ~~~~~~
error: aborting due to 2 previous errors

View File

@ -2,19 +2,25 @@ error: expected identifier, found `,`
--> $DIR/ident-recovery.rs:1:4
|
LL | fn ,comma() {
| ^
| |
| expected identifier
| help: remove this comma
| ^ expected identifier
|
help: remove this comma
|
LL - fn ,comma() {
LL + fn comma() {
|
error: expected identifier, found `,`
--> $DIR/ident-recovery.rs:4:16
|
LL | x: i32,,
| ^
| |
| expected identifier
| help: remove this comma
| ^ expected identifier
|
help: remove this comma
|
LL - x: i32,,
LL + x: i32,
|
error: expected identifier, found keyword `break`
--> $DIR/ident-recovery.rs:10:4

Some files were not shown because too many files have changed in this diff Show More