Skip to content

Commit

Permalink
Auto merge of rust-lang#115126 - Dylan-DPC:rollup-g6w3qjd, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - rust-lang#114930 (Automatically add OS labels to std PRs)
 - rust-lang#115053 (docs: Add example, reference link for `type` keyword.)
 - rust-lang#115092 (Add generics_of to smir)
 - rust-lang#115096 (Add regression test for not `memcpy`ing padding bytes)
 - rust-lang#115100 (Add support for `ptr::write`s for the `invalid_reference_casting` lint)
 - rust-lang#115114 (Contents of reachable statics is reachable)
 - rust-lang#115122 (Fix clippy lint for identical `if`/`else` contraining `?` expressions)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Aug 23, 2023
2 parents 6046aa0 + 867a12d commit 8105739
Show file tree
Hide file tree
Showing 18 changed files with 383 additions and 46 deletions.
64 changes: 47 additions & 17 deletions compiler/rustc_lint/src/reference_casting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
}

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;
};

Expand All @@ -86,15 +73,58 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
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();

Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_passes/src/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,11 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'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);
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ impl<'tcx> Tables<'tcx> {
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))
}
Expand Down Expand Up @@ -120,6 +124,10 @@ impl<'tcx> Tables<'tcx> {
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))
}
Expand Down
73 changes: 72 additions & 1 deletion compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -101,6 +102,12 @@ impl<'tcx> Context for Tables<'tcx> {
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> {
Expand Down Expand Up @@ -1205,3 +1212,67 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
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),
}
}
}
3 changes: 2 additions & 1 deletion compiler/rustc_smir/src/stable_mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::cell::Cell;

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;
Expand Down Expand Up @@ -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.
Expand Down
58 changes: 47 additions & 11 deletions compiler/rustc_smir/src/stable_mir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -132,6 +135,12 @@ impl ImplDef {
}
}

impl GenericDef {
pub fn generics_of(&self) -> Generics {
with(|tcx| tcx.generics_of(self))
}
}

#[derive(Clone, Debug)]
pub struct GenericArgs(pub Vec<GenericArgKind>);

Expand Down Expand Up @@ -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,
}
3 changes: 3 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,9 @@ symbols! {
ptr_offset_from,
ptr_offset_from_unsigned,
ptr_unique,
ptr_write,
ptr_write_unaligned,
ptr_write_volatile,
pub_macro_rules,
pub_restricted,
public,
Expand Down
3 changes: 3 additions & 0 deletions library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
#[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
Expand Down Expand Up @@ -1459,6 +1460,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
#[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.
Expand Down Expand Up @@ -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`.
Expand Down
10 changes: 9 additions & 1 deletion library/std/src/keyword_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;`.
///
Expand All @@ -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
Expand All @@ -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")]
Expand Down
Loading

0 comments on commit 8105739

Please sign in to comment.