Skip to content

Commit 8105739

Browse files
committed
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
2 parents 6046aa0 + 867a12d commit 8105739

File tree

18 files changed

+383
-46
lines changed

18 files changed

+383
-46
lines changed

compiler/rustc_lint/src/reference_casting.rs

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
5656
}
5757

5858
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
59-
// &mut <expr>
60-
let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
61-
expr
62-
// <expr> = ...
63-
} else if let ExprKind::Assign(expr, _, _) = expr.kind {
64-
expr
65-
// <expr> += ...
66-
} else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
67-
expr
68-
} else {
69-
return;
70-
};
71-
72-
let ExprKind::Unary(UnOp::Deref, e) = &inner.kind else {
59+
let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else {
7360
return;
7461
};
7562

@@ -86,15 +73,58 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
8673
cx.emit_spanned_lint(
8774
INVALID_REFERENCE_CASTING,
8875
expr.span,
89-
if matches!(expr.kind, ExprKind::AddrOf(..)) {
90-
InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
91-
} else {
76+
if is_assignment {
9277
InvalidReferenceCastingDiag::AssignToRef { orig_cast }
78+
} else {
79+
InvalidReferenceCastingDiag::BorrowAsMut { orig_cast }
9380
},
9481
);
9582
}
9683
}
9784

85+
fn is_operation_we_care_about<'tcx>(
86+
cx: &LateContext<'tcx>,
87+
e: &'tcx Expr<'tcx>,
88+
) -> Option<(bool, &'tcx Expr<'tcx>)> {
89+
fn deref_assign_or_addr_of<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(bool, &'tcx Expr<'tcx>)> {
90+
// &mut <expr>
91+
let inner = if let ExprKind::AddrOf(_, Mutability::Mut, expr) = expr.kind {
92+
expr
93+
// <expr> = ...
94+
} else if let ExprKind::Assign(expr, _, _) = expr.kind {
95+
expr
96+
// <expr> += ...
97+
} else if let ExprKind::AssignOp(_, expr, _) = expr.kind {
98+
expr
99+
} else {
100+
return None;
101+
};
102+
103+
if let ExprKind::Unary(UnOp::Deref, e) = &inner.kind {
104+
Some((!matches!(expr.kind, ExprKind::AddrOf(..)), e))
105+
} else {
106+
None
107+
}
108+
}
109+
110+
fn ptr_write<'tcx>(
111+
cx: &LateContext<'tcx>,
112+
e: &'tcx Expr<'tcx>,
113+
) -> Option<(bool, &'tcx Expr<'tcx>)> {
114+
if let ExprKind::Call(path, [arg_ptr, _arg_val]) = e.kind
115+
&& let ExprKind::Path(ref qpath) = path.kind
116+
&& let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
117+
&& matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::ptr_write | sym::ptr_write_volatile | sym::ptr_write_unaligned))
118+
{
119+
Some((true, arg_ptr))
120+
} else {
121+
None
122+
}
123+
}
124+
125+
deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e))
126+
}
127+
98128
fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
99129
let e = e.peel_blocks();
100130

compiler/rustc_passes/src/reachable.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,11 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
9898
self.worklist.push(def_id);
9999
} else {
100100
match res {
101-
// If this path leads to a constant, then we need to
102-
// recurse into the constant to continue finding
103-
// items that are reachable.
104-
Res::Def(DefKind::Const | DefKind::AssocConst, _) => {
101+
// Reachable constants and reachable statics can have their contents inlined
102+
// into other crates. Mark them as reachable and recurse into their body.
103+
Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::Static(_), _) => {
105104
self.worklist.push(def_id);
106105
}
107-
108-
// If this wasn't a static, then the destination is
109-
// surely reachable.
110106
_ => {
111107
self.reachable_symbols.insert(def_id);
112108
}

compiler/rustc_smir/src/rustc_internal/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ impl<'tcx> Tables<'tcx> {
8080
self.def_ids[impl_def.0]
8181
}
8282

83+
pub fn generic_def_id(&self, generic_def: &stable_mir::ty::GenericDef) -> DefId {
84+
self.def_ids[generic_def.0]
85+
}
86+
8387
pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
8488
stable_mir::CrateItem(self.create_def_id(did))
8589
}
@@ -120,6 +124,10 @@ impl<'tcx> Tables<'tcx> {
120124
stable_mir::ty::TraitDef(self.create_def_id(did))
121125
}
122126

127+
pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef {
128+
stable_mir::ty::GenericDef(self.create_def_id(did))
129+
}
130+
123131
pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef {
124132
stable_mir::ty::ConstDef(self.create_def_id(did))
125133
}

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
use crate::rustc_internal::{self, opaque};
1111
use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
1212
use crate::stable_mir::ty::{
13-
allocation_filter, new_allocation, Const, FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy,
13+
allocation_filter, new_allocation, Const, FloatTy, GenericDef, GenericParamDef, IntTy,
14+
Movability, RigidTy, TyKind, UintTy,
1415
};
1516
use crate::stable_mir::{self, Context};
1617
use rustc_hir as hir;
@@ -101,6 +102,12 @@ impl<'tcx> Context for Tables<'tcx> {
101102
let ty = self.types[ty.0];
102103
ty.stable(self)
103104
}
105+
106+
fn generics_of(&mut self, generic_def: &GenericDef) -> stable_mir::ty::Generics {
107+
let def_id = self.generic_def_id(generic_def);
108+
let generic_def = self.tcx.generics_of(def_id);
109+
generic_def.stable(self)
110+
}
104111
}
105112

