Apply suggestions from code review
This commit is contained in:
parent
594c499db9
commit
bb67915028
8 changed files with 126 additions and 51 deletions
|
@ -17,8 +17,8 @@ use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_session::lint::{builtin, Level, Lint};
|
use rustc_session::lint::{builtin, Level, Lint};
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::source_map::MultiSpan;
|
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
|
use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP};
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
|
||||||
|
@ -80,6 +80,8 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
let level = cmp::min(level, self.sets.lint_cap);
|
let level = cmp::min(level, self.sets.lint_cap);
|
||||||
|
|
||||||
let lint_flag_val = Symbol::intern(lint_name);
|
let lint_flag_val = Symbol::intern(lint_name);
|
||||||
|
self.check_gated_lint(lint_flag_val, DUMMY_SP);
|
||||||
|
|
||||||
let ids = match store.find_lints(&lint_name) {
|
let ids = match store.find_lints(&lint_name) {
|
||||||
Ok(ids) => ids,
|
Ok(ids) => ids,
|
||||||
Err(_) => continue, // errors handled in check_lint_name_cmdline above
|
Err(_) => continue, // errors handled in check_lint_name_cmdline above
|
||||||
|
@ -211,6 +213,7 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
let name = meta_item.path.segments.last().expect("empty lint name").ident.name;
|
let name = meta_item.path.segments.last().expect("empty lint name").ident.name;
|
||||||
match store.check_lint_name(&name.as_str(), tool_name) {
|
match store.check_lint_name(&name.as_str(), tool_name) {
|
||||||
CheckLintNameResult::Ok(ids) => {
|
CheckLintNameResult::Ok(ids) => {
|
||||||
|
self.check_gated_lint(name, attr.span);
|
||||||
let src = LintSource::Node(name, li.span(), reason);
|
let src = LintSource::Node(name, li.span(), reason);
|
||||||
for id in ids {
|
for id in ids {
|
||||||
specs.insert(*id, (level, src));
|
specs.insert(*id, (level, src));
|
||||||
|
@ -383,6 +386,20 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||||
BuilderPush { prev, changed: prev != self.cur }
|
BuilderPush { prev, changed: prev != self.cur }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_gated_lint(&self, name: Symbol, span: Span) {
|
||||||
|
if name.as_str() == "unsafe_op_in_unsafe_fn"
|
||||||
|
&& !self.sess.features_untracked().unsafe_block_in_unsafe_fn
|
||||||
|
{
|
||||||
|
feature_err(
|
||||||
|
&self.sess.parse_sess,
|
||||||
|
sym::unsafe_block_in_unsafe_fn,
|
||||||
|
span,
|
||||||
|
"the `unsafe_op_in_unsafe_fn` lint is unstable",
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Called after `push` when the scope of a set of attributes are exited.
|
/// Called after `push` when the scope of a set of attributes are exited.
|
||||||
pub fn pop(&mut self, push: BuilderPush) {
|
pub fn pop(&mut self, push: BuilderPush) {
|
||||||
self.cur = push.prev;
|
self.cur = push.prev;
|
||||||
|
|
|
@ -21,16 +21,17 @@ pub enum UnsafetyViolationKind {
|
||||||
GeneralAndConstFn,
|
GeneralAndConstFn,
|
||||||
/// Borrow of packed field.
|
/// Borrow of packed field.
|
||||||
/// Has to be handled as a lint for backwards compatibility.
|
/// Has to be handled as a lint for backwards compatibility.
|
||||||
BorrowPacked(hir::HirId),
|
BorrowPacked,
|
||||||
/// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
|
/// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
|
||||||
/// Has to be handled as a lint for backwards compatibility.
|
/// Has to be handled as a lint for backwards compatibility.
|
||||||
/// Should stay gated under `#![feature(unsafe_block_in_unsafe_fn)]`.
|
/// Should stay gated under `#![feature(unsafe_block_in_unsafe_fn)]`.
|
||||||
UnsafeFn(hir::HirId),
|
UnsafeFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
|
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
|
||||||
pub struct UnsafetyViolation {
|
pub struct UnsafetyViolation {
|
||||||
pub source_info: SourceInfo,
|
pub source_info: SourceInfo,
|
||||||
|
pub lint_root: hir::HirId,
|
||||||
pub description: Symbol,
|
pub description: Symbol,
|
||||||
pub details: Symbol,
|
pub details: Symbol,
|
||||||
pub kind: UnsafetyViolationKind,
|
pub kind: UnsafetyViolationKind,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::struct_span_err;
|
use rustc_errors::struct_span_err;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
|
use rustc_hir::hir_id::HirId;
|
||||||
use rustc_hir::intravisit;
|
use rustc_hir::intravisit;
|
||||||
use rustc_hir::Node;
|
use rustc_hir::Node;
|
||||||
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
|
||||||
|
@ -10,6 +11,7 @@ use rustc_middle::ty::cast::CastTy;
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_session::lint::builtin::{SAFE_PACKED_BORROWS, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
|
use rustc_session::lint::builtin::{SAFE_PACKED_BORROWS, UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
|
||||||
|
use rustc_session::lint::Level;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
|
|
||||||
use std::ops::Bound;
|
use std::ops::Bound;
|
||||||
|
@ -220,7 +222,18 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||||
|
|
||||||
for (i, elem) in place.projection.iter().enumerate() {
|
for (i, elem) in place.projection.iter().enumerate() {
|
||||||
let proj_base = &place.projection[..i];
|
let proj_base = &place.projection[..i];
|
||||||
let old_source_info = self.source_info;
|
if context.is_borrow() {
|
||||||
|
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
|
||||||
|
self.require_unsafe(
|
||||||
|
"borrow of packed field",
|
||||||
|
"fields of packed structs might be misaligned: dereferencing a \
|
||||||
|
misaligned pointer or even just creating a misaligned reference \
|
||||||
|
is undefined behavior",
|
||||||
|
UnsafetyViolationKind::BorrowPacked,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let source_info = self.source_info;
|
||||||
if let [] = proj_base {
|
if let [] = proj_base {
|
||||||
let decl = &self.body.local_decls[place.local];
|
let decl = &self.body.local_decls[place.local];
|
||||||
if decl.internal {
|
if decl.internal {
|
||||||
|
@ -301,7 +314,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
self.source_info = old_source_info;
|
self.source_info = source_info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,9 +327,15 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||||
kind: UnsafetyViolationKind,
|
kind: UnsafetyViolationKind,
|
||||||
) {
|
) {
|
||||||
let source_info = self.source_info;
|
let source_info = self.source_info;
|
||||||
|
let lint_root = self.body.source_scopes[self.source_info.scope]
|
||||||
|
.local_data
|
||||||
|
.as_ref()
|
||||||
|
.assert_crate_local()
|
||||||
|
.lint_root;
|
||||||
self.register_violations(
|
self.register_violations(
|
||||||
&[UnsafetyViolation {
|
&[UnsafetyViolation {
|
||||||
source_info,
|
source_info,
|
||||||
|
lint_root,
|
||||||
description: Symbol::intern(description),
|
description: Symbol::intern(description),
|
||||||
details: Symbol::intern(details),
|
details: Symbol::intern(details),
|
||||||
kind,
|
kind,
|
||||||
|
@ -343,7 +362,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||||
match violation.kind {
|
match violation.kind {
|
||||||
UnsafetyViolationKind::GeneralAndConstFn
|
UnsafetyViolationKind::GeneralAndConstFn
|
||||||
| UnsafetyViolationKind::General => {}
|
| UnsafetyViolationKind::General => {}
|
||||||
UnsafetyViolationKind::BorrowPacked(_) => {
|
UnsafetyViolationKind::BorrowPacked => {
|
||||||
if self.min_const_fn {
|
if self.min_const_fn {
|
||||||
// const fns don't need to be backwards compatible and can
|
// const fns don't need to be backwards compatible and can
|
||||||
// emit these violations as a hard error instead of a backwards
|
// emit these violations as a hard error instead of a backwards
|
||||||
|
@ -351,7 +370,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||||
violation.kind = UnsafetyViolationKind::General;
|
violation.kind = UnsafetyViolationKind::General;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnsafetyViolationKind::UnsafeFn(_) => {
|
UnsafetyViolationKind::UnsafeFn => {
|
||||||
bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context")
|
bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,14 +384,9 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||||
Safety::FnUnsafe if self.tcx.features().unsafe_block_in_unsafe_fn => {
|
Safety::FnUnsafe if self.tcx.features().unsafe_block_in_unsafe_fn => {
|
||||||
for violation in violations {
|
for violation in violations {
|
||||||
let mut violation = *violation;
|
let mut violation = *violation;
|
||||||
let lint_root = self.body.source_scopes[self.source_info.scope]
|
|
||||||
.local_data
|
|
||||||
.as_ref()
|
|
||||||
.assert_crate_local()
|
|
||||||
.lint_root;
|
|
||||||
|
|
||||||
// FIXME(LeSeulArtichaut): what to do with `UnsafetyViolationKind::BorrowPacked`?
|
// FIXME(LeSeulArtichaut): what to do with `UnsafetyViolationKind::BorrowPacked`?
|
||||||
violation.kind = UnsafetyViolationKind::UnsafeFn(lint_root);
|
violation.kind = UnsafetyViolationKind::UnsafeFn;
|
||||||
if !self.violations.contains(&violation) {
|
if !self.violations.contains(&violation) {
|
||||||
self.violations.push(violation)
|
self.violations.push(violation)
|
||||||
}
|
}
|
||||||
|
@ -394,7 +408,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||||
UnsafetyViolationKind::GeneralAndConstFn => {}
|
UnsafetyViolationKind::GeneralAndConstFn => {}
|
||||||
// these things are forbidden in const fns
|
// these things are forbidden in const fns
|
||||||
UnsafetyViolationKind::General
|
UnsafetyViolationKind::General
|
||||||
| UnsafetyViolationKind::BorrowPacked(_) => {
|
| UnsafetyViolationKind::BorrowPacked => {
|
||||||
let mut violation = *violation;
|
let mut violation = *violation;
|
||||||
// const fns don't need to be backwards compatible and can
|
// const fns don't need to be backwards compatible and can
|
||||||
// emit these violations as a hard error instead of a backwards
|
// emit these violations as a hard error instead of a backwards
|
||||||
|
@ -404,7 +418,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
||||||
self.violations.push(violation)
|
self.violations.push(violation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnsafetyViolationKind::UnsafeFn(_) => bug!(
|
UnsafetyViolationKind::UnsafeFn => bug!(
|
||||||
"`UnsafetyViolationKind::UnsafeFn` in an `ExplicitUnsafe` context"
|
"`UnsafetyViolationKind::UnsafeFn` in an `ExplicitUnsafe` context"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -657,10 +671,13 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||||
let UnsafetyCheckResult { violations, unsafe_blocks } =
|
let UnsafetyCheckResult { violations, unsafe_blocks } =
|
||||||
tcx.unsafety_check_result(def_id.expect_local());
|
tcx.unsafety_check_result(def_id.expect_local());
|
||||||
|
|
||||||
let or_block_msg = if tcx.features().unsafe_block_in_unsafe_fn { "" } else { " or block" };
|
for &UnsafetyViolation { source_info, lint_root, description, details, kind } in
|
||||||
|
violations.iter()
|
||||||
for &UnsafetyViolation { source_info, description, details, kind } in violations.iter() {
|
{
|
||||||
// Report an error.
|
// Report an error.
|
||||||
|
let unsafe_fn_msg =
|
||||||
|
if unsafe_op_in_unsafe_fn_allowed(tcx, lint_root) { "" } else { " function or" };
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
UnsafetyViolationKind::GeneralAndConstFn | UnsafetyViolationKind::General => {
|
UnsafetyViolationKind::GeneralAndConstFn | UnsafetyViolationKind::General => {
|
||||||
// once
|
// once
|
||||||
|
@ -668,26 +685,26 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
source_info.span,
|
source_info.span,
|
||||||
E0133,
|
E0133,
|
||||||
"{} is unsafe and requires unsafe function{}",
|
"{} is unsafe and requires unsafe{} block",
|
||||||
description,
|
description,
|
||||||
or_block_msg,
|
unsafe_fn_msg,
|
||||||
)
|
)
|
||||||
.span_label(source_info.span, &*description.as_str())
|
.span_label(source_info.span, &*description.as_str())
|
||||||
.note(&details.as_str())
|
.note(&details.as_str())
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
UnsafetyViolationKind::BorrowPacked(lint_hir_id) => {
|
UnsafetyViolationKind::BorrowPacked => {
|
||||||
if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
|
if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
|
||||||
tcx.ensure().unsafe_derive_on_repr_packed(impl_def_id);
|
tcx.ensure().unsafe_derive_on_repr_packed(impl_def_id);
|
||||||
} else {
|
} else {
|
||||||
tcx.struct_span_lint_hir(
|
tcx.struct_span_lint_hir(
|
||||||
SAFE_PACKED_BORROWS,
|
SAFE_PACKED_BORROWS,
|
||||||
lint_hir_id,
|
lint_root,
|
||||||
source_info.span,
|
source_info.span,
|
||||||
|lint| {
|
|lint| {
|
||||||
lint.build(&format!(
|
lint.build(&format!(
|
||||||
"{} is unsafe and requires unsafe function{} (error E0133)",
|
"{} is unsafe and requires unsafe{} block (error E0133)",
|
||||||
description, or_block_msg,
|
description, unsafe_fn_msg,
|
||||||
))
|
))
|
||||||
.note(&details.as_str())
|
.note(&details.as_str())
|
||||||
.emit()
|
.emit()
|
||||||
|
@ -695,9 +712,9 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnsafetyViolationKind::UnsafeFn(lint_hir_id) => tcx.struct_span_lint_hir(
|
UnsafetyViolationKind::UnsafeFn => tcx.struct_span_lint_hir(
|
||||||
UNSAFE_OP_IN_UNSAFE_FN,
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
lint_hir_id,
|
lint_root,
|
||||||
source_info.span,
|
source_info.span,
|
||||||
|lint| {
|
|lint| {
|
||||||
lint.build(&format!(
|
lint.build(&format!(
|
||||||
|
@ -728,3 +745,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||||
report_unused_unsafe(tcx, &unsafe_used, block_id);
|
report_unused_unsafe(tcx, &unsafe_used, block_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unsafe_op_in_unsafe_fn_allowed(tcx: TyCtxt<'_>, id: HirId) -> bool {
|
||||||
|
tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, id).0 == Level::Allow
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
|
||||||
use crate::hair::*;
|
use crate::hair::*;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
|
use rustc_session::lint::builtin::UNSAFE_OP_IN_UNSAFE_FN;
|
||||||
|
use rustc_session::lint::Level;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
|
@ -218,7 +220,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
match self.unpushed_unsafe {
|
match self.unpushed_unsafe {
|
||||||
Safety::Safe => {}
|
Safety::Safe => {}
|
||||||
// no longer treat `unsafe fn`s as `unsafe` contexts (see RFC #2585)
|
// no longer treat `unsafe fn`s as `unsafe` contexts (see RFC #2585)
|
||||||
Safety::FnUnsafe if self.hir.tcx().features().unsafe_block_in_unsafe_fn => {}
|
Safety::FnUnsafe
|
||||||
|
if self.hir.tcx().lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, hir_id).0
|
||||||
|
!= Level::Allow => {}
|
||||||
_ => return,
|
_ => return,
|
||||||
}
|
}
|
||||||
self.unpushed_unsafe = Safety::ExplicitUnsafe(hir_id);
|
self.unpushed_unsafe = Safety::ExplicitUnsafe(hir_id);
|
||||||
|
@ -233,7 +237,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
.push_unsafe_count
|
.push_unsafe_count
|
||||||
.checked_sub(1)
|
.checked_sub(1)
|
||||||
.unwrap_or_else(|| span_bug!(span, "unsafe count underflow"));
|
.unwrap_or_else(|| span_bug!(span, "unsafe count underflow"));
|
||||||
if self.push_unsafe_count == 0 { Some(self.unpushed_unsafe) } else { None }
|
if self.push_unsafe_count == 0 {
|
||||||
|
Some(self.unpushed_unsafe)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
#![deny(unused_unsafe)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
//~^ ERROR the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||||
unsafe fn unsf() {}
|
|
||||||
|
|
||||||
unsafe fn foo() {
|
|
||||||
unsafe { //~ ERROR unnecessary `unsafe` block
|
|
||||||
unsf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,16 +1,30 @@
|
||||||
error: unnecessary `unsafe` block
|
error[E0658]: the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||||
--> $DIR/feature-gate-unsafe_block_in_unsafe_fn.rs:6:5
|
--> $DIR/feature-gate-unsafe_block_in_unsafe_fn.rs:1:1
|
||||||
|
|
|
|
||||||
LL | unsafe fn foo() {
|
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||||
| --------------- because it's nested under this `unsafe` fn
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
LL | unsafe {
|
|
||||||
| ^^^^^^ unnecessary `unsafe` block
|
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
= note: see issue #71668 <https://github.com/rust-lang/rust/issues/71668> for more information
|
||||||
--> $DIR/feature-gate-unsafe_block_in_unsafe_fn.rs:1:9
|
= help: add `#![feature(unsafe_block_in_unsafe_fn)]` to the crate attributes to enable
|
||||||
|
|
|
||||||
LL | #![deny(unused_unsafe)]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error[E0658]: the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||||
|
--> $DIR/feature-gate-unsafe_block_in_unsafe_fn.rs:1:1
|
||||||
|
|
|
||||||
|
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #71668 <https://github.com/rust-lang/rust/issues/71668> for more information
|
||||||
|
= help: add `#![feature(unsafe_block_in_unsafe_fn)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0658]: the `unsafe_op_in_unsafe_fn` lint is unstable
|
||||||
|
--> $DIR/feature-gate-unsafe_block_in_unsafe_fn.rs:1:1
|
||||||
|
|
|
||||||
|
LL | #![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #71668 <https://github.com/rust-lang/rust/issues/71668> for more information
|
||||||
|
= help: add `#![feature(unsafe_block_in_unsafe_fn)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -21,6 +21,12 @@ unsafe fn baz() {
|
||||||
#[allow(unsafe_op_in_unsafe_fn)]
|
#[allow(unsafe_op_in_unsafe_fn)]
|
||||||
unsafe fn qux() {
|
unsafe fn qux() {
|
||||||
unsf(); // no error
|
unsf(); // no error
|
||||||
|
|
||||||
|
unsafe { unsf() }
|
||||||
|
//~^ ERROR unnecessary `unsafe` block
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {
|
||||||
|
unsf()
|
||||||
|
//~^ ERROR call to unsafe function is unsafe and requires unsafe function or block
|
||||||
|
}
|
||||||
|
|
|
@ -25,5 +25,20 @@ note: the lint level is defined here
|
||||||
LL | #![deny(unused_unsafe)]
|
LL | #![deny(unused_unsafe)]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error; 1 warning emitted
|
error: unnecessary `unsafe` block
|
||||||
|
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:5
|
||||||
|
|
|
||||||
|
LL | unsafe { unsf() }
|
||||||
|
| ^^^^^^ unnecessary `unsafe` block
|
||||||
|
|
||||||
|
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||||
|
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:30:5
|
||||||
|
|
|
||||||
|
LL | unsf()
|
||||||
|
| ^^^^^^ call to unsafe function
|
||||||
|
|
|
||||||
|
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0133`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue