Auto merge of #115126 - Dylan-DPC:rollup-g6w3qjd, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - #114930 (Automatically add OS labels to std PRs) - #115053 (docs: Add example, reference link for `type` keyword.) - #115092 (Add generics_of to smir) - #115096 (Add regression test for not `memcpy`ing padding bytes) - #115100 (Add support for `ptr::write`s for the `invalid_reference_casting` lint) - #115114 (Contents of reachable statics is reachable) - #115122 (Fix clippy lint for identical `if`/`else` contraining `?` expressions) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
810573919f
@ -56,20 +56,7 @@ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx rustc_hir::Stmt<'tc
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
// &mut <expr>
|
||||
let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
|
||||
expr
|
||||
// <expr> = ...
|
||||
} else if let ExprKind::Assign(expr, _, _) = expr.kind {
|
||||
expr
|
||||
// <expr> += ...
|
||||
} else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
|
||||
expr
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let ExprKind::Unary(UnOp::Deref, e) = &inner.kind else {
|
||||
let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else {
|
||||
return;
|
||||
};
|
||||
|
||||
@ -86,15 +73,58 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
cx.emit_spanned_lint(
|
||||
INVALID_REFERENCE_CASTING,
|
||||
expr.span,
|
||||
if matches!(expr.kind, ExprKind::AddrOf(..)) {
|
||||
InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
|
||||
} else {
|
||||
if is_assignment {
|
||||
InvalidReferenceCastingDiag::AssignToRef { orig_cast }
|
||||
} else {
|
||||
InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn is_operation_we_care_about<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
e: &'tcx Expr<'tcx>,
|
||||
) -> Option<(bool, &'tcx Expr<'tcx>)> {
|
||||
fn deref_assign_or_addr_of<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(bool, &'tcx Expr<'tcx>)> {
|
||||
// &mut <expr>
|
||||
let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
|
||||
expr
|
||||
// <expr> = ...
|
||||
} else if let ExprKind::Assign(expr, _, _) = expr.kind {
|
||||
expr
|
||||
// <expr> += ...
|
||||
} else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
|
||||
expr
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if let ExprKind::Unary(UnOp::Deref, e) = &inner.kind {
|
||||
Some((!matches!(expr.kind, ExprKind::AddrOf(..)), e))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn ptr_write<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
e: &'tcx Expr<'tcx>,
|
||||
) -> Option<(bool, &'tcx Expr<'tcx>)> {
|
||||
if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind
|
||||
&& let ExprKind::Path(ref qpath) = path.kind
|
||||
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
|
||||
&& matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned))
|
||||
{
|
||||
Some((true, arg_ptr))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e))
|
||||
}
|
||||
|
||||
fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
|
||||
let e = e.peel_blocks();
|
||||
|
||||
|
@ -98,15 +98,11 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
self.worklist.push(def_id);
|
||||
} else {
|
||||
match res {
|
||||
// If this path leads to a constant, then we need to
|
||||
// recurse into the constant to continue finding
|
||||
// items that are reachable.
|
||||
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
|
||||
// Reachable constants and reachable statics can have their contents inlined
|
||||
// into other crates. Mark them as reachable and recurse into their body.
|
||||
Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::Static(_), _) => {
|
||||
self.worklist.push(def_id);
|
||||
}
|
||||
|
||||
// If this wasn't a static, then the destination is
|
||||
// surely reachable.
|
||||
_ => {
|
||||
self.reachable_symbols.insert(def_id);
|
||||
}
|
||||
|
@ -80,6 +80,10 @@ pub fn impl_trait_def_id(&self, impl_def: &stable_mir::ty::ImplDef) -> DefId {
|
||||
self.def_ids[impl_def.0]
|
||||
}
|
||||
|
||||
pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId {
|
||||
self.def_ids[generic_def.0]
|
||||
}
|
||||
|
||||
pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
|
||||
stable_mir::CrateItem(self.create_def_id(did))
|
||||
}
|
||||
@ -120,6 +124,10 @@ pub fn trait_def(&mut self, did: DefId) -> stable_mir::ty::TraitDef {
|
||||
stable_mir::ty::TraitDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef {
|
||||
stable_mir::ty::GenericDef(self.create_def_id(did))
|
||||
}
|
||||
|
||||
pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
|
||||
stable_mir::ty::ConstDef(self.create_def_id(did))
|
||||
}
|
||||
|
@ -10,7 +10,8 @@
|
||||
use crate::rustc_internal::{self, opaque};
|
||||
use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
|
||||
use crate::stable_mir::ty::{
|
||||
allocation_filter, new_allocation, Const, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy,
|
||||
allocation_filter, new_allocation, Const, FloatTy, GenericDef, GenericParamDef, IntTy,
|
||||
Movability, RigidTy, TyKind, UintTy,
|
||||
};
|
||||
use crate::stable_mir::{self, Context};
|
||||
use rustc_hir as hir;
|
||||
@ -101,6 +102,12 @@ fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind {
|
||||
let ty = self.types[ty.0];
|
||||
ty.stable(self)
|
||||
}
|
||||
|
||||
fn generics_of(&mut self, generic_def: &GenericDef) -> stable_mir::ty::Generics {
|
||||
let def_id = self.generic_def_id(generic_def);
|
||||
let generic_def = self.tcx.generics_of(def_id);
|
||||
generic_def.stable(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Tables<'tcx> {
|
||||
@ -1205,3 +1212,67 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for ty::Generics {
|
||||
type T = stable_mir::ty::Generics;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
use stable_mir::ty::Generics;
|
||||
|
||||
let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect();
|
||||
let param_def_id_to_index =
|
||||
params.iter().map(|param| (param.def_id, param.index)).collect();
|
||||
|
||||
Generics {
|
||||
parent: self.parent.map(|did| tables.generic_def(did)),
|
||||
parent_count: self.parent_count,
|
||||
params,
|
||||
param_def_id_to_index,
|
||||
has_self: self.has_self,
|
||||
has_late_bound_regions: self
|
||||
.has_late_bound_regions
|
||||
.as_ref()
|
||||
.map(|late_bound_regions| late_bound_regions.stable(tables)),
|
||||
host_effect_index: self.host_effect_index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_span::Span {
|
||||
type T = stable_mir::ty::Span;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
|
||||
opaque(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
|
||||
type T = stable_mir::ty::GenericParamDefKind;
|
||||
|
||||
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
|
||||
use stable_mir::ty::GenericParamDefKind;
|
||||
match self {
|
||||
ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
|
||||
ty::GenericParamDefKind::Type { has_default, synthetic } => {
|
||||
GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic }
|
||||
}
|
||||
ty::GenericParamDefKind::Const { has_default } => {
|
||||
GenericParamDefKind::Const { has_default: *has_default }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
|
||||
type T = stable_mir::ty::GenericParamDef;
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
|
||||
GenericParamDef {
|
||||
name: self.name.to_string(),
|
||||
def_id: tables.generic_def(self.def_id),
|
||||
index: self.index,
|
||||
pure_wrt_drop: self.pure_wrt_drop,
|
||||
kind: self.kind.stable(tables),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
use crate::rustc_smir::Tables;
|
||||
|
||||
use self::ty::{ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
|
||||
use self::ty::{GenericDef, Generics, ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
|
||||
|
||||
pub mod mir;
|
||||
pub mod ty;
|
||||
@ -110,6 +110,7 @@ pub trait Context {
|
||||
fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
|
||||
fn all_trait_impls(&mut self) -> ImplTraitDecls;
|
||||
fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
|
||||
fn generics_of(&mut self, generic_def: &GenericDef) -> Generics;
|
||||
/// Get information about the local crate.
|
||||
fn local_crate(&self) -> Crate;
|
||||
/// Retrieve a list of all external crates.
|
||||
|
@ -22,7 +22,7 @@ pub struct Const {
|
||||
|
||||
type Ident = Opaque;
|
||||
pub(crate) type Region = Opaque;
|
||||
type Span = Opaque;
|
||||
pub type Span = Opaque;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TyKind {
|
||||
@ -87,34 +87,37 @@ pub enum Movability {
|
||||
Movable,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct ForeignDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct FnDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct ClosureDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct GeneratorDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct ParamDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct BrNamedDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct AdtDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct AliasDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct TraitDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct GenericDef(pub(crate) DefId);
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub struct ConstDef(pub(crate) DefId);
|
||||
|
||||
impl TraitDef {
|
||||
@ -132,6 +135,12 @@ pub fn trait_impl(&self) -> ImplTrait {
|
||||
}
|
||||
}
|
||||
|
||||
impl GenericDef {
|
||||
pub fn generics_of(&self) -> Generics {
|
||||
with(|tcx| tcx.generics_of(self))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GenericArgs(pub Vec<GenericArgKind>);
|
||||
|
||||
@ -461,3 +470,30 @@ pub struct TraitRef {
|
||||
pub def_id: TraitDef,
|
||||
pub args: GenericArgs,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Generics {
|
||||
pub parent: Option<GenericDef>,
|
||||
pub parent_count: usize,
|
||||
pub params: Vec<GenericParamDef>,
|
||||
pub param_def_id_to_index: Vec<(GenericDef, u32)>,
|
||||
pub has_self: bool,
|
||||
pub has_late_bound_regions: Option<Span>,
|
||||
pub host_effect_index: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum GenericParamDefKind {
|
||||
Lifetime,
|
||||
Type { has_default: bool, synthetic: bool },
|
||||
Const { has_default: bool },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GenericParamDef {
|
||||
pub name: super::Symbol,
|
||||
pub def_id: GenericDef,
|
||||
pub index: u32,
|
||||
pub pure_wrt_drop: bool,
|
||||
pub kind: GenericParamDefKind,
|
||||
}
|
||||
|
@ -1179,6 +1179,9 @@
|
||||
ptr_offset_from,
|
||||
ptr_offset_from_unsigned,
|
||||
ptr_unique,
|
||||
ptr_write,
|
||||
ptr_write_unaligned,
|
||||
ptr_write_volatile,
|
||||
pub_macro_rules,
|
||||
pub_restricted,
|
||||
public,
|
||||
|
@ -1357,6 +1357,7 @@ macro_rules! attempt_swap_as_chunks {
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
||||
#[rustc_diagnostic_item = "ptr_write"]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn write<T>(dst: *mut T, src: T) {
|
||||
// Semantically, it would be fine for this to be implemented as a
|
||||
@ -1459,6 +1460,7 @@ macro_rules! attempt_swap_as_chunks {
|
||||
#[inline]
|
||||
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
|
||||
#[rustc_diagnostic_item = "ptr_write_unaligned"]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
||||
// SAFETY: the caller must guarantee that `dst` is valid for writes.
|
||||
@ -1607,6 +1609,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "volatile", since = "1.9.0")]
|
||||
#[rustc_diagnostic_item = "ptr_write_volatile"]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
|
||||
// SAFETY: the caller must uphold the safety contract for `volatile_store`.
|
||||
|
@ -1820,7 +1820,7 @@ mod true_keyword {}
|
||||
|
||||
#[doc(keyword = "type")]
|
||||
//
|
||||
/// Define an alias for an existing type.
|
||||
/// Define an [alias] for an existing type.
|
||||
///
|
||||
/// The syntax is `type Name = ExistingType;`.
|
||||
///
|
||||
@ -1838,6 +1838,13 @@ mod true_keyword {}
|
||||
/// assert_eq!(m, k);
|
||||
/// ```
|
||||
///
|
||||
/// A type can be generic:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use std::sync::{Arc, Mutex};
|
||||
/// type ArcMutex<T> = Arc<Mutex<T>>;
|
||||
/// ```
|
||||
///
|
||||
/// In traits, `type` is used to declare an [associated type]:
|
||||
///
|
||||
/// ```rust
|
||||
@ -1860,6 +1867,7 @@ mod true_keyword {}
|
||||
///
|
||||
/// [`trait`]: keyword.trait.html
|
||||
/// [associated type]: ../reference/items/associated-items.html#associated-types
|
||||
/// [alias]: ../reference/items/type-aliases.html
|
||||
mod type_keyword {}
|
||||
|
||||
#[doc(keyword = "unsafe")]
|
||||
|
@ -10,6 +10,7 @@
|
||||
GenericArgs, Guard, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
|
||||
PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
|
||||
};
|
||||
use rustc_hir::MatchSource::TryDesugar;
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::TypeckResults;
|
||||
@ -311,7 +312,7 @@ pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {
|
||||
lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
|
||||
},
|
||||
(&ExprKind::Match(le, la, ref ls), &ExprKind::Match(re, ra, ref rs)) => {
|
||||
ls == rs
|
||||
(ls == rs || (matches!((ls, rs), (TryDesugar(_), TryDesugar(_)))))
|
||||
&& self.eq_expr(le, re)
|
||||
&& over(la, ra, |l, r| {
|
||||
self.eq_pat(l.pat, r.pat)
|
||||
|
@ -98,7 +98,7 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
|
||||
};
|
||||
|
||||
if true {
|
||||
// FIXME: should emit "this `if` has identical blocks"
|
||||
//~^ ERROR: this `if` has identical blocks
|
||||
Ok("foo")?;
|
||||
} else {
|
||||
Ok("foo")?;
|
||||
|
@ -82,6 +82,25 @@ LL | | f32::NAN
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
||||
error: this `if` has identical blocks
|
||||
--> $DIR/if_same_then_else2.rs:100:13
|
||||
|
|
||||
LL | if true {
|
||||
| _____________^
|
||||
LL | |
|
||||
LL | | Ok("foo")?;
|
||||
LL | | } else {
|
||||
| |_____^
|
||||
|
|
||||
note: same as this
|
||||
--> $DIR/if_same_then_else2.rs:103:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
LL | | Ok("foo")?;
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
||||
error: this `if` has identical blocks
|
||||
--> $DIR/if_same_then_else2.rs:124:20
|
||||
|
|
||||
@ -103,5 +122,5 @@ LL | | return Ok(&foo[0..]);
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -25,6 +25,20 @@ pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
|
||||
Box::new(MaybeUninit::uninit())
|
||||
}
|
||||
|
||||
#[repr(align(1024))]
|
||||
pub struct LotsaPadding(usize);
|
||||
|
||||
// Boxing a value with padding should not copy junk from the stack
|
||||
#[no_mangle]
|
||||
pub fn box_lotsa_padding() -> Box<LotsaPadding> {
|
||||
// CHECK-LABEL: @box_lotsa_padding
|
||||
// CHECK-NOT: alloca
|
||||
// CHECK-NOT: getelementptr
|
||||
// CHECK-NOT: memcpy
|
||||
// CHECK-NOT: memset
|
||||
Box::new(LotsaPadding(42))
|
||||
}
|
||||
|
||||
// Hide the `allocalign` attribute in the declaration of __rust_alloc
|
||||
// from the CHECK-NOT above, and also verify the attributes got set reasonably.
|
||||
// CHECK: declare {{(dso_local )?}}noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
|
@ -1,10 +1,14 @@
|
||||
pub static V: &u32 = &X;
|
||||
pub static F: fn() = f;
|
||||
pub static G: fn() = G0;
|
||||
|
||||
static X: u32 = 42;
|
||||
static G0: fn() = g;
|
||||
|
||||
pub fn v() -> *const u32 {
|
||||
V
|
||||
}
|
||||
|
||||
fn f() {}
|
||||
|
||||
fn g() {}
|
||||
|
@ -1,9 +1,11 @@
|
||||
// Regression test for #84455 and #115052.
|
||||
// run-pass
|
||||
// aux-build:static_init_aux.rs
|
||||
extern crate static_init_aux as aux;
|
||||
|
||||
static V: &u32 = aux::V;
|
||||
static F: fn() = aux::F;
|
||||
static G: fn() = aux::G;
|
||||
|
||||
fn v() -> *const u32 {
|
||||
V
|
||||
@ -12,4 +14,5 @@ fn v() -> *const u32 {
|
||||
fn main() {
|
||||
assert_eq!(aux::v(), crate::v());
|
||||
F();
|
||||
G();
|
||||
}
|
||||
|
@ -71,6 +71,11 @@ unsafe fn assign_to_ref() {
|
||||
//~^ ERROR assigning to `&T` is undefined behavior
|
||||
*std::mem::transmute::<_, *mut i32>(num) += 1;
|
||||
//~^ ERROR assigning to `&T` is undefined behavior
|
||||
std::ptr::write(
|
||||
//~^ ERROR assigning to `&T` is undefined behavior
|
||||
std::mem::transmute::<*const i32, *mut i32>(num),
|
||||
-1i32,
|
||||
);
|
||||
|
||||
let value = num as *const i32 as *mut i32;
|
||||
*value = 1;
|
||||
@ -79,6 +84,12 @@ unsafe fn assign_to_ref() {
|
||||
//~^ ERROR assigning to `&T` is undefined behavior
|
||||
*(num as *const _ as usize as *mut i32) = 2;
|
||||
//~^ ERROR assigning to `&T` is undefined behavior
|
||||
std::ptr::write(value, 2);
|
||||
//~^ ERROR assigning to `&T` is undefined behavior
|
||||
std::ptr::write_unaligned(value, 2);
|
||||
//~^ ERROR assigning to `&T` is undefined behavior
|
||||
std::ptr::write_volatile(value, 2);
|
||||
//~^ ERROR assigning to `&T` is undefined behavior
|
||||
|
||||
unsafe fn generic_assign_to_ref<T>(this: &T, a: T) {
|
||||
*(this as *const _ as *mut _) = a;
|
||||
|
@ -131,7 +131,17 @@ LL | *std::mem::transmute::<_, *mut i32>(num) += 1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
|
||||
--> $DIR/reference_casting.rs:76:5
|
||||
--> $DIR/reference_casting.rs:74:5
|
||||
|
|
||||
LL | / std::ptr::write(
|
||||
LL | |
|
||||
LL | | std::mem::transmute::<*const i32, *mut i32>(num),
|
||||
LL | | -1i32,
|
||||
LL | | );
|
||||
| |_____^
|
||||
|
||||
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
|
||||
--> $DIR/reference_casting.rs:81:5
|
||||
|
|
||||
LL | let value = num as *const i32 as *mut i32;
|
||||
| ----------------------------- casting happend here
|
||||
@ -139,22 +149,49 @@ LL | *value = 1;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
|
||||
--> $DIR/reference_casting.rs:78:5
|
||||
--> $DIR/reference_casting.rs:83:5
|
||||
|
|
||||
LL | *(num as *const i32).cast::<i32>().cast_mut() = 2;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
|
||||
--> $DIR/reference_casting.rs:80:5
|
||||
--> $DIR/reference_casting.rs:85:5
|
||||
|
|
||||
LL | *(num as *const _ as usize as *mut i32) = 2;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
|
||||
--> $DIR/reference_casting.rs:84:9
|
||||
--> $DIR/reference_casting.rs:87:5
|
||||
|
|
||||
LL | let value = num as *const i32 as *mut i32;
|
||||
| ----------------------------- casting happend here
|
||||
...
|
||||
LL | std::ptr::write(value, 2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
|
||||
--> $DIR/reference_casting.rs:89:5
|
||||
|
|
||||
LL | let value = num as *const i32 as *mut i32;
|
||||
| ----------------------------- casting happend here
|
||||
...
|
||||
LL | std::ptr::write_unaligned(value, 2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
|
||||
--> $DIR/reference_casting.rs:91:5
|
||||
|
|
||||
LL | let value = num as *const i32 as *mut i32;
|
||||
| ----------------------------- casting happend here
|
||||
...
|
||||
LL | std::ptr::write_volatile(value, 2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
|
||||
--> $DIR/reference_casting.rs:95:9
|
||||
|
|
||||
LL | *(this as *const _ as *mut _) = a;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 25 previous errors
|
||||
error: aborting due to 29 previous errors
|
||||
|
||||
|
@ -177,6 +177,98 @@ exclude_labels = [
|
||||
"T-*",
|
||||
]
|
||||
|
||||
[autolabel."O-android"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/android"
|
||||
]
|
||||
|
||||
[autolabel."O-fuchsia"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/fuchsia"
|
||||
]
|
||||
|
||||
[autolabel."O-hermit"]
|
||||
trigger_files = [
|
||||
"library/std/src/sys/hermit",
|
||||
"library/std/src/os/hermit"
|
||||
]
|
||||
|
||||
[autolabel."O-ios"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/ios"
|
||||
]
|
||||
|
||||
[autolabel."O-itron"]
|
||||
trigger_files = [
|
||||
"library/std/src/sys/itron"
|
||||
]
|
||||
|
||||
[autolabel."O-linux"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/linux"
|
||||
]
|
||||
|
||||
[autolabel."O-macos"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/macos"
|
||||
]
|
||||
|
||||
[autolabel."O-netbsd"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/netbsd"
|
||||
]
|
||||
|
||||
[autolabel."O-redox"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/redox"
|
||||
]
|
||||
|
||||
[autolabel."O-SGX"]
|
||||
trigger_files = [
|
||||
"library/std/src/sys/sgx",
|
||||
"library/std/src/os/fortanix_sgx"
|
||||
]
|
||||
|
||||
[autolabel."O-solaris"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/solaris"
|
||||
]
|
||||
|
||||
[autolabel."O-solid"]
|
||||
trigger_files = [
|
||||
"library/std/src/sys/solid",
|
||||
"library/std/src/os/solid"
|
||||
]
|
||||
|
||||
[autolabel."O-unix"]
|
||||
trigger_files = [
|
||||
"library/std/src/sys/unix",
|
||||
"library/std/src/os/unix"
|
||||
]
|
||||
|
||||
[autolabel."O-wasi"]
|
||||
trigger_files = [
|
||||
"library/std/src/sys/wasi",
|
||||
"library/std/src/os/wasi"
|
||||
]
|
||||
|
||||
[autolabel."O-wasm"]
|
||||
trigger_files = [
|
||||
"library/std/src/sys/wasm",
|
||||
"library/std/src/os/wasm"
|
||||
]
|
||||
|
||||
[autolabel."O-watchos"]
|
||||
trigger_files = [
|
||||
"library/std/src/os/watchos"
|
||||
]
|
||||
|
||||
[autolabel."O-windows"]
|
||||
trigger_files = [
|
||||
"library/std/src/sys/windows",
|
||||
"library/std/src/os/windows"
|
||||
]
|
||||
|
||||
[autolabel."T-bootstrap"]
|
||||
trigger_files = [
|
||||
"x.py",
|
||||
|
Loading…
Reference in New Issue
Block a user