106113
pub struct Tables<'tcx> {
@@ -1205,3 +1212,67 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
12051212
TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) }
12061213
}
12071214
}
1215+
1216+
impl<'tcx> Stable<'tcx> for ty::Generics {
1217+
type T = stable_mir::ty::Generics;
1218+
1219+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1220+
use stable_mir::ty::Generics;
1221+
1222+
let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect();
1223+
let param_def_id_to_index =
1224+
params.iter().map(|param| (param.def_id, param.index)).collect();
1225+
1226+
Generics {
1227+
parent: self.parent.map(|did| tables.generic_def(did)),
1228+
parent_count: self.parent_count,
1229+
params,
1230+
param_def_id_to_index,
1231+
has_self: self.has_self,
1232+
has_late_bound_regions: self
1233+
.has_late_bound_regions
1234+
.as_ref()
1235+
.map(|late_bound_regions| late_bound_regions.stable(tables)),
1236+
host_effect_index: self.host_effect_index,
1237+
}
1238+
}
1239+
}
1240+
1241+
impl<'tcx> Stable<'tcx> for rustc_span::Span {
1242+
type T = stable_mir::ty::Span;
1243+
1244+
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
1245+
opaque(self)
1246+
}
1247+
}
1248+
1249+
impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
1250+
type T = stable_mir::ty::GenericParamDefKind;
1251+
1252+
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
1253+
use stable_mir::ty::GenericParamDefKind;
1254+
match self {
1255+
ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
1256+
ty::GenericParamDefKind::Type { has_default, synthetic } => {
1257+
GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic }
1258+
}
1259+
ty::GenericParamDefKind::Const { has_default } => {
1260+
GenericParamDefKind::Const { has_default: *has_default }
1261+
}
1262+
}
1263+
}
1264+
}
1265+
1266+
impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
1267+
type T = stable_mir::ty::GenericParamDef;
1268+
1269+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1270+
GenericParamDef {
1271+
name: self.name.to_string(),
1272+
def_id: tables.generic_def(self.def_id),
1273+
index: self.index,
1274+
pure_wrt_drop: self.pure_wrt_drop,
1275+
kind: self.kind.stable(tables),
1276+
}
1277+
}
1278+
}

compiler/rustc_smir/src/stable_mir/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::cell::Cell;
1515

1616
use crate::rustc_smir::Tables;
1717

