Auto merge of #85720 - Dylan-DPC:rollup-in5917x, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #85478 (Disallow shadowing const parameters) - #85625 (Prevent double drop in `Vec::dedup_by` if a destructor panics) - #85627 (Fix a few details in THIR unsafeck) - #85633 (Post-monomorphization errors traces MVP) - #85670 (Remove arrays/IntoIterator message from Iterator trait.) - #85678 (fix `matches!` and `assert_matches!` on edition 2021) - #85679 (Remove num_as_ne_bytes feature) - #85712 (Fix typo in core::array::IntoIter comment) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f6a28aa403
27 changed files with 444 additions and 201 deletions
|
@ -186,6 +186,15 @@ impl<'tcx> MonoItem<'tcx> {
|
|||
pub fn codegen_dep_node(&self, tcx: TyCtxt<'tcx>) -> DepNode {
|
||||
crate::dep_graph::make_compile_mono_item(tcx, self)
|
||||
}
|
||||
|
||||
/// Returns the item's `CrateNum`
|
||||
pub fn krate(&self) -> CrateNum {
|
||||
match self {
|
||||
MonoItem::Fn(ref instance) => instance.def_id().krate,
|
||||
MonoItem::Static(def_id) => def_id.krate,
|
||||
MonoItem::GlobalAsm(..) => LOCAL_CRATE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for MonoItem<'tcx> {
|
||||
|
|
|
@ -184,7 +184,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|||
use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
|
||||
use rustc_errors::{ErrorReported, FatalError};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
|
@ -342,7 +342,8 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<
|
|||
.collect()
|
||||
}
|
||||
|
||||
// Collect all monomorphized items reachable from `starting_point`
|
||||
/// Collect all monomorphized items reachable from `starting_point`, and emit a note diagnostic if a
|
||||
/// post-monorphization error is encountered during a collection step.
|
||||
fn collect_items_rec<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
starting_point: Spanned<MonoItem<'tcx>>,
|
||||
|
@ -359,6 +360,31 @@ fn collect_items_rec<'tcx>(
|
|||
let mut neighbors = Vec::new();
|
||||
let recursion_depth_reset;
|
||||
|
||||
//
|
||||
// Post-monomorphization errors MVP
|
||||
//
|
||||
// We can encounter errors while monomorphizing an item, but we don't have a good way of
|
||||
// showing a complete stack of spans ultimately leading to collecting the erroneous one yet.
|
||||
// (It's also currently unclear exactly which diagnostics and information would be interesting
|
||||
// to report in such cases)
|
||||
//
|
||||
// This leads to suboptimal error reporting: a post-monomorphization error (PME) will be
|
||||
// shown with just a spanned piece of code causing the error, without information on where
|
||||
// it was called from. This is especially obscure if the erroneous mono item is in a
|
||||
// dependency. See for example issue #85155, where, before minimization, a PME happened two
|
||||
// crates downstream from libcore's stdarch, without a way to know which dependency was the
|
||||
// cause.
|
||||
//
|
||||
// If such an error occurs in the current crate, its span will be enough to locate the
|
||||
// source. If the cause is in another crate, the goal here is to quickly locate which mono
|
||||
// item in the current crate is ultimately responsible for causing the error.
|
||||
//
|
||||
// To give at least _some_ context to the user: while collecting mono items, we check the
|
||||
// error count. If it has changed, a PME occurred, and we trigger some diagnostics about the
|
||||
// current step of mono items collection.
|
||||
//
|
||||
let error_count = tcx.sess.diagnostic().err_count();
|
||||
|
||||
match starting_point.node {
|
||||
MonoItem::Static(def_id) => {
|
||||
let instance = Instance::mono(tcx, def_id);
|
||||
|
@ -411,6 +437,22 @@ fn collect_items_rec<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
// Check for PMEs and emit a diagnostic if one happened. To try to show relevant edges of the
|
||||
// mono item graph where the PME diagnostics are currently the most problematic (e.g. ones
|
||||
// involving a dependency, and the lack of context is confusing) in this MVP, we focus on
|
||||
// diagnostics on edges crossing a crate boundary: the collected mono items which are not
|
||||
// defined in the local crate.
|
||||
if tcx.sess.diagnostic().err_count() > error_count && starting_point.node.krate() != LOCAL_CRATE
|
||||
{
|
||||
tcx.sess.span_note_without_error(
|
||||
starting_point.span,
|
||||
&format!(
|
||||
"the above error was encountered while instantiating `{}`",
|
||||
starting_point.node
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
record_accesses(tcx, starting_point.node, neighbors.iter().map(|i| &i.node), inlining_map);
|
||||
|
||||
for neighbour in neighbors {
|
||||
|
|
|
@ -42,7 +42,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
|||
self.warn_unused_unsafe(
|
||||
hir_id,
|
||||
block_span,
|
||||
Some(self.tcx.sess.source_map().guess_head_span(enclosing_span)),
|
||||
Some((self.tcx.sess.source_map().guess_head_span(enclosing_span), "block")),
|
||||
);
|
||||
f(self);
|
||||
} else {
|
||||
|
@ -52,7 +52,15 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
|||
f(self);
|
||||
|
||||
if let SafetyContext::UnsafeBlock { used: false, span, hir_id } = self.safety_context {
|
||||
self.warn_unused_unsafe(hir_id, span, self.body_unsafety.unsafe_fn_sig_span());
|
||||
self.warn_unused_unsafe(
|
||||
hir_id,
|
||||
span,
|
||||
if self.unsafe_op_in_unsafe_fn_allowed() {
|
||||
self.body_unsafety.unsafe_fn_sig_span().map(|span| (span, "fn"))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
);
|
||||
}
|
||||
self.safety_context = prev_context;
|
||||
return;
|
||||
|
@ -72,16 +80,20 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
|||
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
|
||||
SafetyContext::UnsafeFn => {
|
||||
// unsafe_op_in_unsafe_fn is disallowed
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
self.tcx.struct_span_lint_hir(
|
||||
UNSAFE_OP_IN_UNSAFE_FN,
|
||||
self.hir_context,
|
||||
span,
|
||||
E0133,
|
||||
"{} is unsafe and requires unsafe block",
|
||||
description,
|
||||
|lint| {
|
||||
lint.build(&format!(
|
||||
"{} is unsafe and requires unsafe block (error E0133)",
|
||||
description,
|
||||
))
|
||||
.span_label(span, description)
|
||||
.note(note)
|
||||
.emit();
|
||||
},
|
||||
)
|
||||
.span_label(span, description)
|
||||
.note(note)
|
||||
.emit();
|
||||
}
|
||||
SafetyContext::Safe => {
|
||||
let fn_sugg = if unsafe_op_in_unsafe_fn_allowed { " function or" } else { "" };
|
||||
|
@ -104,18 +116,15 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
|||
&self,
|
||||
hir_id: hir::HirId,
|
||||
block_span: Span,
|
||||
enclosing_span: Option<Span>,
|
||||
enclosing_unsafe: Option<(Span, &'static str)>,
|
||||
) {
|
||||
let block_span = self.tcx.sess.source_map().guess_head_span(block_span);
|
||||
self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, |lint| {
|
||||
let msg = "unnecessary `unsafe` block";
|
||||
let mut db = lint.build(msg);
|
||||
db.span_label(block_span, msg);
|
||||
if let Some(enclosing_span) = enclosing_span {
|
||||
db.span_label(
|
||||
enclosing_span,
|
||||
format!("because it's nested under this `unsafe` block"),
|
||||
);
|
||||
if let Some((span, kind)) = enclosing_unsafe {
|
||||
db.span_label(span, format!("because it's nested under this `unsafe` {}", kind));
|
||||
}
|
||||
db.emit();
|
||||
});
|
||||
|
|
|
@ -425,24 +425,29 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
err
|
||||
}
|
||||
ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
|
||||
let res = binding.res();
|
||||
let shadows_what = res.descr();
|
||||
ResolutionError::BindingShadowsSomethingUnacceptable {
|
||||
shadowing_binding_descr,
|
||||
name,
|
||||
participle,
|
||||
article,
|
||||
shadowed_binding_descr,
|
||||
shadowed_binding_span,
|
||||
} => {
|
||||
let mut err = struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0530,
|
||||
"{}s cannot shadow {}s",
|
||||
what_binding,
|
||||
shadows_what
|
||||
shadowing_binding_descr,
|
||||
shadowed_binding_descr,
|
||||
);
|
||||
err.span_label(
|
||||
span,
|
||||
format!("cannot be named the same as {} {}", res.article(), shadows_what),
|
||||
format!("cannot be named the same as {} {}", article, shadowed_binding_descr),
|
||||
);
|
||||
let participle = if binding.is_import() { "imported" } else { "defined" };
|
||||
let msg = format!("the {} `{}` is {} here", shadows_what, name, participle);
|
||||
err.span_label(binding.span, msg);
|
||||
let msg =
|
||||
format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle);
|
||||
err.span_label(shadowed_binding_span, msg);
|
||||
err
|
||||
}
|
||||
ResolutionError::ForwardDeclaredTyParam => {
|
||||
|
|
|
@ -1763,13 +1763,33 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
// to something unusable as a pattern (e.g., constructor function),
|
||||
// but we still conservatively report an error, see
|
||||
// issues/33118#issuecomment-233962221 for one reason why.
|
||||
let binding = binding.expect("no binding for a ctor or static");
|
||||
self.report_error(
|
||||
ident.span,
|
||||
ResolutionError::BindingShadowsSomethingUnacceptable(
|
||||
pat_src.descr(),
|
||||
ident.name,
|
||||
binding.expect("no binding for a ctor or static"),
|
||||
),
|
||||
ResolutionError::BindingShadowsSomethingUnacceptable {
|
||||
shadowing_binding_descr: pat_src.descr(),
|
||||
name: ident.name,
|
||||
participle: if binding.is_import() { "imported" } else { "defined" },
|
||||
article: binding.res().article(),
|
||||
shadowed_binding_descr: binding.res().descr(),
|
||||
shadowed_binding_span: binding.span,
|
||||
},
|
||||
);
|
||||
None
|
||||
}
|
||||
Res::Def(DefKind::ConstParam, def_id) => {
|
||||
// Same as for DefKind::Const above, but here, `binding` is `None`, so we
|
||||
// have to construct the error differently
|
||||
self.report_error(
|
||||
ident.span,
|
||||
ResolutionError::BindingShadowsSomethingUnacceptable {
|
||||
shadowing_binding_descr: pat_src.descr(),
|
||||
name: ident.name,
|
||||
participle: "defined",
|
||||
article: res.article(),
|
||||
shadowed_binding_descr: res.descr(),
|
||||
shadowed_binding_span: self.r.opt_span(def_id).expect("const parameter defined outside of local crate"),
|
||||
}
|
||||
);
|
||||
None
|
||||
}
|
||||
|
|
|
@ -233,7 +233,14 @@ enum ResolutionError<'a> {
|
|||
/* current */ &'static str,
|
||||
),
|
||||
/// Error E0530: `X` bindings cannot shadow `Y`s.
|
||||
BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>),
|
||||
BindingShadowsSomethingUnacceptable {
|
||||
shadowing_binding_descr: &'static str,
|
||||
name: Symbol,
|
||||
participle: &'static str,
|
||||
article: &'static str,
|
||||
shadowed_binding_descr: &'static str,
|
||||
shadowed_binding_span: Span,
|
||||
},
|
||||
/// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
|
||||
ForwardDeclaredTyParam, // FIXME(const_generics_defaults)
|
||||
/// ERROR E0770: the type of const parameters must not depend on other generic parameters.
|
||||
|
|
|
@ -1619,6 +1619,8 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
let prev_ptr = ptr.add(gap.write.wrapping_sub(1));
|
||||
|
||||
if same_bucket(&mut *read_ptr, &mut *prev_ptr) {
|
||||
// Increase `gap.read` now since the drop may panic.
|
||||
gap.read += 1;
|
||||
/* We have found duplicate, drop it in-place */
|
||||
ptr::drop_in_place(read_ptr);
|
||||
} else {
|
||||
|
@ -1631,9 +1633,8 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||
|
||||
/* We have filled that place, so go further */
|
||||
gap.write += 1;
|
||||
gap.read += 1;
|
||||
}
|
||||
|
||||
gap.read += 1;
|
||||
}
|
||||
|
||||
/* Technically we could let `gap` clean up with its Drop, but
|
||||
|
|
|
@ -2234,48 +2234,50 @@ fn test_vec_dedup() {
|
|||
#[test]
|
||||
fn test_vec_dedup_panicking() {
|
||||
#[derive(Debug)]
|
||||
struct Panic {
|
||||
drop_counter: &'static AtomicU32,
|
||||
struct Panic<'a> {
|
||||
drop_counter: &'a Cell<u32>,
|
||||
value: bool,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl PartialEq for Panic {
|
||||
impl<'a> PartialEq for Panic<'a> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.value == other.value
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Panic {
|
||||
impl<'a> Drop for Panic<'a> {
|
||||
fn drop(&mut self) {
|
||||
let x = self.drop_counter.fetch_add(1, Ordering::SeqCst);
|
||||
assert!(x != 4);
|
||||
self.drop_counter.set(self.drop_counter.get() + 1);
|
||||
if !std::thread::panicking() {
|
||||
assert!(self.index != 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static DROP_COUNTER: AtomicU32 = AtomicU32::new(0);
|
||||
let drop_counter = &Cell::new(0);
|
||||
let expected = [
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 0 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 5 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: true, index: 6 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: true, index: 7 },
|
||||
Panic { drop_counter, value: false, index: 0 },
|
||||
Panic { drop_counter, value: false, index: 5 },
|
||||
Panic { drop_counter, value: true, index: 6 },
|
||||
Panic { drop_counter, value: true, index: 7 },
|
||||
];
|
||||
let mut vec = vec![
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 0 },
|
||||
Panic { drop_counter, value: false, index: 0 },
|
||||
// these elements get deduplicated
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 1 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 2 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 3 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 4 },
|
||||
// here it panics
|
||||
Panic { drop_counter: &DROP_COUNTER, value: false, index: 5 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: true, index: 6 },
|
||||
Panic { drop_counter: &DROP_COUNTER, value: true, index: 7 },
|
||||
Panic { drop_counter, value: false, index: 1 },
|
||||
Panic { drop_counter, value: false, index: 2 },
|
||||
Panic { drop_counter, value: false, index: 3 },
|
||||
Panic { drop_counter, value: false, index: 4 },
|
||||
// here it panics while dropping the item with index==4
|
||||
Panic { drop_counter, value: false, index: 5 },
|
||||
Panic { drop_counter, value: true, index: 6 },
|
||||
Panic { drop_counter, value: true, index: 7 },
|
||||
];
|
||||
|
||||
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
vec.dedup();
|
||||
}));
|
||||
let _ = catch_unwind(AssertUnwindSafe(|| vec.dedup())).unwrap_err();
|
||||
|
||||
assert_eq!(drop_counter.get(), 4);
|
||||
|
||||
let ok = vec.iter().zip(expected.iter()).all(|(x, y)| x.index == y.index);
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
|
|||
// SAFETY: Callers are only allowed to pass an index that is in bounds
|
||||
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
|
||||
// multiple repeated reads of the same index would be safe and the
|
||||
// values aree !Drop, thus won't suffer from double drops.
|
||||
// values are !Drop, thus won't suffer from double drops.
|
||||
unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,11 +79,6 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
|||
_Self = "std::string::String",
|
||||
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
|
||||
),
|
||||
on(
|
||||
_Self = "[]",
|
||||
label = "arrays do not yet implement `IntoIterator`; try using `std::array::IntoIter::new(arr)`",
|
||||
note = "see <https://github.com/rust-lang/rust/pull/65819> for more details"
|
||||
),
|
||||
on(
|
||||
_Self = "{integral}",
|
||||
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
|
||||
|
|
|
@ -168,6 +168,7 @@
|
|||
#![feature(no_coverage)] // rust-lang/rust#84605
|
||||
#![feature(int_error_matching)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![deny(or_patterns_back_compat)]
|
||||
|
||||
// allow using `core::` in intra-doc links
|
||||
#[allow(unused_extern_crates)]
|
||||
|
|
|
@ -138,7 +138,7 @@ macro_rules! assert_ne {
|
|||
#[unstable(feature = "assert_matches", issue = "82775")]
|
||||
#[allow_internal_unstable(core_panic)]
|
||||
macro_rules! assert_matches {
|
||||
($left:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => ({
|
||||
($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({
|
||||
match $left {
|
||||
$( $pattern )|+ $( if $guard )? => {}
|
||||
ref left_val => {
|
||||
|
@ -150,7 +150,7 @@ macro_rules! assert_matches {
|
|||
}
|
||||
}
|
||||
});
|
||||
($left:expr, $( $pattern:pat )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
|
||||
($left:expr, $( $pattern:pat_param )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
|
||||
match $left {
|
||||
$( $pattern )|+ $( if $guard )? => {}
|
||||
ref left_val => {
|
||||
|
@ -315,7 +315,7 @@ macro_rules! debug_assert_matches {
|
|||
#[macro_export]
|
||||
#[stable(feature = "matches_macro", since = "1.42.0")]
|
||||
macro_rules! matches {
|
||||
($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => {
|
||||
($expression:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
|
||||
match $expression {
|
||||
$( $pattern )|+ $( if $guard )? => true,
|
||||
_ => false
|
||||
|
|
|
@ -854,35 +854,6 @@ impl f32 {
|
|||
self.to_bits().to_ne_bytes()
|
||||
}
|
||||
|
||||
/// Return the memory representation of this floating point number as a byte array in
|
||||
/// native byte order.
|
||||
///
|
||||
/// [`to_ne_bytes`] should be preferred over this whenever possible.
|
||||
///
|
||||
/// [`to_ne_bytes`]: f32::to_ne_bytes
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(num_as_ne_bytes)]
|
||||
/// let num = 12.5f32;
|
||||
/// let bytes = num.as_ne_bytes();
|
||||
/// assert_eq!(
|
||||
/// bytes,
|
||||
/// if cfg!(target_endian = "big") {
|
||||
/// &[0x41, 0x48, 0x00, 0x00]
|
||||
/// } else {
|
||||
/// &[0x00, 0x00, 0x48, 0x41]
|
||||
/// }
|
||||
/// );
|
||||
/// ```
|
||||
#[unstable(feature = "num_as_ne_bytes", issue = "76976")]
|
||||
#[inline]
|
||||
pub fn as_ne_bytes(&self) -> &[u8; 4] {
|
||||
// SAFETY: `f32` is a plain old datatype so we can always transmute to it
|
||||
unsafe { &*(self as *const Self as *const _) }
|
||||
}
|
||||
|
||||
/// Create a floating point value from its representation as a byte array in big endian.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
@ -868,35 +868,6 @@ impl f64 {
|
|||
self.to_bits().to_ne_bytes()
|
||||
}
|
||||
|
||||
/// Return the memory representation of this floating point number as a byte array in
|
||||
/// native byte order.
|
||||
///
|
||||
/// [`to_ne_bytes`] should be preferred over this whenever possible.
|
||||
///
|
||||
/// [`to_ne_bytes`]: f64::to_ne_bytes
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(num_as_ne_bytes)]
|
||||
/// let num = 12.5f64;
|
||||
/// let bytes = num.as_ne_bytes();
|
||||
/// assert_eq!(
|
||||
/// bytes,
|
||||
/// if cfg!(target_endian = "big") {
|
||||
/// &[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||
/// } else {
|
||||
/// &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40]
|
||||
/// }
|
||||
/// );
|
||||
/// ```
|
||||
#[unstable(feature = "num_as_ne_bytes", issue = "76976")]
|
||||
#[inline]
|
||||
pub fn as_ne_bytes(&self) -> &[u8; 8] {
|
||||
// SAFETY: `f64` is a plain old datatype so we can always transmute to it
|
||||
unsafe { &*(self as *const Self as *const _) }
|
||||
}
|
||||
|
||||
/// Create a floating point value from its representation as a byte array in big endian.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
@ -1842,36 +1842,6 @@ macro_rules! int_impl {
|
|||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// Return the memory representation of this integer as a byte array in
|
||||
/// native byte order.
|
||||
///
|
||||
/// [`to_ne_bytes`] should be preferred over this whenever possible.
|
||||
///
|
||||
/// [`to_ne_bytes`]: Self::to_ne_bytes
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(num_as_ne_bytes)]
|
||||
#[doc = concat!("let num = ", $swap_op, stringify!($SelfT), ";")]
|
||||
/// let bytes = num.as_ne_bytes();
|
||||
/// assert_eq!(
|
||||
/// bytes,
|
||||
/// if cfg!(target_endian = "big") {
|
||||
#[doc = concat!(" &", $be_bytes)]
|
||||
/// } else {
|
||||
#[doc = concat!(" &", $le_bytes)]
|
||||
/// }
|
||||
/// );
|
||||
/// ```
|
||||
#[unstable(feature = "num_as_ne_bytes", issue = "76976")]
|
||||
#[inline]
|
||||
pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::<Self>()] {
|
||||
// SAFETY: integers are plain old datatypes so we can always transmute them to
|
||||
// arrays of bytes
|
||||
unsafe { &*(self as *const Self as *const _) }
|
||||
}
|
||||
|
||||
/// Create an integer value from its representation as a byte array in
|
||||
/// big endian.
|
||||
///
|
||||
|
|
|
@ -1672,36 +1672,6 @@ macro_rules! uint_impl {
|
|||
unsafe { mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// Return the memory representation of this integer as a byte array in
|
||||
/// native byte order.
|
||||
///
|
||||
/// [`to_ne_bytes`] should be preferred over this whenever possible.
|
||||
///
|
||||
/// [`to_ne_bytes`]: Self::to_ne_bytes
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(num_as_ne_bytes)]
|
||||
#[doc = concat!("let num = ", $swap_op, stringify!($SelfT), ";")]
|
||||
/// let bytes = num.as_ne_bytes();
|
||||
/// assert_eq!(
|
||||
/// bytes,
|
||||
/// if cfg!(target_endian = "big") {
|
||||
#[doc = concat!(" &", $be_bytes)]
|
||||
/// } else {
|
||||
#[doc = concat!(" &", $le_bytes)]
|
||||
/// }
|
||||
/// );
|
||||
/// ```
|
||||
#[unstable(feature = "num_as_ne_bytes", issue = "76976")]
|
||||
#[inline]
|
||||
pub fn as_ne_bytes(&self) -> &[u8; mem::size_of::<Self>()] {
|
||||
// SAFETY: integers are plain old datatypes so we can always transmute them to
|
||||
// arrays of bytes
|
||||
unsafe { &*(self as *const Self as *const _) }
|
||||
}
|
||||
|
||||
/// Create a native endian integer value from its representation
|
||||
/// as a byte array in big endian.
|
||||
///
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// Auxiliary crate used for testing post-monomorphization errors cross-crate.
|
||||
// It duplicates the setup used in `stdarch` to validate its intrinsics' const arguments.
|
||||
|
||||
struct ValidateConstImm<const IMM: i32, const MIN: i32, const MAX: i32>;
|
||||
impl<const IMM: i32, const MIN: i32, const MAX: i32> ValidateConstImm<IMM, MIN, MAX> {
|
||||
pub(crate) const VALID: () = {
|
||||
let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! static_assert_imm1 {
|
||||
($imm:ident) => {
|
||||
let _ = $crate::ValidateConstImm::<$imm, 0, { (1 << 1) - 1 }>::VALID;
|
||||
};
|
||||
}
|
||||
|
||||
// This function triggers an error whenever the const argument does not fit in 1-bit.
|
||||
pub fn stdarch_intrinsic<const IMM1: i32>() {
|
||||
static_assert_imm1!(IMM1);
|
||||
}
|
21
src/test/ui/consts/const-eval/issue-85155.rs
Normal file
21
src/test/ui/consts/const-eval/issue-85155.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// This is a test with a setup similar to issue 85155, which triggers a const eval error: a const
|
||||
// argument value is outside the range expected by the `stdarch` intrinsic.
|
||||
//
|
||||
// It's not the exact code mentioned in that issue because it depends both on `stdarch` intrinsics
|
||||
// only available on x64, and internal implementation details of `stdarch`. But mostly because these
|
||||
// are not important to trigger the diagnostics issue: it's specifically about the lack of context
|
||||
// in the diagnostics of post-monomorphization errors (PMEs) for consts, happening in a dependency.
|
||||
// Therefore, its setup is reproduced with an aux crate, which will similarly trigger a PME
|
||||
// depending on the const argument value, like the `stdarch` intrinsics would.
|
||||
//
|
||||
// aux-build: post_monomorphization_error.rs
|
||||
// build-fail: this is a post-monomorphization error, it passes check runs and requires building
|
||||
// to actually fail.
|
||||
|
||||
extern crate post_monomorphization_error;
|
||||
|
||||
fn main() {
|
||||
// This function triggers a PME whenever the const argument does not fit in 1-bit.
|
||||
post_monomorphization_error::stdarch_intrinsic::<2>();
|
||||
//~^ NOTE the above error was encountered while instantiating
|
||||
}
|
15
src/test/ui/consts/const-eval/issue-85155.stderr
Normal file
15
src/test/ui/consts/const-eval/issue-85155.stderr
Normal file
|
@ -0,0 +1,15 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/auxiliary/post_monomorphization_error.rs:7:17
|
||||
|
|
||||
LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to divide `1_usize` by zero
|
||||
|
||||
note: the above error was encountered while instantiating `fn stdarch_intrinsic::<2_i32>`
|
||||
--> $DIR/issue-85155.rs:19:5
|
||||
|
|
||||
LL | post_monomorphization_error::stdarch_intrinsic::<2>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
12
src/test/ui/matches2021.rs
Normal file
12
src/test/ui/matches2021.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// run-pass
|
||||
// edition:2021
|
||||
// compile-flags: -Zunstable-options
|
||||
|
||||
// regression test for https://github.com/rust-lang/rust/pull/85678
|
||||
|
||||
#![feature(assert_matches)]
|
||||
|
||||
fn main() {
|
||||
assert!(matches!((), ()));
|
||||
assert_matches!((), ());
|
||||
}
|
12
src/test/ui/resolve/issue-85348.rs
Normal file
12
src/test/ui/resolve/issue-85348.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Checks whether shadowing a const parameter leads to an ICE (#85348).
|
||||
|
||||
impl<const N: usize> ArrayWindowsExample {
|
||||
//~^ ERROR: cannot find type `ArrayWindowsExample` in this scope [E0412]
|
||||
fn next() {
|
||||
let mut N;
|
||||
//~^ ERROR: let bindings cannot shadow const parameters [E0530]
|
||||
//~| ERROR: type annotations needed [E0282]
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
25
src/test/ui/resolve/issue-85348.stderr
Normal file
25
src/test/ui/resolve/issue-85348.stderr
Normal file
|
@ -0,0 +1,25 @@
|
|||
error[E0530]: let bindings cannot shadow const parameters
|
||||
--> $DIR/issue-85348.rs:6:17
|
||||
|
|
||||
LL | impl<const N: usize> ArrayWindowsExample {
|
||||
| - the const parameter `N` is defined here
|
||||
...
|
||||
LL | let mut N;
|
||||
| ^ cannot be named the same as a const parameter
|
||||
|
||||
error[E0412]: cannot find type `ArrayWindowsExample` in this scope
|
||||
--> $DIR/issue-85348.rs:3:22
|
||||
|
|
||||
LL | impl<const N: usize> ArrayWindowsExample {
|
||||
| ^^^^^^^^^^^^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-85348.rs:6:13
|
||||
|
|
||||
LL | let mut N;
|
||||
| ^^^^^ consider giving `N` a type
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0412, E0530.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
20
src/test/ui/resolve/shadow-const-param.rs
Normal file
20
src/test/ui/resolve/shadow-const-param.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Checks that const parameters cannot be shadowed with fresh bindings
|
||||
// even in syntactically unambiguous contexts. See
|
||||
// https://github.com/rust-lang/rust/issues/33118#issuecomment-233962221
|
||||
|
||||
fn foo<const N: i32>(i: i32) -> bool {
|
||||
match i {
|
||||
N @ _ => true,
|
||||
//~^ ERROR: match bindings cannot shadow const parameters [E0530]
|
||||
}
|
||||
}
|
||||
|
||||
fn bar<const N: i32>(i: i32) -> bool {
|
||||
let N @ _ = 0;
|
||||
//~^ ERROR: let bindings cannot shadow const parameters [E0530]
|
||||
match i {
|
||||
N @ _ => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
20
src/test/ui/resolve/shadow-const-param.stderr
Normal file
20
src/test/ui/resolve/shadow-const-param.stderr
Normal file
|
@ -0,0 +1,20 @@
|
|||
error[E0530]: match bindings cannot shadow const parameters
|
||||
--> $DIR/shadow-const-param.rs:7:9
|
||||
|
|
||||
LL | fn foo<const N: i32>(i: i32) -> bool {
|
||||
| - the const parameter `N` is defined here
|
||||
LL | match i {
|
||||
LL | N @ _ => true,
|
||||
| ^ cannot be named the same as a const parameter
|
||||
|
||||
error[E0530]: let bindings cannot shadow const parameters
|
||||
--> $DIR/shadow-const-param.rs:13:9
|
||||
|
|
||||
LL | fn bar<const N: i32>(i: i32) -> bool {
|
||||
| - the const parameter `N` is defined here
|
||||
LL | let N @ _ = 0;
|
||||
| ^ cannot be named the same as a const parameter
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0530`.
|
|
@ -1,18 +1,18 @@
|
|||
error: call to unsafe function is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:9:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:1:9
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9
|
||||
|
|
||||
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:11:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5
|
||||
|
|
||||
LL | *PTR;
|
||||
| ^^^^ dereference of raw pointer
|
||||
|
@ -20,7 +20,7 @@ LL | *PTR;
|
|||
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
|
||||
error: use of mutable static is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:13:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5
|
||||
|
|
||||
LL | VOID = ();
|
||||
| ^^^^^^^^^ use of mutable static
|
||||
|
@ -28,25 +28,25 @@ LL | VOID = ();
|
|||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5
|
||||
|
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:2:9
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:5:9
|
||||
|
|
||||
LL | #![deny(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: call to unsafe function is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:24:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:22:8
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8
|
||||
|
|
||||
LL | #[deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
|
@ -54,7 +54,7 @@ LL | #[deny(warnings)]
|
|||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5
|
||||
|
|
||||
LL | *PTR;
|
||||
| ^^^^ dereference of raw pointer
|
||||
|
@ -62,7 +62,7 @@ LL | *PTR;
|
|||
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
|
||||
error: use of mutable static is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
|
||||
|
|
||||
LL | VOID = ();
|
||||
| ^^^^^^^^^ use of mutable static
|
||||
|
@ -70,13 +70,13 @@ LL | VOID = ();
|
|||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:30:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5
|
||||
|
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:44:14
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14
|
||||
|
|
||||
LL | unsafe { unsafe { unsf() } }
|
||||
| ------ ^^^^^^ unnecessary `unsafe` block
|
||||
|
@ -84,7 +84,7 @@ LL | unsafe { unsafe { unsf() } }
|
|||
| because it's nested under this `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:55:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5
|
||||
|
|
||||
LL | unsafe fn allow_level() {
|
||||
| ----------------------- because it's nested under this `unsafe` fn
|
||||
|
@ -93,7 +93,7 @@ LL | unsafe { unsf() }
|
|||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:67:9
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9
|
||||
|
|
||||
LL | unsafe fn nested_allow_level() {
|
||||
| ------------------------------ because it's nested under this `unsafe` fn
|
||||
|
@ -102,7 +102,7 @@ LL | unsafe { unsf() }
|
|||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:73:5
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
@ -110,7 +110,7 @@ LL | unsf();
|
|||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:77:9
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
|
@ -1,3 +1,6 @@
|
|||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Zthir-unsafeck
|
||||
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![deny(unused_unsafe)]
|
||||
|
||||
|
|
122
src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
Normal file
122
src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr
Normal file
|
@ -0,0 +1,122 @@
|
|||
error: call to unsafe function is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9
|
||||
|
|
||||
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5
|
||||
|
|
||||
LL | *PTR;
|
||||
| ^^^^ dereference of raw pointer
|
||||
|
|
||||
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
|
||||
error: use of mutable static is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5
|
||||
|
|
||||
LL | VOID = ();
|
||||
| ^^^^ use of mutable static
|
||||
|
|
||||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5
|
||||
|
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:5:9
|
||||
|
|
||||
LL | #![deny(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: call to unsafe function is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8
|
||||
|
|
||||
LL | #[deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
= note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]`
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: dereference of raw pointer is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5
|
||||
|
|
||||
LL | *PTR;
|
||||
| ^^^^ dereference of raw pointer
|
||||
|
|
||||
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
|
||||
|
||||
error: use of mutable static is unsafe and requires unsafe block (error E0133)
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5
|
||||
|
|
||||
LL | VOID = ();
|
||||
| ^^^^ use of mutable static
|
||||
|
|
||||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5
|
||||
|
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14
|
||||
|
|
||||
LL | unsafe { unsafe { unsf() } }
|
||||
| ------ ^^^^^^ unnecessary `unsafe` block
|
||||
| |
|
||||
| because it's nested under this `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5
|
||||
|
|
||||
LL | unsafe fn allow_level() {
|
||||
| ----------------------- because it's nested under this `unsafe` fn
|
||||
...
|
||||
LL | unsafe { unsf() }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9
|
||||
|
|
||||
LL | unsafe fn nested_allow_level() {
|
||||
| ------------------------------ because it's nested under this `unsafe` fn
|
||||
...
|
||||
LL | unsafe { unsf() }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9
|
||||
|
|
||||
LL | unsf();
|
||||
| ^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
Loading…
Add table
Reference in a new issue