Add safe/unsafe to static inside extern blocks
This commit is contained in:
parent
b4cbdb7246
commit
bac72cf7cf
27 changed files with 152 additions and 57 deletions
|
@ -3164,6 +3164,7 @@ pub struct DelegationMac {
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub struct StaticItem {
|
pub struct StaticItem {
|
||||||
pub ty: P<Ty>,
|
pub ty: P<Ty>,
|
||||||
|
pub safety: Safety,
|
||||||
pub mutability: Mutability,
|
pub mutability: Mutability,
|
||||||
pub expr: Option<P<Expr>>,
|
pub expr: Option<P<Expr>>,
|
||||||
}
|
}
|
||||||
|
@ -3182,7 +3183,7 @@ impl From<StaticItem> for StaticForeignItem {
|
||||||
fn from(static_item: StaticItem) -> StaticForeignItem {
|
fn from(static_item: StaticItem) -> StaticForeignItem {
|
||||||
StaticForeignItem {
|
StaticForeignItem {
|
||||||
ty: static_item.ty,
|
ty: static_item.ty,
|
||||||
safety: Safety::Default,
|
safety: static_item.safety,
|
||||||
mutability: static_item.mutability,
|
mutability: static_item.mutability,
|
||||||
expr: static_item.expr,
|
expr: static_item.expr,
|
||||||
}
|
}
|
||||||
|
@ -3193,6 +3194,7 @@ impl From<StaticForeignItem> for StaticItem {
|
||||||
fn from(static_item: StaticForeignItem) -> StaticItem {
|
fn from(static_item: StaticForeignItem) -> StaticItem {
|
||||||
StaticItem {
|
StaticItem {
|
||||||
ty: static_item.ty,
|
ty: static_item.ty,
|
||||||
|
safety: static_item.safety,
|
||||||
mutability: static_item.mutability,
|
mutability: static_item.mutability,
|
||||||
expr: static_item.expr,
|
expr: static_item.expr,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1080,7 +1080,7 @@ impl NoopVisitItemKind for ItemKind {
|
||||||
match self {
|
match self {
|
||||||
ItemKind::ExternCrate(_orig_name) => {}
|
ItemKind::ExternCrate(_orig_name) => {}
|
||||||
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
|
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
|
||||||
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
|
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
|
||||||
vis.visit_ty(ty);
|
vis.visit_ty(ty);
|
||||||
visit_opt(expr, |expr| vis.visit_expr(expr));
|
visit_opt(expr, |expr| vis.visit_expr(expr));
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,7 +334,7 @@ impl WalkItemKind for ItemKind {
|
||||||
match self {
|
match self {
|
||||||
ItemKind::ExternCrate(_) => {}
|
ItemKind::ExternCrate(_) => {}
|
||||||
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)),
|
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, item.id, false)),
|
||||||
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
|
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
|
||||||
try_visit!(visitor.visit_ty(ty));
|
try_visit!(visitor.visit_ty(ty));
|
||||||
visit_opt!(visitor, visit_expr, expr);
|
visit_opt!(visitor, visit_expr, expr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|
|
||||||
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
|
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
|
||||||
}
|
}
|
||||||
ItemKind::Static(box ast::StaticItem { ty: t, mutability: m, expr: e }) => {
|
ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => {
|
||||||
let (ty, body_id) =
|
let (ty, body_id) =
|
||||||
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
|
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
|
||||||
hir::ItemKind::Static(ty, *m, body_id)
|
hir::ItemKind::Static(ty, *m, body_id)
|
||||||
|
|
|
@ -171,7 +171,8 @@ impl<'a> State<'a> {
|
||||||
self.print_use_tree(tree);
|
self.print_use_tree(tree);
|
||||||
self.word(";");
|
self.word(";");
|
||||||
}
|
}
|
||||||
ast::ItemKind::Static(box StaticItem { ty, mutability: mutbl, expr: body }) => {
|
ast::ItemKind::Static(box StaticItem { ty, safety, mutability: mutbl, expr: body }) => {
|
||||||
|
self.print_safety(*safety);
|
||||||
self.print_item_const(
|
self.print_item_const(
|
||||||
item.ident,
|
item.ident,
|
||||||
Some(*mutbl),
|
Some(*mutbl),
|
||||||
|
|
|
@ -102,7 +102,7 @@ fn intern_as_new_static<'tcx>(
|
||||||
let feed = tcx.create_def(
|
let feed = tcx.create_def(
|
||||||
static_id,
|
static_id,
|
||||||
sym::nested,
|
sym::nested,
|
||||||
DefKind::Static { mutability: alloc.0.mutability, nested: true },
|
DefKind::Static { safety: hir::Safety::Safe, mutability: alloc.0.mutability, nested: true },
|
||||||
);
|
);
|
||||||
tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());
|
tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());
|
||||||
|
|
||||||
|
|
|
@ -711,7 +711,9 @@ fn mutability<'tcx>(ecx: &InterpCx<'tcx, impl Machine<'tcx>>, alloc_id: AllocId)
|
||||||
// We're not using `try_global_alloc` since dangling pointers have already been handled.
|
// We're not using `try_global_alloc` since dangling pointers have already been handled.
|
||||||
match ecx.tcx.global_alloc(alloc_id) {
|
match ecx.tcx.global_alloc(alloc_id) {
|
||||||
GlobalAlloc::Static(did) => {
|
GlobalAlloc::Static(did) => {
|
||||||
let DefKind::Static { mutability, nested } = ecx.tcx.def_kind(did) else { bug!() };
|
let DefKind::Static { safety: _, mutability, nested } = ecx.tcx.def_kind(did) else {
|
||||||
|
bug!()
|
||||||
|
};
|
||||||
if nested {
|
if nested {
|
||||||
assert!(
|
assert!(
|
||||||
ecx.memory.alloc_map.get(alloc_id).is_none(),
|
ecx.memory.alloc_map.get(alloc_id).is_none(),
|
||||||
|
|
|
@ -631,7 +631,10 @@ impl<'a> ExtCtxt<'a> {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
AttrVec::new(),
|
AttrVec::new(),
|
||||||
ast::ItemKind::Static(ast::StaticItem { ty, mutability, expr: Some(expr) }.into()),
|
ast::ItemKind::Static(
|
||||||
|
ast::StaticItem { ty, safety: ast::Safety::Default, mutability, expr: Some(expr) }
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,8 @@ pub enum DefKind {
|
||||||
/// Constant generic parameter: `struct Foo<const N: usize> { ... }`
|
/// Constant generic parameter: `struct Foo<const N: usize> { ... }`
|
||||||
ConstParam,
|
ConstParam,
|
||||||
Static {
|
Static {
|
||||||
|
/// Whether it's a `unsafe static`, `safe static` (inside extern only) or just a `static`.
|
||||||
|
safety: hir::Safety,
|
||||||
/// Whether it's a `static mut` or just a `static`.
|
/// Whether it's a `static mut` or just a `static`.
|
||||||
mutability: ast::Mutability,
|
mutability: ast::Mutability,
|
||||||
/// Whether it's an anonymous static generated for nested allocations.
|
/// Whether it's an anonymous static generated for nested allocations.
|
||||||
|
|
|
@ -41,7 +41,8 @@ fn path_if_static_mut(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> Option<String> {
|
||||||
if let hir::ExprKind::Path(qpath) = expr.kind
|
if let hir::ExprKind::Path(qpath) = expr.kind
|
||||||
&& let hir::QPath::Resolved(_, path) = qpath
|
&& let hir::QPath::Resolved(_, path) = qpath
|
||||||
&& let hir::def::Res::Def(def_kind, _) = path.res
|
&& let hir::def::Res::Def(def_kind, _) = path.res
|
||||||
&& let hir::def::DefKind::Static { mutability: Mutability::Mut, nested: false } = def_kind
|
&& let hir::def::DefKind::Static { safety: _, mutability: Mutability::Mut, nested: false } =
|
||||||
|
def_kind
|
||||||
{
|
{
|
||||||
return Some(qpath_to_string(&tcx, &qpath));
|
return Some(qpath_to_string(&tcx, &qpath));
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,10 +156,14 @@ fixed_size_enum! {
|
||||||
( Impl { of_trait: false } )
|
( Impl { of_trait: false } )
|
||||||
( Impl { of_trait: true } )
|
( Impl { of_trait: true } )
|
||||||
( Closure )
|
( Closure )
|
||||||
( Static { mutability: ast::Mutability::Not, nested: false } )
|
( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: false } )
|
||||||
( Static { mutability: ast::Mutability::Mut, nested: false } )
|
( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: false } )
|
||||||
( Static { mutability: ast::Mutability::Not, nested: true } )
|
( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: false } )
|
||||||
( Static { mutability: ast::Mutability::Mut, nested: true } )
|
( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: false } )
|
||||||
|
( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Not, nested: true } )
|
||||||
|
( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Not, nested: true } )
|
||||||
|
( Static { safety: hir::Safety::Unsafe, mutability: ast::Mutability::Mut, nested: true } )
|
||||||
|
( Static { safety: hir::Safety::Safe, mutability: ast::Mutability::Mut, nested: true } )
|
||||||
( Ctor(CtorOf::Struct, CtorKind::Fn) )
|
( Ctor(CtorOf::Struct, CtorKind::Fn) )
|
||||||
( Ctor(CtorOf::Struct, CtorKind::Const) )
|
( Ctor(CtorOf::Struct, CtorKind::Const) )
|
||||||
( Ctor(CtorOf::Variant, CtorKind::Fn) )
|
( Ctor(CtorOf::Variant, CtorKind::Fn) )
|
||||||
|
|
|
@ -305,7 +305,9 @@ impl<'hir> Map<'hir> {
|
||||||
DefKind::InlineConst => BodyOwnerKind::Const { inline: true },
|
DefKind::InlineConst => BodyOwnerKind::Const { inline: true },
|
||||||
DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => BodyOwnerKind::Fn,
|
DefKind::Ctor(..) | DefKind::Fn | DefKind::AssocFn => BodyOwnerKind::Fn,
|
||||||
DefKind::Closure => BodyOwnerKind::Closure,
|
DefKind::Closure => BodyOwnerKind::Closure,
|
||||||
DefKind::Static { mutability, nested: false } => BodyOwnerKind::Static(mutability),
|
DefKind::Static { safety: _, mutability, nested: false } => {
|
||||||
|
BodyOwnerKind::Static(mutability)
|
||||||
|
}
|
||||||
dk => bug!("{:?} is not a body node: {:?}", def_id, dk),
|
dk => bug!("{:?} is not a body node: {:?}", def_id, dk),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -559,10 +559,10 @@ fn write_mir_sig(tcx: TyCtxt<'_>, body: &Body<'_>, w: &mut dyn io::Write) -> io:
|
||||||
match (kind, body.source.promoted) {
|
match (kind, body.source.promoted) {
|
||||||
(_, Some(_)) => write!(w, "const ")?, // promoteds are the closest to consts
|
(_, Some(_)) => write!(w, "const ")?, // promoteds are the closest to consts
|
||||||
(DefKind::Const | DefKind::AssocConst, _) => write!(w, "const ")?,
|
(DefKind::Const | DefKind::AssocConst, _) => write!(w, "const ")?,
|
||||||
(DefKind::Static { mutability: hir::Mutability::Not, nested: false }, _) => {
|
(DefKind::Static { safety: _, mutability: hir::Mutability::Not, nested: false }, _) => {
|
||||||
write!(w, "static ")?
|
write!(w, "static ")?
|
||||||
}
|
}
|
||||||
(DefKind::Static { mutability: hir::Mutability::Mut, nested: false }, _) => {
|
(DefKind::Static { safety: _, mutability: hir::Mutability::Mut, nested: false }, _) => {
|
||||||
write!(w, "static mut ")?
|
write!(w, "static mut ")?
|
||||||
}
|
}
|
||||||
(_, _) if is_function => write!(w, "fn ")?,
|
(_, _) if is_function => write!(w, "fn ")?,
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::build::ExprCategory;
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
|
|
||||||
use rustc_errors::DiagArgValue;
|
use rustc_errors::DiagArgValue;
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
|
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
|
||||||
use rustc_middle::mir::BorrowKind;
|
use rustc_middle::mir::BorrowKind;
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
|
@ -456,7 +457,10 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||||
if self.tcx.is_mutable_static(def_id) {
|
if self.tcx.is_mutable_static(def_id) {
|
||||||
self.requires_unsafe(expr.span, UseOfMutableStatic);
|
self.requires_unsafe(expr.span, UseOfMutableStatic);
|
||||||
} else if self.tcx.is_foreign_item(def_id) {
|
} else if self.tcx.is_foreign_item(def_id) {
|
||||||
self.requires_unsafe(expr.span, UseOfExternStatic);
|
match self.tcx.def_kind(def_id) {
|
||||||
|
DefKind::Static { safety: hir::Safety::Safe, .. } => {}
|
||||||
|
_ => self.requires_unsafe(expr.span, UseOfExternStatic),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if self.thir[arg].ty.is_unsafe_ptr() {
|
} else if self.thir[arg].ty.is_unsafe_ptr() {
|
||||||
self.requires_unsafe(expr.span, DerefOfRawPointer);
|
self.requires_unsafe(expr.span, DerefOfRawPointer);
|
||||||
|
|
|
@ -226,10 +226,11 @@ impl<'a> Parser<'a> {
|
||||||
self.expect_keyword(kw::Extern)?;
|
self.expect_keyword(kw::Extern)?;
|
||||||
self.parse_item_foreign_mod(attrs, safety)?
|
self.parse_item_foreign_mod(attrs, safety)?
|
||||||
} else if self.is_static_global() {
|
} else if self.is_static_global() {
|
||||||
|
let safety = self.parse_safety(Case::Sensitive);
|
||||||
// STATIC ITEM
|
// STATIC ITEM
|
||||||
self.bump(); // `static`
|
self.bump(); // `static`
|
||||||
let mutability = self.parse_mutability();
|
let mutability = self.parse_mutability();
|
||||||
let (ident, item) = self.parse_static_item(mutability)?;
|
let (ident, item) = self.parse_static_item(safety, mutability)?;
|
||||||
(ident, ItemKind::Static(Box::new(item)))
|
(ident, ItemKind::Static(Box::new(item)))
|
||||||
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
|
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
|
||||||
// CONST ITEM
|
// CONST ITEM
|
||||||
|
@ -952,7 +953,7 @@ impl<'a> Parser<'a> {
|
||||||
let kind = match AssocItemKind::try_from(kind) {
|
let kind = match AssocItemKind::try_from(kind) {
|
||||||
Ok(kind) => kind,
|
Ok(kind) => kind,
|
||||||
Err(kind) => match kind {
|
Err(kind) => match kind {
|
||||||
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
|
ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
|
||||||
self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
|
self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
|
||||||
AssocItemKind::Const(Box::new(ConstItem {
|
AssocItemKind::Const(Box::new(ConstItem {
|
||||||
defaultness: Defaultness::Final,
|
defaultness: Defaultness::Final,
|
||||||
|
@ -1259,7 +1260,10 @@ impl<'a> Parser<'a> {
|
||||||
matches!(token.kind, token::BinOp(token::Or) | token::OrOr)
|
matches!(token.kind, token::BinOp(token::Or) | token::OrOr)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
false
|
let quals: &[Symbol] = &[kw::Unsafe, kw::Safe];
|
||||||
|
// `$qual static`
|
||||||
|
quals.iter().any(|&kw| self.check_keyword(kw))
|
||||||
|
&& self.look_ahead(1, |t| t.is_keyword(kw::Static))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1320,7 +1324,11 @@ impl<'a> Parser<'a> {
|
||||||
/// ```ebnf
|
/// ```ebnf
|
||||||
/// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
|
/// Static = "static" "mut"? $ident ":" $ty (= $expr)? ";" ;
|
||||||
/// ```
|
/// ```
|
||||||
fn parse_static_item(&mut self, mutability: Mutability) -> PResult<'a, (Ident, StaticItem)> {
|
fn parse_static_item(
|
||||||
|
&mut self,
|
||||||
|
safety: Safety,
|
||||||
|
mutability: Mutability,
|
||||||
|
) -> PResult<'a, (Ident, StaticItem)> {
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
|
|
||||||
if self.token.kind == TokenKind::Lt && self.may_recover() {
|
if self.token.kind == TokenKind::Lt && self.may_recover() {
|
||||||
|
@ -1341,7 +1349,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
self.expect_semi()?;
|
self.expect_semi()?;
|
||||||
|
|
||||||
Ok((ident, StaticItem { ty, mutability, expr }))
|
Ok((ident, StaticItem { ty, safety, mutability, expr }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a constant item with the prefix `"const"` already parsed.
|
/// Parse a constant item with the prefix `"const"` already parsed.
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::{ImplTraitContext, Resolver};
|
||||||
use rustc_ast::visit::FnKind;
|
use rustc_ast::visit::FnKind;
|
||||||
use rustc_ast::*;
|
use rustc_ast::*;
|
||||||
use rustc_expand::expand::AstFragment;
|
use rustc_expand::expand::AstFragment;
|
||||||
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_span::hygiene::LocalExpnId;
|
use rustc_span::hygiene::LocalExpnId;
|
||||||
|
@ -128,7 +129,11 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
||||||
ItemKind::Union(..) => DefKind::Union,
|
ItemKind::Union(..) => DefKind::Union,
|
||||||
ItemKind::ExternCrate(..) => DefKind::ExternCrate,
|
ItemKind::ExternCrate(..) => DefKind::ExternCrate,
|
||||||
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
ItemKind::TyAlias(..) => DefKind::TyAlias,
|
||||||
ItemKind::Static(s) => DefKind::Static { mutability: s.mutability, nested: false },
|
ItemKind::Static(s) => DefKind::Static {
|
||||||
|
safety: hir::Safety::Safe,
|
||||||
|
mutability: s.mutability,
|
||||||
|
nested: false,
|
||||||
|
},
|
||||||
ItemKind::Const(..) => DefKind::Const,
|
ItemKind::Const(..) => DefKind::Const,
|
||||||
ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn,
|
ItemKind::Fn(..) | ItemKind::Delegation(..) => DefKind::Fn,
|
||||||
ItemKind::MacroDef(..) => {
|
ItemKind::MacroDef(..) => {
|
||||||
|
@ -215,8 +220,15 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
|
||||||
ty: _,
|
ty: _,
|
||||||
mutability,
|
mutability,
|
||||||
expr: _,
|
expr: _,
|
||||||
safety: _,
|
safety,
|
||||||
}) => DefKind::Static { mutability, nested: false },
|
}) => {
|
||||||
|
let safety = match safety {
|
||||||
|
ast::Safety::Unsafe(_) | ast::Safety::Default => hir::Safety::Unsafe,
|
||||||
|
ast::Safety::Safe(_) => hir::Safety::Safe,
|
||||||
|
};
|
||||||
|
|
||||||
|
DefKind::Static { safety, mutability, nested: false }
|
||||||
|
}
|
||||||
ForeignItemKind::Fn(_) => DefKind::Fn,
|
ForeignItemKind::Fn(_) => DefKind::Fn,
|
||||||
ForeignItemKind::TyAlias(_) => DefKind::ForeignTy,
|
ForeignItemKind::TyAlias(_) => DefKind::ForeignTy,
|
||||||
ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id),
|
ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id),
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_errors::{Applicability, Diag, DiagMessage};
|
||||||
use rustc_hir::def::Namespace::*;
|
use rustc_hir::def::Namespace::*;
|
||||||
use rustc_hir::def::{DefKind, Namespace, PerNS};
|
use rustc_hir::def::{DefKind, Namespace, PerNS};
|
||||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
|
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
|
||||||
use rustc_hir::Mutability;
|
use rustc_hir::{Mutability, Safety};
|
||||||
use rustc_middle::ty::{Ty, TyCtxt};
|
use rustc_middle::ty::{Ty, TyCtxt};
|
||||||
use rustc_middle::{bug, span_bug, ty};
|
use rustc_middle::{bug, span_bug, ty};
|
||||||
use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution};
|
use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution};
|
||||||
|
@ -1517,7 +1517,11 @@ impl Disambiguator {
|
||||||
"union" => Kind(DefKind::Union),
|
"union" => Kind(DefKind::Union),
|
||||||
"module" | "mod" => Kind(DefKind::Mod),
|
"module" | "mod" => Kind(DefKind::Mod),
|
||||||
"const" | "constant" => Kind(DefKind::Const),
|
"const" | "constant" => Kind(DefKind::Const),
|
||||||
"static" => Kind(DefKind::Static { mutability: Mutability::Not, nested: false }),
|
"static" => Kind(DefKind::Static {
|
||||||
|
mutability: Mutability::Not,
|
||||||
|
nested: false,
|
||||||
|
safety: Safety::Safe,
|
||||||
|
}),
|
||||||
"function" | "fn" | "method" => Kind(DefKind::Fn),
|
"function" | "fn" | "method" => Kind(DefKind::Fn),
|
||||||
"derive" => Kind(DefKind::Macro(MacroKind::Derive)),
|
"derive" => Kind(DefKind::Macro(MacroKind::Derive)),
|
||||||
"type" => NS(Namespace::TypeNS),
|
"type" => NS(Namespace::TypeNS),
|
||||||
|
|
|
@ -308,13 +308,15 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
||||||
ty: lt,
|
ty: lt,
|
||||||
mutability: lm,
|
mutability: lm,
|
||||||
expr: le,
|
expr: le,
|
||||||
|
safety: ls,
|
||||||
}),
|
}),
|
||||||
Static(box StaticItem {
|
Static(box StaticItem {
|
||||||
ty: rt,
|
ty: rt,
|
||||||
mutability: rm,
|
mutability: rm,
|
||||||
expr: re,
|
expr: re,
|
||||||
|
safety: rs,
|
||||||
}),
|
}),
|
||||||
) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
|
) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le, re),
|
||||||
(
|
(
|
||||||
Const(box ConstItem {
|
Const(box ConstItem {
|
||||||
defaultness: ld,
|
defaultness: ld,
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
|
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/extern-items-unsafe.rs:11:5
|
--> $DIR/extern-items-unsafe.rs:12:5
|
||||||
|
|
|
|
||||||
LL | test1(i);
|
LL | test1(TEST1);
|
||||||
| ^^^^^^^^ call to unsafe function
|
| ^^^^^^^^^^^^ call to unsafe function
|
||||||
|
|
|
|
||||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0133]: use of extern static is unsafe and requires unsafe function or block
|
||||||
|
--> $DIR/extern-items-unsafe.rs:12:11
|
||||||
|
|
|
||||||
|
LL | test1(TEST1);
|
||||||
|
| ^^^^^ use of extern static
|
||||||
|
|
|
||||||
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0133`.
|
For more information about this error, try `rustc --explain E0133`.
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
|
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
|
||||||
--> $DIR/extern-items-unsafe.rs:11:5
|
--> $DIR/extern-items-unsafe.rs:12:5
|
||||||
|
|
|
|
||||||
LL | test1(i);
|
LL | test1(TEST1);
|
||||||
| ^^^^^^^^ call to unsafe function
|
| ^^^^^^^^^^^^ call to unsafe function
|
||||||
|
|
|
|
||||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0133]: use of extern static is unsafe and requires unsafe block
|
||||||
|
--> $DIR/extern-items-unsafe.rs:12:11
|
||||||
|
|
|
||||||
|
LL | test1(TEST1);
|
||||||
|
| ^^^^^ use of extern static
|
||||||
|
|
|
||||||
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0133`.
|
For more information about this error, try `rustc --explain E0133`.
|
||||||
|
|
|
@ -4,17 +4,19 @@
|
||||||
//@[edition2024] compile-flags: -Zunstable-options
|
//@[edition2024] compile-flags: -Zunstable-options
|
||||||
|
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
|
static TEST1: i32;
|
||||||
fn test1(i: i32);
|
fn test1(i: i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test2(i: i32) {
|
fn test2() {
|
||||||
test1(i);
|
test1(TEST1);
|
||||||
//~^ ERROR: call to unsafe function `test1` is unsafe
|
//~^ ERROR: call to unsafe function `test1` is unsafe
|
||||||
|
//~| ERROR: use of extern static is unsafe
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test3(i: i32) {
|
fn test3() {
|
||||||
unsafe {
|
unsafe {
|
||||||
test1(i);
|
test1(TEST1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
|
safe static TEST1: i32;
|
||||||
safe fn test1(i: i32);
|
safe fn test1(i: i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test2(i: i32) {
|
fn test2() {
|
||||||
test1(i);
|
test1(TEST1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
safe static TEST1: i32;
|
||||||
|
//~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
|
||||||
safe fn test1(i: i32);
|
safe fn test1(i: i32);
|
||||||
//~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
|
//~^ ERROR items in unadorned `extern` blocks cannot have safety qualifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test2(i: i32) {
|
fn test2() {
|
||||||
test1(i);
|
test1(TEST1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -3,8 +3,17 @@ error: items in unadorned `extern` blocks cannot have safety qualifiers
|
||||||
|
|
|
|
||||||
LL | extern "C" {
|
LL | extern "C" {
|
||||||
| ---------- help: add unsafe to this `extern` block
|
| ---------- help: add unsafe to this `extern` block
|
||||||
|
LL | safe static TEST1: i32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: items in unadorned `extern` blocks cannot have safety qualifiers
|
||||||
|
--> $DIR/safe-unsafe-on-unadorned-extern-block.rs:4:5
|
||||||
|
|
|
||||||
|
LL | extern "C" {
|
||||||
|
| ---------- help: add unsafe to this `extern` block
|
||||||
|
...
|
||||||
LL | safe fn test1(i: i32);
|
LL | safe fn test1(i: i32);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
|
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/unsafe-items.rs:17:5
|
--> $DIR/unsafe-items.rs:18:5
|
||||||
|
|
|
|
||||||
LL | test1(i);
|
LL | test1(TEST1);
|
||||||
| ^^^^^^^^ call to unsafe function
|
| ^^^^^^^^^^^^ call to unsafe function
|
||||||
|
|
|
|
||||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0133]: use of extern static is unsafe and requires unsafe function or block
|
||||||
|
--> $DIR/unsafe-items.rs:18:11
|
||||||
|
|
|
||||||
|
LL | test1(TEST1);
|
||||||
|
| ^^^^^ use of extern static
|
||||||
|
|
|
||||||
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0133`.
|
For more information about this error, try `rustc --explain E0133`.
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
|
error[E0133]: call to unsafe function `test1` is unsafe and requires unsafe block
|
||||||
--> $DIR/unsafe-items.rs:17:5
|
--> $DIR/unsafe-items.rs:18:5
|
||||||
|
|
|
|
||||||
LL | test1(i);
|
LL | test1(TEST1);
|
||||||
| ^^^^^^^^ call to unsafe function
|
| ^^^^^^^^^^^^ call to unsafe function
|
||||||
|
|
|
|
||||||
= note: consult the function's documentation for information on how to avoid undefined behavior
|
= note: consult the function's documentation for information on how to avoid undefined behavior
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error[E0133]: use of extern static is unsafe and requires unsafe block
|
||||||
|
--> $DIR/unsafe-items.rs:18:11
|
||||||
|
|
|
||||||
|
LL | test1(TEST1);
|
||||||
|
| ^^^^^ use of extern static
|
||||||
|
|
|
||||||
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0133`.
|
For more information about this error, try `rustc --explain E0133`.
|
||||||
|
|
|
@ -4,18 +4,20 @@
|
||||||
//@[edition2024] compile-flags: -Zunstable-options
|
//@[edition2024] compile-flags: -Zunstable-options
|
||||||
|
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
|
unsafe static TEST1: i32;
|
||||||
unsafe fn test1(i: i32);
|
unsafe fn test1(i: i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test2(i: i32) {
|
fn test2() {
|
||||||
unsafe {
|
unsafe {
|
||||||
test1(i);
|
test1(TEST1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test3(i: i32) {
|
fn test3() {
|
||||||
test1(i);
|
test1(TEST1);
|
||||||
//~^ ERROR: call to unsafe function `test1` is unsafe
|
//~^ ERROR: call to unsafe function `test1` is unsafe
|
||||||
|
//~| ERROR: use of extern static is unsafe
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue