Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some convenience helper methods on hir::Safety #134285

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/codegen_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
sym::target_feature => {
if !tcx.is_closure_like(did.to_def_id())
&& let Some(fn_sig) = fn_sig()
&& fn_sig.skip_binder().safety() == hir::Safety::Safe
&& fn_sig.skip_binder().safety().is_safe()
{
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
// The `#[target_feature]` attribute is allowed on
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
Some(stab) => {
if cfg!(debug_assertions) && stab.promotable {
let sig = tcx.fn_sig(def_id);
assert_eq!(
sig.skip_binder().safety(),
hir::Safety::Safe,
assert!(
sig.skip_binder().safety().is_safe(),
"don't mark const unsafe fns as promotable",
// https://github.com/rust-lang/rust/pull/53851#issuecomment-418760682
);
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3401,6 +3401,17 @@ impl Safety {
Self::Safe => "",
}
}

pub fn is_unsafe(self) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
pub fn is_unsafe(self) -> bool {
#[inline]
pub fn is_unsafe(self) -> bool {

!self.is_safe()
}

pub fn is_safe(self) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
pub fn is_safe(self) -> bool {
#[inline]
pub fn is_safe(self) -> bool {

match self {
Self::Unsafe => false,
Self::Safe => true,
}
}
}

impl fmt::Display for Safety {
Expand Down Expand Up @@ -3445,7 +3456,7 @@ impl FnHeader {
}

pub fn is_unsafe(&self) -> bool {
matches!(&self.safety, Safety::Unsafe)
self.safety.is_unsafe()
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::MultiSpan;
use rustc_errors::codes::*;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::{Node, Safety, intravisit};
use rustc_hir::{Node, intravisit};
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::{Obligation, ObligationCauseCode};
use rustc_lint_defs::builtin::{
Expand Down Expand Up @@ -161,7 +161,7 @@ fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) {
};
let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
for field in def.all_fields() {
if field.safety != Safety::Unsafe {
if !field.safety.is_unsafe() {
continue;
}
let Ok(field_ty) = tcx.try_normalize_erasing_regions(typing_env, field.ty(tcx, args))
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
let outer_universe = self.infcx.universe();

let result = if let ty::FnPtr(_, hdr_b) = b.kind()
&& let (hir::Safety::Safe, hir::Safety::Unsafe) = (fn_ty_a.safety(), hdr_b.safety)
&& fn_ty_a.safety().is_safe()
&& hdr_b.safety.is_unsafe()
{
let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
self.unify_and(unsafe_a, b, to_unsafe)
Expand Down Expand Up @@ -925,7 +926,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {

// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).

if b_hdr.safety == hir::Safety::Safe
if b_hdr.safety.is_safe()
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
{
return Err(TypeError::TargetFeatureCast(def_id));
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id)
&& let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity()
&& let sig = method_ty.fn_sig(self.fcx.tcx)
&& let hir::Safety::Unsafe = sig.safety()
&& sig.safety().is_unsafe()
{
let mut collector = InferVarCollector {
value: (ex.hir_id, ex.span, UnsafeUseReason::Method),
Expand All @@ -785,7 +785,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(

if func_ty.is_fn()
&& let sig = func_ty.fn_sig(self.fcx.tcx)
&& let hir::Safety::Unsafe = sig.safety()
&& sig.safety().is_unsafe()
{
let mut collector = InferVarCollector {
value: (ex.hir_id, ex.span, UnsafeUseReason::Call),
Expand Down Expand Up @@ -816,7 +816,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
// `is_fn` excludes closures, but those can't be unsafe.
if ty.is_fn()
&& let sig = ty.fn_sig(self.fcx.tcx)
&& let hir::Safety::Unsafe = sig.safety()
&& sig.safety().is_unsafe()
{
let mut collector = InferVarCollector {
value: (ex.hir_id, ex.span, UnsafeUseReason::Path),
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
}

fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
self.trait_def(trait_def_id).safety == hir::Safety::Unsafe
self.trait_def(trait_def_id).safety.is_unsafe()
}

fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
Expand Down Expand Up @@ -722,7 +722,7 @@ impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
}

fn is_safe(self) -> bool {
matches!(self, hir::Safety::Safe)
self.is_safe()
}

fn prefix_str(self) -> &'static str {
Expand Down Expand Up @@ -2521,7 +2521,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// that is, a `fn` type that is equivalent in every way for being
/// unsafe.
pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
assert_eq!(sig.safety(), hir::Safety::Safe);
assert!(sig.safety().is_safe());
Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ use rustc_data_structures::intern::Interned;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::steal::Steal;
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
use rustc_hir::LangItem;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
use rustc_hir::{LangItem, Safety};
use rustc_index::IndexVec;
use rustc_macros::{
Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
Expand Down Expand Up @@ -1279,7 +1279,7 @@ impl VariantDef {

/// Returns whether this variant has unsafe fields.
pub fn has_unsafe_fields(&self) -> bool {
self.fields.iter().any(|x| x.safety == Safety::Unsafe)
self.fields.iter().any(|x| x.safety.is_unsafe())
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ impl<'tcx> Ty<'tcx> {
/// Checks whether this type is an ADT that has unsafe fields.
pub fn has_unsafe_fields(self) -> bool {
if let ty::Adt(adt_def, ..) = self.kind() {
adt_def.all_fields().any(|x| x.safety == hir::Safety::Unsafe)
adt_def.all_fields().any(|x| x.safety.is_unsafe())
} else {
false
}
Expand Down
16 changes: 6 additions & 10 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::ops::Bound;

use rustc_errors::DiagArgValue;
use rustc_hir::def::DefKind;
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Safety};
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
use rustc_middle::mir::BorrowKind;
use rustc_middle::span_bug;
Expand Down Expand Up @@ -342,7 +342,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
PatKind::Leaf { subpatterns, .. } => {
if let ty::Adt(adt_def, ..) = pat.ty.kind() {
for pat in subpatterns {
if adt_def.non_enum_variant().fields[pat.field].safety == Safety::Unsafe {
if adt_def.non_enum_variant().fields[pat.field].safety.is_unsafe() {
self.requires_unsafe(pat.pattern.span, UseOfUnsafeField);
}
}
Expand All @@ -367,7 +367,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
PatKind::Variant { adt_def, args: _, variant_index, subpatterns } => {
for pat in subpatterns {
let field = &pat.field;
if adt_def.variant(*variant_index).fields[*field].safety == Safety::Unsafe {
if adt_def.variant(*variant_index).fields[*field].safety.is_unsafe() {
self.requires_unsafe(pat.pattern.span, UseOfUnsafeField);
}
}
Expand Down Expand Up @@ -479,7 +479,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
return; // don't visit the whole expression
}
ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => {
if self.thir[fun].ty.fn_sig(self.tcx).safety() == hir::Safety::Unsafe {
if self.thir[fun].ty.fn_sig(self.tcx).safety().is_unsafe() {
let func_id = if let ty::FnDef(func_id, _) = self.thir[fun].ty.kind() {
Some(*func_id)
} else {
Expand Down Expand Up @@ -623,7 +623,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
ExprKind::Field { lhs, variant_index, name } => {
let lhs = &self.thir[lhs];
if let ty::Adt(adt_def, _) = lhs.ty.kind() {
if adt_def.variant(variant_index).fields[name].safety == Safety::Unsafe {
if adt_def.variant(variant_index).fields[name].safety.is_unsafe() {
self.requires_unsafe(expr.span, UseOfUnsafeField);
} else if adt_def.is_union() {
if let Some(assigned_ty) = self.assignment_info {
Expand Down Expand Up @@ -1112,11 +1112,7 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {

let hir_id = tcx.local_def_id_to_hir_id(def);
let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
if fn_sig.header.safety == hir::Safety::Unsafe {
SafetyContext::UnsafeFn
} else {
SafetyContext::Safe
}
if fn_sig.header.safety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe }
});
let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features;
let mut warnings = Vec::new();
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
attrs: &[Attribute],
) {
match target {
Target::Fn => {
Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
| Target::Fn => {
// `#[target_feature]` is not allowed in lang items.
if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
// Calling functions with `#[target_feature]` is
Expand All @@ -732,7 +733,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
});
}
}
Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {}
// FIXME: #[target_feature] was previously erroneously allowed on statements and some
// crates used this, so only emit a warning.
Target::Statement => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_symbol_mangling/src/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
let sig = sig_tys.with(hdr);
self.push("F");
self.in_binder(&sig, |cx, sig| {
if sig.safety == hir::Safety::Unsafe {
if sig.safety.is_unsafe() {
cx.push("U");
}
match sig.abi {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub fn type_allowed_to_implement_copy<'tcx>(
return Err(CopyImplementationError::HasDestructor);
}

if impl_safety == hir::Safety::Safe && self_type.has_unsafe_fields() {
if impl_safety.is_safe() && self_type.has_unsafe_fields() {
return Err(CopyImplementationError::HasUnsafeFields);
}

Expand Down
5 changes: 1 addition & 4 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1626,10 +1626,7 @@ pub(crate) trait PrintWithSpace {

impl PrintWithSpace for hir::Safety {
fn print_with_space(&self) -> &str {
match self {
hir::Safety::Unsafe => "unsafe ",
hir::Safety::Safe => "",
}
self.prefix_str()
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl

let unsafety_flag = match myitem.kind {
clean::FunctionItem(_) | clean::ForeignFunctionItem(..)
if myitem.fn_header(tcx).unwrap().safety == hir::Safety::Unsafe =>
if myitem.fn_header(tcx).unwrap().safety.is_unsafe() =>
{
"<sup title=\"unsafe function\">⚠</sup>"
}
Expand Down Expand Up @@ -1926,9 +1926,7 @@ fn item_static(
buffer,
"{vis}{safe}static {mutability}{name}: {typ}",
vis = visibility_print_with_space(it, cx),
safe = safety
.map(|safe| if safe == hir::Safety::Unsafe { "unsafe " } else { "" })
.unwrap_or(""),
safe = safety.map(|safe| safe.prefix_str()).unwrap_or(""),
mutability = s.mutability.print_with_space(),
name = it.name.unwrap(),
typ = s.type_.print(cx)
Expand Down
8 changes: 4 additions & 4 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ impl FromClean<clean::BareFunctionDecl> for FunctionPointer {
let clean::BareFunctionDecl { safety, generic_params, decl, abi } = bare_decl;
FunctionPointer {
header: FunctionHeader {
is_unsafe: matches!(safety, rustc_hir::Safety::Unsafe),
is_unsafe: safety.is_unsafe(),
is_const: false,
is_async: false,
abi: convert_abi(abi),
Expand Down Expand Up @@ -669,7 +669,7 @@ impl FromClean<clean::Trait> for Trait {
fn from_clean(trait_: clean::Trait, renderer: &JsonRenderer<'_>) -> Self {
let tcx = renderer.tcx;
let is_auto = trait_.is_auto(tcx);
let is_unsafe = trait_.safety(tcx) == rustc_hir::Safety::Unsafe;
let is_unsafe = trait_.safety(tcx).is_unsafe();
let is_dyn_compatible = trait_.is_dyn_compatible(tcx);
let clean::Trait { items, generics, bounds, .. } = trait_;
Trait {
Expand Down Expand Up @@ -711,7 +711,7 @@ impl FromClean<clean::Impl> for Impl {
ty::ImplPolarity::Negative => true,
};
Impl {
is_unsafe: safety == rustc_hir::Safety::Unsafe,
is_unsafe: safety.is_unsafe(),
generics: generics.into_json(renderer),
provided_trait_methods: provided_trait_methods
.into_iter()
Expand Down Expand Up @@ -840,7 +840,7 @@ fn convert_static(
Static {
type_: (*stat.type_).into_json(renderer),
is_mutable: stat.mutability == ast::Mutability::Mut,
is_unsafe: safety == rustc_hir::Safety::Unsafe,
is_unsafe: safety.is_unsafe(),
expr: stat
.expr
.map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e)))
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_utils/src/check_proc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {
TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1),
TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1),
TyKind::BareFn(bare_fn) => (
if bare_fn.safety == Safety::Unsafe {
if bare_fn.safety.is_unsafe() {
Pat::Str("unsafe")
} else if bare_fn.abi != Abi::Rust {
Pat::Str("extern")
Expand Down
4 changes: 2 additions & 2 deletions src/tools/clippy/clippy_utils/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{Expr, FnDecl, LangItem, Safety, TyKind};
use rustc_hir::{Expr, FnDecl, LangItem, TyKind};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::LateContext;
use rustc_middle::mir::ConstValue;
Expand Down Expand Up @@ -531,7 +531,7 @@ pub fn peel_mid_ty_refs_is_mutable(ty: Ty<'_>) -> (Ty<'_>, usize, Mutability) {
/// Returns `true` if the given type is an `unsafe` function.
pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
match ty.kind() {
ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety() == Safety::Unsafe,
ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety().is_unsafe(),
_ => false,
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/tools/clippy/clippy_utils/src/visitors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr};
use rustc_hir::{
AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath,
Safety, Stmt, UnOp, UnsafeSource, StructTailExpr,
Stmt, UnOp, UnsafeSource, StructTailExpr,
};
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter;
Expand Down Expand Up @@ -426,15 +426,15 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
.cx
.typeck_results()
.type_dependent_def_id(e.hir_id)
.is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe) =>
.is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe()) =>
{
ControlFlow::Break(())
},
ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() {
ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe => {
ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe() => {
ControlFlow::Break(())
},
ty::FnPtr(_, hdr) if hdr.safety == Safety::Unsafe => ControlFlow::Break(()),
ty::FnPtr(_, hdr) if hdr.safety.is_unsafe() => ControlFlow::Break(()),
_ => walk_expr(self, e),
},
ExprKind::Path(ref p)
Expand All @@ -458,7 +458,7 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
}
fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
if let ItemKind::Impl(i) = &self.cx.tcx.hir().item(id).kind
&& i.safety == Safety::Unsafe
&& i.safety.is_unsafe()
{
ControlFlow::Break(())
} else {
Expand Down
Loading