Auto merge of #83129 - LeSeulArtichaut:thir-unsafeck, r=nikomatsakis
Introduce the beginning of a THIR unsafety checker This poses the foundations for the THIR unsafety checker, so that it can be implemented incrementally: - implements a rudimentary `Visitor` for the THIR (which will definitely need some tweaking in the future) - introduces a new `-Zthir-unsafeck` flag which tells the compiler to use THIR unsafeck instead of MIR unsafeck - implements detection of unsafe functions - adds revisions to the UI tests to test THIR unsafeck alongside MIR unsafeck This uses a very simple query design, where bodies are unsafety-checked on a body per body basis. This however has some big flaws: - the unsafety-checker builds the THIR itself, which means a lot of work is duplicated with MIR building constructing its own copy of the THIR - unsafety-checking closures is currently completely wrong: closures should take into account the "safety context" in which they are created, here we are considering that closures are always a safe context I had intended to fix these problems in follow-up PRs since they are always gated under the `-Zthir-unsafeck` flag (which is explicitely noted to be unsound). r? `@nikomatsakis` cc https://github.com/rust-lang/project-thir-unsafeck/issues/3 https://github.com/rust-lang/project-thir-unsafeck/issues/7
This commit is contained in:
commit
17b60b8738
@ -876,7 +876,11 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
|
||||
|
||||
sess.time("MIR_effect_checking", || {
|
||||
for def_id in tcx.body_owners() {
|
||||
mir::transform::check_unsafety::check_unsafety(tcx, def_id);
|
||||
if tcx.sess.opts.debugging_opts.thir_unsafeck {
|
||||
tcx.ensure().thir_check_unsafety(def_id);
|
||||
} else {
|
||||
mir::transform::check_unsafety::check_unsafety(tcx, def_id);
|
||||
}
|
||||
|
||||
if tcx.hir().body_const_context(def_id).is_some() {
|
||||
tcx.ensure()
|
||||
|
@ -736,6 +736,7 @@ fn test_debugging_options_tracking_hash() {
|
||||
tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));
|
||||
tracked!(teach, true);
|
||||
tracked!(thinlto, Some(true));
|
||||
tracked!(thir_unsafeck, true);
|
||||
tracked!(tune_cpu, Some(String::from("abc")));
|
||||
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
|
||||
tracked!(trap_unreachable, Some(false));
|
||||
|
@ -611,6 +611,19 @@ rustc_queries! {
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafety-check this `LocalDefId` with THIR unsafeck. This should be
|
||||
/// used with `-Zthir-unsafeck`.
|
||||
query thir_check_unsafety(key: LocalDefId) {
|
||||
desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||
cache_on_disk_if { true }
|
||||
}
|
||||
query thir_check_unsafety_for_const_arg(key: (LocalDefId, DefId)) {
|
||||
desc {
|
||||
|tcx| "unsafety-checking the const argument `{}`",
|
||||
tcx.def_path_str(key.0.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error.
|
||||
///
|
||||
/// Unsafety checking is executed for each method separately, but we only want
|
||||
|
334
compiler/rustc_mir_build/src/check_unsafety.rs
Normal file
334
compiler/rustc_mir_build/src/check_unsafety.rs
Normal file
@ -0,0 +1,334 @@
|
||||
use crate::thir::visit::{self, Visitor};
|
||||
use crate::thir::*;
|
||||
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
|
||||
use rustc_session::lint::Level;
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::Span;
|
||||
|
||||
struct UnsafetyVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
/// The `HirId` of the current scope, which would be the `HirId`
|
||||
/// of the current HIR node, modulo adjustments. Used for lint levels.
|
||||
hir_context: hir::HirId,
|
||||
/// The current "safety context". This notably tracks whether we are in an
|
||||
/// `unsafe` block, and whether it has been used.
|
||||
safety_context: SafetyContext,
|
||||
body_unsafety: BodyUnsafety,
|
||||
}
|
||||
|
||||
impl<'tcx> UnsafetyVisitor<'tcx> {
|
||||
fn in_safety_context<R>(
|
||||
&mut self,
|
||||
safety_context: SafetyContext,
|
||||
f: impl FnOnce(&mut Self) -> R,
|
||||
) {
|
||||
if let (
|
||||
SafetyContext::UnsafeBlock { span: enclosing_span, .. },
|
||||
SafetyContext::UnsafeBlock { span: block_span, hir_id, .. },
|
||||
) = (self.safety_context, safety_context)
|
||||
{
|
||||
self.warn_unused_unsafe(
|
||||
hir_id,
|
||||
block_span,
|
||||
Some(self.tcx.sess.source_map().guess_head_span(enclosing_span)),
|
||||
);
|
||||
f(self);
|
||||
} else {
|
||||
let prev_context = self.safety_context;
|
||||
self.safety_context = safety_context;
|
||||
|
||||
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.safety_context = prev_context;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fn requires_unsafe(&mut self, span: Span, kind: UnsafeOpKind) {
|
||||
let (description, note) = kind.description_and_note();
|
||||
let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed();
|
||||
match self.safety_context {
|
||||
SafetyContext::UnsafeBlock { ref mut used, .. } => {
|
||||
if !self.body_unsafety.is_unsafe() || !unsafe_op_in_unsafe_fn_allowed {
|
||||
// Mark this block as useful
|
||||
*used = true;
|
||||
}
|
||||
}
|
||||
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
|
||||
SafetyContext::UnsafeFn => {
|
||||
// unsafe_op_in_unsafe_fn is disallowed
|
||||
if kind == BorrowOfPackedField {
|
||||
// FIXME handle borrows of packed fields
|
||||
} else {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0133,
|
||||
"{} is unsafe and requires unsafe block",
|
||||
description,
|
||||
)
|
||||
.span_label(span, description)
|
||||
.note(note)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
SafetyContext::Safe => {
|
||||
if kind == BorrowOfPackedField {
|
||||
// FIXME handle borrows of packed fields
|
||||
} else {
|
||||
let fn_sugg = if unsafe_op_in_unsafe_fn_allowed { " function or" } else { "" };
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0133,
|
||||
"{} is unsafe and requires unsafe{} block",
|
||||
description,
|
||||
fn_sugg,
|
||||
)
|
||||
.span_label(span, description)
|
||||
.note(note)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn warn_unused_unsafe(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
block_span: Span,
|
||||
enclosing_span: Option<Span>,
|
||||
) {
|
||||
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"),
|
||||
);
|
||||
}
|
||||
db.emit();
|
||||
});
|
||||
}
|
||||
|
||||
/// Whether the `unsafe_op_in_unsafe_fn` lint is `allow`ed at the current HIR node.
|
||||
fn unsafe_op_in_unsafe_fn_allowed(&self) -> bool {
|
||||
self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, self.hir_context).0 == Level::Allow
|
||||
}
|
||||
}
|
||||
|
||||
impl<'thir, 'tcx> Visitor<'thir, 'tcx> for UnsafetyVisitor<'tcx> {
|
||||
fn visit_block(&mut self, block: &Block<'thir, 'tcx>) {
|
||||
if let BlockSafety::ExplicitUnsafe(hir_id) = block.safety_mode {
|
||||
self.in_safety_context(
|
||||
SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
|
||||
|this| visit::walk_block(this, block),
|
||||
);
|
||||
} else {
|
||||
visit::walk_block(self, block);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'thir Expr<'thir, 'tcx>) {
|
||||
match expr.kind {
|
||||
ExprKind::Scope { value, lint_level: LintLevel::Explicit(hir_id), region_scope: _ } => {
|
||||
let prev_id = self.hir_context;
|
||||
self.hir_context = hir_id;
|
||||
self.visit_expr(value);
|
||||
self.hir_context = prev_id;
|
||||
return;
|
||||
}
|
||||
ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => {
|
||||
if fun.ty.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
|
||||
self.requires_unsafe(expr.span, CallToUnsafeFunction);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
visit::walk_expr(self, expr);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum SafetyContext {
|
||||
Safe,
|
||||
UnsafeFn,
|
||||
UnsafeBlock { span: Span, hir_id: hir::HirId, used: bool },
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum BodyUnsafety {
|
||||
/// The body is not unsafe.
|
||||
Safe,
|
||||
/// The body is an unsafe function. The span points to
|
||||
/// the signature of the function.
|
||||
Unsafe(Span),
|
||||
}
|
||||
|
||||
impl BodyUnsafety {
|
||||
/// Returns whether the body is unsafe.
|
||||
fn is_unsafe(&self) -> bool {
|
||||
matches!(self, BodyUnsafety::Unsafe(_))
|
||||
}
|
||||
|
||||
/// If the body is unsafe, returns the `Span` of its signature.
|
||||
fn unsafe_fn_sig_span(self) -> Option<Span> {
|
||||
match self {
|
||||
BodyUnsafety::Unsafe(span) => Some(span),
|
||||
BodyUnsafety::Safe => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
enum UnsafeOpKind {
|
||||
CallToUnsafeFunction,
|
||||
#[allow(dead_code)] // FIXME
|
||||
UseOfInlineAssembly,
|
||||
#[allow(dead_code)] // FIXME
|
||||
InitializingTypeWith,
|
||||
#[allow(dead_code)] // FIXME
|
||||
CastOfPointerToInt,
|
||||
#[allow(dead_code)] // FIXME
|
||||
BorrowOfPackedField,
|
||||
#[allow(dead_code)] // FIXME
|
||||
UseOfMutableStatic,
|
||||
#[allow(dead_code)] // FIXME
|
||||
UseOfExternStatic,
|
||||
#[allow(dead_code)] // FIXME
|
||||
DerefOfRawPointer,
|
||||
#[allow(dead_code)] // FIXME
|
||||
AssignToDroppingUnionField,
|
||||
#[allow(dead_code)] // FIXME
|
||||
AccessToUnionField,
|
||||
#[allow(dead_code)] // FIXME
|
||||
MutationOfLayoutConstrainedField,
|
||||
#[allow(dead_code)] // FIXME
|
||||
BorrowOfLayoutConstrainedField,
|
||||
#[allow(dead_code)] // FIXME
|
||||
CallToFunctionWith,
|
||||
}
|
||||
|
||||
use UnsafeOpKind::*;
|
||||
|
||||
impl UnsafeOpKind {
|
||||
pub fn description_and_note(&self) -> (&'static str, &'static str) {
|
||||
match self {
|
||||
CallToUnsafeFunction => (
|
||||
"call to unsafe function",
|
||||
"consult the function's documentation for information on how to avoid undefined \
|
||||
behavior",
|
||||
),
|
||||
UseOfInlineAssembly => (
|
||||
"use of inline assembly",
|
||||
"inline assembly is entirely unchecked and can cause undefined behavior",
|
||||
),
|
||||
InitializingTypeWith => (
|
||||
"initializing type with `rustc_layout_scalar_valid_range` attr",
|
||||
"initializing a layout restricted type's field with a value outside the valid \
|
||||
range is undefined behavior",
|
||||
),
|
||||
CastOfPointerToInt => {
|
||||
("cast of pointer to int", "casting pointers to integers in constants")
|
||||
}
|
||||
BorrowOfPackedField => (
|
||||
"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",
|
||||
),
|
||||
UseOfMutableStatic => (
|
||||
"use of mutable static",
|
||||
"mutable statics can be mutated by multiple threads: aliasing violations or data \
|
||||
races will cause undefined behavior",
|
||||
),
|
||||
UseOfExternStatic => (
|
||||
"use of extern static",
|
||||
"extern statics are not controlled by the Rust type system: invalid data, \
|
||||
aliasing violations or data races will cause undefined behavior",
|
||||
),
|
||||
DerefOfRawPointer => (
|
||||
"dereference of raw pointer",
|
||||
"raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules \
|
||||
and cause data races: all of these are undefined behavior",
|
||||
),
|
||||
AssignToDroppingUnionField => (
|
||||
"assignment to union field that might need dropping",
|
||||
"the previous content of the field will be dropped, which causes undefined \
|
||||
behavior if the field was not properly initialized",
|
||||
),
|
||||
AccessToUnionField => (
|
||||
"access to union field",
|
||||
"the field may not be properly initialized: using uninitialized data will cause \
|
||||
undefined behavior",
|
||||
),
|
||||
MutationOfLayoutConstrainedField => (
|
||||
"mutation of layout constrained field",
|
||||
"mutating layout constrained fields cannot statically be checked for valid values",
|
||||
),
|
||||
BorrowOfLayoutConstrainedField => (
|
||||
"borrow of layout constrained field with interior mutability",
|
||||
"references to fields of layout constrained fields lose the constraints. Coupled \
|
||||
with interior mutability, the field can be changed to invalid values",
|
||||
),
|
||||
CallToFunctionWith => (
|
||||
"call to function with `#[target_feature]`",
|
||||
"can only be called if the required target features are available",
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: checking unsafety for closures should be handled by their parent body,
|
||||
// as they inherit their "safety context" from their declaration site.
|
||||
pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, thir: &Expr<'_, 'tcx>, hir_id: hir::HirId) {
|
||||
let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| {
|
||||
if fn_sig.header.unsafety == hir::Unsafety::Unsafe {
|
||||
BodyUnsafety::Unsafe(fn_sig.span)
|
||||
} else {
|
||||
BodyUnsafety::Safe
|
||||
}
|
||||
});
|
||||
let safety_context =
|
||||
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
|
||||
let mut visitor = UnsafetyVisitor { tcx, safety_context, hir_context: hir_id, body_unsafety };
|
||||
visitor.visit_expr(thir);
|
||||
}
|
||||
|
||||
crate fn thir_check_unsafety_inner<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
|
||||
let body_id = tcx.hir().body_owned_by(hir_id);
|
||||
let body = tcx.hir().body(body_id);
|
||||
|
||||
let arena = Arena::default();
|
||||
let thir = cx::build_thir(tcx, def, &arena, &body.value);
|
||||
check_unsafety(tcx, thir, hir_id);
|
||||
}
|
||||
|
||||
crate fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
|
||||
if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
|
||||
tcx.thir_check_unsafety_for_const_arg(def)
|
||||
} else {
|
||||
thir_check_unsafety_inner(tcx, ty::WithOptConstParam::unknown(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
crate fn thir_check_unsafety_for_const_arg<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(did, param_did): (LocalDefId, DefId),
|
||||
) {
|
||||
thir_check_unsafety_inner(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
|
||||
}
|
@ -19,6 +19,7 @@ extern crate tracing;
|
||||
extern crate rustc_middle;
|
||||
|
||||
mod build;
|
||||
mod check_unsafety;
|
||||
mod lints;
|
||||
pub mod thir;
|
||||
|
||||
@ -28,4 +29,6 @@ pub fn provide(providers: &mut Providers) {
|
||||
providers.check_match = thir::pattern::check_match;
|
||||
providers.lit_to_const = thir::constant::lit_to_const;
|
||||
providers.mir_built = build::mir_built;
|
||||
providers.thir_check_unsafety = check_unsafety::thir_check_unsafety;
|
||||
providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ mod arena;
|
||||
pub use arena::Arena;
|
||||
|
||||
mod util;
|
||||
pub mod visit;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum LintLevel {
|
||||
|
186
compiler/rustc_mir_build/src/thir/visit.rs
Normal file
186
compiler/rustc_mir_build/src/thir/visit.rs
Normal file
@ -0,0 +1,186 @@
|
||||
use crate::thir::*;
|
||||
|
||||
pub trait Visitor<'thir, 'tcx>: Sized {
|
||||
fn visit_expr(&mut self, expr: &'thir Expr<'thir, 'tcx>) {
|
||||
walk_expr(self, expr);
|
||||
}
|
||||
|
||||
fn visit_stmt(&mut self, stmt: &'thir Stmt<'thir, 'tcx>) {
|
||||
walk_stmt(self, stmt);
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, block: &Block<'thir, 'tcx>) {
|
||||
walk_block(self, block);
|
||||
}
|
||||
|
||||
fn visit_arm(&mut self, arm: &'thir Arm<'thir, 'tcx>) {
|
||||
walk_arm(self, arm);
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
|
||||
}
|
||||
|
||||
pub fn walk_expr<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
|
||||
visitor: &mut V,
|
||||
expr: &'thir Expr<'thir, 'tcx>,
|
||||
) {
|
||||
use ExprKind::*;
|
||||
match expr.kind {
|
||||
Scope { value, region_scope: _, lint_level: _ } => visitor.visit_expr(value),
|
||||
Box { value } => visitor.visit_expr(value),
|
||||
If { cond, then, else_opt } => {
|
||||
visitor.visit_expr(cond);
|
||||
visitor.visit_expr(then);
|
||||
if let Some(else_expr) = else_opt {
|
||||
visitor.visit_expr(else_expr);
|
||||
}
|
||||
}
|
||||
Call { fun, args, ty: _, from_hir_call: _, fn_span: _ } => {
|
||||
visitor.visit_expr(fun);
|
||||
for arg in args {
|
||||
visitor.visit_expr(arg);
|
||||
}
|
||||
}
|
||||
Deref { arg } => visitor.visit_expr(arg),
|
||||
Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => {
|
||||
visitor.visit_expr(lhs);
|
||||
visitor.visit_expr(rhs);
|
||||
}
|
||||
Unary { arg, op: _ } => visitor.visit_expr(arg),
|
||||
Cast { source } => visitor.visit_expr(source),
|
||||
Use { source } => visitor.visit_expr(source),
|
||||
NeverToAny { source } => visitor.visit_expr(source),
|
||||
Pointer { source, cast: _ } => visitor.visit_expr(source),
|
||||
Loop { body } => visitor.visit_expr(body),
|
||||
Match { scrutinee, arms } => {
|
||||
visitor.visit_expr(scrutinee);
|
||||
for arm in arms {
|
||||
visitor.visit_arm(arm);
|
||||
}
|
||||
}
|
||||
Block { ref body } => visitor.visit_block(body),
|
||||
Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
|
||||
visitor.visit_expr(lhs);
|
||||
visitor.visit_expr(rhs);
|
||||
}
|
||||
Field { lhs, name: _ } => visitor.visit_expr(lhs),
|
||||
Index { lhs, index } => {
|
||||
visitor.visit_expr(lhs);
|
||||
visitor.visit_expr(index);
|
||||
}
|
||||
VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
|
||||
Borrow { arg, borrow_kind: _ } => visitor.visit_expr(arg),
|
||||
AddressOf { arg, mutability: _ } => visitor.visit_expr(arg),
|
||||
Break { value, label: _ } => {
|
||||
if let Some(value) = value {
|
||||
visitor.visit_expr(value)
|
||||
}
|
||||
}
|
||||
Continue { label: _ } => {}
|
||||
Return { value } => {
|
||||
if let Some(value) = value {
|
||||
visitor.visit_expr(value)
|
||||
}
|
||||
}
|
||||
ConstBlock { value } => visitor.visit_const(value),
|
||||
Repeat { value, count } => {
|
||||
visitor.visit_expr(value);
|
||||
visitor.visit_const(count);
|
||||
}
|
||||
Array { fields } | Tuple { fields } => {
|
||||
for field in fields {
|
||||
visitor.visit_expr(field);
|
||||
}
|
||||
}
|
||||
Adt { fields, ref base, adt_def: _, variant_index: _, substs: _, user_ty: _ } => {
|
||||
for field in fields {
|
||||
visitor.visit_expr(field.expr);
|
||||
}
|
||||
if let Some(base) = base {
|
||||
visitor.visit_expr(base.base);
|
||||
}
|
||||
}
|
||||
PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
|
||||
visitor.visit_expr(source)
|
||||
}
|
||||
Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
|
||||
Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
|
||||
StaticRef { literal, def_id: _ } => visitor.visit_const(literal),
|
||||
InlineAsm { operands, template: _, options: _, line_spans: _ } => {
|
||||
for op in operands {
|
||||
use InlineAsmOperand::*;
|
||||
match op {
|
||||
In { expr, reg: _ }
|
||||
| Out { expr: Some(expr), reg: _, late: _ }
|
||||
| InOut { expr, reg: _, late: _ }
|
||||
| SymFn { expr } => visitor.visit_expr(expr),
|
||||
SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
|
||||
visitor.visit_expr(in_expr);
|
||||
if let Some(out_expr) = out_expr {
|
||||
visitor.visit_expr(out_expr);
|
||||
}
|
||||
}
|
||||
Out { expr: None, reg: _, late: _ }
|
||||
| Const { value: _, span: _ }
|
||||
| SymStatic { def_id: _ } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
ThreadLocalRef(_) => {}
|
||||
LlvmInlineAsm { outputs, inputs, asm: _ } => {
|
||||
for out_expr in outputs {
|
||||
visitor.visit_expr(out_expr);
|
||||
}
|
||||
for in_expr in inputs {
|
||||
visitor.visit_expr(in_expr);
|
||||
}
|
||||
}
|
||||
Yield { value } => visitor.visit_expr(value),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_stmt<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
|
||||
visitor: &mut V,
|
||||
stmt: &'thir Stmt<'thir, 'tcx>,
|
||||
) {
|
||||
match stmt.kind {
|
||||
StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(expr),
|
||||
StmtKind::Let {
|
||||
initializer,
|
||||
remainder_scope: _,
|
||||
init_scope: _,
|
||||
pattern: _,
|
||||
lint_level: _,
|
||||
} => {
|
||||
if let Some(init) = initializer {
|
||||
visitor.visit_expr(init);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_block<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
|
||||
visitor: &mut V,
|
||||
block: &Block<'thir, 'tcx>,
|
||||
) {
|
||||
for stmt in block.stmts {
|
||||
visitor.visit_stmt(stmt);
|
||||
}
|
||||
if let Some(expr) = block.expr {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_arm<'thir, 'tcx, V: Visitor<'thir, 'tcx>>(
|
||||
visitor: &mut V,
|
||||
arm: &'thir Arm<'thir, 'tcx>,
|
||||
) {
|
||||
match arm.guard {
|
||||
Some(Guard::If(expr)) => visitor.visit_expr(expr),
|
||||
Some(Guard::IfLet(ref _pat, expr)) => {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
visitor.visit_expr(arm.body);
|
||||
}
|
@ -1254,6 +1254,8 @@ options! {
|
||||
"select processor to schedule for (`rustc --print target-cpus` for details)"),
|
||||
thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"enable ThinLTO when possible"),
|
||||
thir_unsafeck: bool = (false, parse_bool, [TRACKED],
|
||||
"use the work-in-progress THIR unsafety checker. NOTE: this is unsound (default: no)"),
|
||||
/// We default to 1 here since we want to behave like
|
||||
/// a sequential compiler for now. This'll likely be adjusted
|
||||
/// in the future. Note that -Zthreads=0 is the way to get
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/async-unsafe-fn-call-in-safe.rs:12:5
|
||||
--> $DIR/async-unsafe-fn-call-in-safe.rs:14:5
|
||||
|
|
||||
LL | S::f();
|
||||
| ^^^^^^ call to unsafe function
|
||||
@ -7,7 +7,7 @@ LL | S::f();
|
||||
= 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/async-unsafe-fn-call-in-safe.rs:13:5
|
||||
--> $DIR/async-unsafe-fn-call-in-safe.rs:15:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ call to unsafe function
|
||||
@ -15,7 +15,7 @@ LL | f();
|
||||
= 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/async-unsafe-fn-call-in-safe.rs:17:5
|
||||
--> $DIR/async-unsafe-fn-call-in-safe.rs:19:5
|
||||
|
|
||||
LL | S::f();
|
||||
| ^^^^^^ call to unsafe function
|
||||
@ -23,7 +23,7 @@ LL | S::f();
|
||||
= 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/async-unsafe-fn-call-in-safe.rs:18:5
|
||||
--> $DIR/async-unsafe-fn-call-in-safe.rs:20:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ call to unsafe function
|
@ -1,4 +1,6 @@
|
||||
// edition:2018
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
struct S;
|
||||
|
||||
|
@ -0,0 +1,35 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/async-unsafe-fn-call-in-safe.rs:14:5
|
||||
|
|
||||
LL | S::f();
|
||||
| ^^^^^^ 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/async-unsafe-fn-call-in-safe.rs:15:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ 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/async-unsafe-fn-call-in-safe.rs:19:5
|
||||
|
|
||||
LL | S::f();
|
||||
| ^^^^^^ 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/async-unsafe-fn-call-in-safe.rs:20:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/closure_no_cap_coerce_many_unsafe_0.rs:12:23
|
||||
--> $DIR/closure_no_cap_coerce_many_unsafe_0.rs:15:23
|
||||
|
|
||||
LL | let result: i32 = foo(5, 5);
|
||||
| ^^^^^^^^^ call to unsafe function
|
||||
@ -7,7 +7,7 @@ LL | let result: i32 = foo(5, 5);
|
||||
= 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/closure_no_cap_coerce_many_unsafe_0.rs:21:23
|
||||
--> $DIR/closure_no_cap_coerce_many_unsafe_0.rs:24:23
|
||||
|
|
||||
LL | let result: i32 = foo(5, 5);
|
||||
| ^^^^^^^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
// Ensure we get unsafe function after coercion
|
||||
unsafe fn add(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
|
@ -0,0 +1,19 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/closure_no_cap_coerce_many_unsafe_0.rs:15:23
|
||||
|
|
||||
LL | let result: i32 = foo(5, 5);
|
||||
| ^^^^^^^^^ 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/closure_no_cap_coerce_many_unsafe_0.rs:24:23
|
||||
|
|
||||
LL | let result: i32 = foo(5, 5);
|
||||
| ^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/coerce-unsafe-closure-to-unsafe-fn-ptr.rs:2:31
|
||||
--> $DIR/coerce-unsafe-closure-to-unsafe-fn-ptr.rs:5:31
|
||||
|
|
||||
LL | let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
fn main() {
|
||||
let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
|
||||
//~^ ERROR E0133
|
||||
|
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/coerce-unsafe-closure-to-unsafe-fn-ptr.rs:5:31
|
||||
|
|
||||
LL | let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/const-extern-fn-requires-unsafe.rs:8:5
|
||||
--> $DIR/const-extern-fn-requires-unsafe.rs:11:5
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^^^ call to unsafe function
|
||||
@ -7,7 +7,7 @@ LL | foo();
|
||||
= 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/const-extern-fn-requires-unsafe.rs:6:17
|
||||
--> $DIR/const-extern-fn-requires-unsafe.rs:9:17
|
||||
|
|
||||
LL | let a: [u8; foo()];
|
||||
| ^^^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
#![feature(const_extern_fn)]
|
||||
|
||||
const unsafe extern "C" fn foo() -> usize { 5 }
|
||||
|
@ -0,0 +1,19 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/const-extern-fn-requires-unsafe.rs:11:5
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^^^ 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/const-extern-fn-requires-unsafe.rs:9:17
|
||||
|
|
||||
LL | let a: [u8; foo()];
|
||||
| ^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/E0133.rs:4:5
|
||||
--> $DIR/E0133.rs:7:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
unsafe fn f() { return; }
|
||||
|
||||
fn main() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-fn-called-from-safe.rs:4:5
|
||||
--> $DIR/E0133.rs:7:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ call to unsafe function
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:8:43
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:11:43
|
||||
|
|
||||
LL | const fn transmute_fn() -> u32 { unsafe { mem::transmute(Foo(3)) } }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -9,7 +9,7 @@ LL | const fn transmute_fn() -> u32 { unsafe { mem::transmute(Foo(3)) } }
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:11:53
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:14:53
|
||||
|
|
||||
LL | const fn transmute_fn_intrinsic() -> u32 { unsafe { std::intrinsics::transmute(Foo(3)) } }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -19,7 +19,7 @@ LL | const fn transmute_fn_intrinsic() -> u32 { unsafe { std::intrinsics::transm
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:14:58
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:17:58
|
||||
|
|
||||
LL | const fn transmute_fn_core_intrinsic() -> u32 { unsafe { core::intrinsics::transmute(Foo(3)) } }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -29,7 +29,7 @@ LL | const fn transmute_fn_core_intrinsic() -> u32 { unsafe { core::intrinsics::
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:17:48
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:20:48
|
||||
|
|
||||
LL | const unsafe fn unsafe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -39,7 +39,7 @@ LL | const unsafe fn unsafe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:20:58
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:23:58
|
||||
|
|
||||
LL | const unsafe fn unsafe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -49,7 +49,7 @@ LL | const unsafe fn unsafe_transmute_fn_intrinsic() -> u32 { std::intrinsics::t
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:23:63
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:26:63
|
||||
|
|
||||
LL | const unsafe fn unsafe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -59,7 +59,7 @@ LL | const unsafe fn unsafe_transmute_fn_core_intrinsic() -> u32 { core::intrins
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:26:39
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:29:39
|
||||
|
|
||||
LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -69,7 +69,7 @@ LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:30:49
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:33:49
|
||||
|
|
||||
LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -79,7 +79,7 @@ LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:34:54
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:37:54
|
||||
|
|
||||
LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -89,7 +89,7 @@ LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::tran
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:26:39
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:29:39
|
||||
|
|
||||
LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
@ -97,7 +97,7 @@ LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
= 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/feature-gate-const_fn_transmute.rs:30:49
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:33:49
|
||||
|
|
||||
LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
@ -105,7 +105,7 @@ LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(
|
||||
= 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/feature-gate-const_fn_transmute.rs:34:54
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:37:54
|
||||
|
|
||||
LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
use std::mem;
|
||||
|
||||
#[repr(transparent)]
|
||||
|
@ -0,0 +1,118 @@
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:11:43
|
||||
|
|
||||
LL | const fn transmute_fn() -> u32 { unsafe { mem::transmute(Foo(3)) } }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:14:53
|
||||
|
|
||||
LL | const fn transmute_fn_intrinsic() -> u32 { unsafe { std::intrinsics::transmute(Foo(3)) } }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:17:58
|
||||
|
|
||||
LL | const fn transmute_fn_core_intrinsic() -> u32 { unsafe { core::intrinsics::transmute(Foo(3)) } }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:20:48
|
||||
|
|
||||
LL | const unsafe fn unsafe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:23:58
|
||||
|
|
||||
LL | const unsafe fn unsafe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:26:63
|
||||
|
|
||||
LL | const unsafe fn unsafe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:29:39
|
||||
|
|
||||
LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:33:49
|
||||
|
|
||||
LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0658]: `transmute` is not allowed in constant functions
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:37:54
|
||||
|
|
||||
LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
|
||||
= help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
|
||||
= note: `transmute` is only allowed in constants and statics for now
|
||||
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/feature-gate-const_fn_transmute.rs:29:39
|
||||
|
|
||||
LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ 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/feature-gate-const_fn_transmute.rs:33:49
|
||||
|
|
||||
LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/feature-gate-const_fn_transmute.rs:37:54
|
||||
|
|
||||
LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0133, E0658.
|
||||
For more information about an error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/foreign-unsafe-fn-called.rs:8:5
|
||||
--> $DIR/foreign-unsafe-fn-called.rs:11:5
|
||||
|
|
||||
LL | test::free();
|
||||
| ^^^^^^^^^^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
mod test {
|
||||
extern "C" {
|
||||
pub fn free();
|
||||
|
11
src/test/ui/foreign-unsafe-fn-called.thir.stderr
Normal file
11
src/test/ui/foreign-unsafe-fn-called.thir.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/foreign-unsafe-fn-called.rs:11:5
|
||||
|
|
||||
LL | test::free();
|
||||
| ^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unchecked_math_unsafe.rs:5:15
|
||||
--> $DIR/unchecked_math_unsafe.rs:8:15
|
||||
|
|
||||
LL | let add = std::intrinsics::unchecked_add(x, y);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
@ -7,7 +7,7 @@ LL | let add = std::intrinsics::unchecked_add(x, y);
|
||||
= 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/unchecked_math_unsafe.rs:6:15
|
||||
--> $DIR/unchecked_math_unsafe.rs:9:15
|
||||
|
|
||||
LL | let sub = std::intrinsics::unchecked_sub(x, y);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
@ -15,7 +15,7 @@ LL | let sub = std::intrinsics::unchecked_sub(x, y);
|
||||
= 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/unchecked_math_unsafe.rs:7:15
|
||||
--> $DIR/unchecked_math_unsafe.rs:10:15
|
||||
|
|
||||
LL | let mul = std::intrinsics::unchecked_mul(x, y);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
fn main() {
|
||||
|
27
src/test/ui/intrinsics/unchecked_math_unsafe.thir.stderr
Normal file
27
src/test/ui/intrinsics/unchecked_math_unsafe.thir.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unchecked_math_unsafe.rs:8:15
|
||||
|
|
||||
LL | let add = std::intrinsics::unchecked_add(x, y);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/unchecked_math_unsafe.rs:9:15
|
||||
|
|
||||
LL | let sub = std::intrinsics::unchecked_sub(x, y);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/unchecked_math_unsafe.rs:10:15
|
||||
|
|
||||
LL | let mul = std::intrinsics::unchecked_mul(x, y);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-28776.rs:4:5
|
||||
--> $DIR/issue-28776.rs:7:5
|
||||
|
|
||||
LL | (&ptr::write)(1 as *mut _, 42);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
use std::ptr;
|
||||
|
||||
fn main() {
|
||||
|
11
src/test/ui/issues/issue-28776.thir.stderr
Normal file
11
src/test/ui/issues/issue-28776.thir.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-28776.rs:7:5
|
||||
|
|
||||
LL | (&ptr::write)(1 as *mut _, 42);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-3080.rs:7:5
|
||||
--> $DIR/issue-3080.rs:10:5
|
||||
|
|
||||
LL | X(()).with();
|
||||
| ^^^^^^^^^^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
struct X(());
|
||||
impl X {
|
||||
pub unsafe fn with(&self) { }
|
||||
|
11
src/test/ui/issues/issue-3080.thir.stderr
Normal file
11
src/test/ui/issues/issue-3080.thir.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-3080.rs:10:5
|
||||
|
|
||||
LL | X(()).with();
|
||||
| ^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,17 +1,17 @@
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/issue-48131.rs:9:9
|
||||
--> $DIR/issue-48131.rs:12:9
|
||||
|
|
||||
LL | unsafe { /* unnecessary */ }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-48131.rs:3:9
|
||||
--> $DIR/issue-48131.rs:6:9
|
||||
|
|
||||
LL | #![deny(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/issue-48131.rs:20:13
|
||||
--> $DIR/issue-48131.rs:23:13
|
||||
|
|
||||
LL | unsafe { /* unnecessary */ }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
// This note is annotated because the purpose of the test
|
||||
// is to ensure that certain other notes are not generated.
|
||||
#![deny(unused_unsafe)] //~ NOTE
|
||||
|
20
src/test/ui/issues/issue-48131.thir.stderr
Normal file
20
src/test/ui/issues/issue-48131.thir.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/issue-48131.rs:12:9
|
||||
|
|
||||
LL | unsafe { /* unnecessary */ }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-48131.rs:6:9
|
||||
|
|
||||
LL | #![deny(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/issue-48131.rs:23:13
|
||||
|
|
||||
LL | unsafe { /* unnecessary */ }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-5844.rs:6:5
|
||||
--> $DIR/issue-5844.rs:8:5
|
||||
|
|
||||
LL | issue_5844_aux::rand();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
@ -1,4 +1,6 @@
|
||||
//aux-build:issue-5844-aux.rs
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
extern crate issue_5844_aux;
|
||||
|
||||
|
11
src/test/ui/issues/issue-5844.thir.stderr
Normal file
11
src/test/ui/issues/issue-5844.thir.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-5844.rs:8:5
|
||||
|
|
||||
LL | issue_5844_aux::rand();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -7,10 +7,10 @@ LL | __KEY.get(Default::default)
|
||||
= 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/issue-43733.rs:21:5
|
||||
--> $DIR/issue-43733.rs:20:42
|
||||
|
|
||||
LL | std::thread::LocalKey::new(__getit);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
LL | static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
#![feature(thread_local)]
|
||||
#![feature(cfg_target_thread_local, thread_local_internals)]
|
||||
|
||||
@ -5,26 +8,24 @@ type Foo = std::cell::RefCell<String>;
|
||||
|
||||
#[cfg(target_thread_local)]
|
||||
#[thread_local]
|
||||
static __KEY: std::thread::__FastLocalKeyInner<Foo> =
|
||||
std::thread::__FastLocalKeyInner::new();
|
||||
static __KEY: std::thread::__FastLocalKeyInner<Foo> = std::thread::__FastLocalKeyInner::new();
|
||||
|
||||
#[cfg(not(target_thread_local))]
|
||||
static __KEY: std::thread::__OsLocalKeyInner<Foo> =
|
||||
std::thread::__OsLocalKeyInner::new();
|
||||
static __KEY: std::thread::__OsLocalKeyInner<Foo> = std::thread::__OsLocalKeyInner::new();
|
||||
|
||||
fn __getit() -> std::option::Option<&'static Foo>
|
||||
{
|
||||
fn __getit() -> std::option::Option<&'static Foo> {
|
||||
__KEY.get(Default::default) //~ ERROR call to unsafe function is unsafe
|
||||
}
|
||||
|
||||
static FOO: std::thread::LocalKey<Foo> =
|
||||
std::thread::LocalKey::new(__getit);
|
||||
static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit);
|
||||
//~^ ERROR call to unsafe function is unsafe
|
||||
|
||||
fn main() {
|
||||
FOO.with(|foo| println!("{}", foo.borrow()));
|
||||
std::thread::spawn(|| {
|
||||
FOO.with(|foo| *foo.borrow_mut() += "foo");
|
||||
}).join().unwrap();
|
||||
})
|
||||
.join()
|
||||
.unwrap();
|
||||
FOO.with(|foo| println!("{}", foo.borrow()));
|
||||
}
|
||||
|
19
src/test/ui/threads-sendsync/issue-43733.thir.stderr
Normal file
19
src/test/ui/threads-sendsync/issue-43733.thir.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-43733.rs:17:5
|
||||
|
|
||||
LL | __KEY.get(Default::default)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/issue-43733.rs:20:42
|
||||
|
|
||||
LL | static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,11 +1,11 @@
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:6:5
|
||||
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:5
|
||||
|
|
||||
LL | unsafe { println!("foo"); }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:3:9
|
||||
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:6:9
|
||||
|
|
||||
LL | #![deny(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
@ -1,5 +1,8 @@
|
||||
// issue #12418
|
||||
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
#![deny(unused_unsafe)]
|
||||
|
||||
fn main() {
|
||||
|
@ -0,0 +1,14 @@
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:5
|
||||
|
|
||||
LL | unsafe { println!("foo"); }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unsafe-around-compiler-generated-unsafe.rs:6:9
|
||||
|
|
||||
LL | #![deny(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-const-fn.rs:7:18
|
||||
--> $DIR/unsafe-const-fn.rs:10:18
|
||||
|
|
||||
LL | const VAL: u32 = dummy(0xFFFF);
|
||||
| ^^^^^^^^^^^^^ call to unsafe function
|
@ -1,5 +1,8 @@
|
||||
// A quick test of 'unsafe const fn' functionality
|
||||
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
const unsafe fn dummy(v: u32) -> u32 {
|
||||
!v
|
||||
}
|
||||
|
11
src/test/ui/unsafe/unsafe-const-fn.thir.stderr
Normal file
11
src/test/ui/unsafe/unsafe-const-fn.thir.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-const-fn.rs:10:18
|
||||
|
|
||||
LL | const VAL: u32 = dummy(0xFFFF);
|
||||
| ^^^^^^^^^^^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
11
src/test/ui/unsafe/unsafe-fn-called-from-safe.mir.stderr
Normal file
11
src/test/ui/unsafe/unsafe-fn-called-from-safe.mir.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-fn-called-from-safe.rs:7:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
unsafe fn f() { return; }
|
||||
|
||||
fn main() {
|
||||
|
11
src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr
Normal file
11
src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-fn-called-from-safe.rs:7:5
|
||||
|
|
||||
LL | f();
|
||||
| ^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -1,5 +1,5 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-fn-used-as-value.rs:5:5
|
||||
--> $DIR/unsafe-fn-used-as-value.rs:8:5
|
||||
|
|
||||
LL | x();
|
||||
| ^^^ call to unsafe function
|
@ -1,3 +1,6 @@
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
unsafe fn f() { return; }
|
||||
|
||||
fn main() {
|
||||
|
11
src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr
Normal file
11
src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
|
||||
--> $DIR/unsafe-fn-used-as-value.rs:8:5
|
||||
|
|
||||
LL | x();
|
||||
| ^^^ call to unsafe function
|
||||
|
|
||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
@ -7,8 +7,8 @@ use std::path::Path;
|
||||
|
||||
const ENTRY_LIMIT: usize = 1000;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ROOT_ENTRY_LIMIT: usize = 1388;
|
||||
const ISSUES_ENTRY_LIMIT: usize = 2551;
|
||||
const ROOT_ENTRY_LIMIT: usize = 1370;
|
||||
const ISSUES_ENTRY_LIMIT: usize = 2555;
|
||||
|
||||
fn check_entries(path: &Path, bad: &mut bool) {
|
||||
let dirs = walkdir::WalkDir::new(&path.join("test/ui"))
|
||||
|
Loading…
x
Reference in New Issue
Block a user