18-
use self::ty::{ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
18+
use self::ty::{GenericDef, Generics, ImplDef, ImplTrait, TraitDecl, TraitDef, Ty, TyKind};
1919

2020
pub mod mir;
2121
pub mod ty;
@@ -110,6 +110,7 @@ pub trait Context {
110110
fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
111111
fn all_trait_impls(&mut self) -> ImplTraitDecls;
112112
fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
113+
fn generics_of(&mut self, generic_def: &GenericDef) -> Generics;
113114
/// Get information about the local crate.
114115
fn local_crate(&self) -> Crate;
115116
/// Retrieve a list of all external crates.

compiler/rustc_smir/src/stable_mir/ty.rs

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub struct Const {
2222

2323
type Ident = Opaque;
2424
pub(crate) type Region = Opaque;
25-
type Span = Opaque;
25+
pub type Span = Opaque;
2626

2727
#[derive(Clone, Debug)]
2828
pub enum TyKind {
@@ -87,34 +87,37 @@ pub enum Movability {
8787
Movable,
8888
}
8989

90-
#[derive(Clone, PartialEq, Eq, Debug)]
90+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
9191
pub struct ForeignDef(pub(crate) DefId);
9292

93-
#[derive(Clone, PartialEq, Eq, Debug)]
93+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
9494
pub struct FnDef(pub(crate) DefId);
9595

96-
#[derive(Clone, PartialEq, Eq, Debug)]
96+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
9797
pub struct ClosureDef(pub(crate) DefId);
9898

99-
#[derive(Clone, PartialEq, Eq, Debug)]
99+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
100100
pub struct GeneratorDef(pub(crate) DefId);
101101

102-
#[derive(Clone, PartialEq, Eq, Debug)]
102+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
103103
pub struct ParamDef(pub(crate) DefId);
104104

105-
#[derive(Clone, PartialEq, Eq, Debug)]
105+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
106106
pub struct BrNamedDef(pub(crate) DefId);
107107

108-
#[derive(Clone, PartialEq, Eq, Debug)]
108+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
109109
pub struct AdtDef(pub(crate) DefId);
110110

111-
#[derive(Clone, PartialEq, Eq, Debug)]
111+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
112112
pub struct AliasDef(pub(crate) DefId);
113113

114-
#[derive(Clone, PartialEq, Eq, Debug)]
114+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
115115
pub struct TraitDef(pub(crate) DefId);
116116

117-
#[derive(Clone, PartialEq, Eq, Debug)]
117+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
118+
pub struct GenericDef(pub(crate) DefId);
119+
120+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
118121
pub struct ConstDef(pub(crate) DefId);
119122

120123
impl TraitDef {
@@ -132,6 +135,12 @@ impl ImplDef {
132135
}
133136
}
134137

138+
impl GenericDef {
139+
pub fn generics_of(&self) -> Generics {
140+
with(|tcx| tcx.generics_of(self))
141+
}
142+
}
143+
135144
#[derive(Clone, Debug)]
136145
pub struct GenericArgs(pub Vec<GenericArgKind>);
137146

@@ -461,3 +470,30 @@ pub struct TraitRef {
461470
pub def_id: TraitDef,
462471
pub args: GenericArgs,
463472
}
473+
474+
#[derive(Clone, Debug)]
475+
pub struct Generics {
476+
pub parent: Option<GenericDef>,
477+
pub parent_count: usize,
478+
pub params: Vec<GenericParamDef>,
479+
pub param_def_id_to_index: Vec<(GenericDef, u32)>,
480+
pub has_self: bool,
481+
pub has_late_bound_regions: Option<Span>,
482+
pub host_effect_index: Option<usize>,
483+
}
484+
485+
#[derive(Clone, Debug)]
486+
pub enum GenericParamDefKind {
487+
Lifetime,
488+
Type { has_default: bool, synthetic: bool },
489+
Const { has_default: bool },
490+
}
491+
492+
#[derive(Clone, Debug)]
493+
pub struct GenericParamDef {
494+
pub name: super::Symbol,
495+
pub def_id: GenericDef,
496+
pub index: u32,
497+
pub pure_wrt_drop: bool,
498+
pub kind: GenericParamDefKind,
499+
}

compiler/rustc_span/src/symbol.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,9 @@ symbols! {
11791179
ptr_offset_from,
11801180
ptr_offset_from_unsigned,
11811181
ptr_unique,
1182+
ptr_write,
1183+
ptr_write_unaligned,
1184+
ptr_write_volatile,
11821185
pub_macro_rules,
11831186
pub_restricted,
11841187
public,

library/core/src/ptr/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
13571357
#[inline]
13581358
#[stable(feature = "rust1", since = "1.0.0")]
13591359
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
1360+
#[rustc_diagnostic_item = "ptr_write"]
13601361
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
13611362
pub const unsafe fn write<T>(dst: *mut T, src: T) {
13621363
// Semantically, it would be fine for this to be implemented as a
@@ -1459,6 +1460,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
14591460
#[inline]
14601461
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
14611462
#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
1463+
#[rustc_diagnostic_item = "ptr_write_unaligned"]
14621464
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
14631465
pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
14641466
// 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 {
16071609
/// ```
16081610
#[inline]
16091611
#[stable(feature = "volatile", since = "1.9.0")]
1612+
#[rustc_diagnostic_item = "ptr_write_volatile"]
16101613
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
16111614
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
16121615
// SAFETY: the caller must uphold the safety contract for `volatile_store`.

library/std/src/keyword_docs.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1820,7 +1820,7 @@ mod true_keyword {}
18201820

18211821
#[doc(keyword = "type")]
18221822
//
1823-
/// Define an alias for an existing type.
1823+
/// Define an [alias] for an existing type.
18241824
///
18251825
/// The syntax is `type Name = ExistingType;`.
18261826
///
@@ -1838,6 +1838,13 @@ mod true_keyword {}
18381838
/// assert_eq!(m, k);
18391839
/// ```
18401840
///
1841+
/// A type can be generic:
1842+
///
1843+
/// ```rust
1844+
/// # use std::sync::{Arc, Mutex};
1845+
/// type ArcMutex<T> = Arc<Mutex<T>>;
1846+
/// ```
1847+
///
18411848
/// In traits, `type` is used to declare an [associated type]:
18421849
///
18431850
/// ```rust
@@ -1860,6 +1867,7 @@ mod true_keyword {}
18601867
///
18611868
/// [`trait`]: keyword.trait.html
18621869
/// [associated type]: ../reference/items/associated-items.html#associated-types
1870+
/// [alias]: ../reference/items/type-aliases.html
18631871
mod type_keyword {}
18641872

18651873
#[doc(keyword = "unsafe")]

0 commit comments

Comments
 (0)