Skip to content

Commit 4e78abb

Browse files
committed
Auto merge of #115326 - matthiaskrgr:rollup-qsoa8ar, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #115164 (MIR validation: reject in-place argument/return for packed fields) - #115240 (codegen_llvm/llvm_type: avoid matching on the Rust type) - #115294 (More precisely detect cycle errors from type_of on opaque) - #115310 (Document panic behavior across editions, and improve xrefs) - #115311 (Revert "Suggest using `Arc` on `!Send`/`!Sync` types") - #115317 (Devacationize oli-obk) - #115319 (don't use SnapshotVec in Graph implementation, as it looks unused; use Vec instead) - #115322 (Tweak output of `to_pretty_impl_header` involving only anon lifetimes) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 93dd620 + 07a32e2 commit 4e78abb

File tree

154 files changed

+435
-658
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+435
-658
lines changed

compiler/rustc_codegen_gcc/src/abi.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
125125
PassMode::Ignore => continue,
126126
PassMode::Direct(_) => arg.layout.immediate_gcc_type(cx),
127127
PassMode::Pair(..) => {
128-
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 0, true));
129-
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 1, true));
128+
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 0));
129+
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 1));
130130
continue;
131131
}
132132
PassMode::Indirect { extra_attrs: Some(_), .. } => {

compiler/rustc_codegen_gcc/src/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
821821

822822
let mut load = |i, scalar: &abi::Scalar, align| {
823823
let llptr = self.struct_gep(pair_type, place.llval, i as u64);
824-
let llty = place.layout.scalar_pair_element_gcc_type(self, i, false);
824+
let llty = place.layout.scalar_pair_element_gcc_type(self, i);
825825
let load = self.load(llty, llptr, align);
826826
scalar_load_metadata(self, load, scalar);
827827
if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load }

compiler/rustc_codegen_gcc/src/type_of.rs

+14-34
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use gccjit::{Struct, Type};
44
use crate::rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods};
55
use rustc_middle::bug;
66
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
7-
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
7+
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
88
use rustc_middle::ty::print::with_no_trimmed_paths;
99
use rustc_target::abi::{self, Abi, Align, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
1010
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
@@ -74,8 +74,8 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
7474
Abi::ScalarPair(..) => {
7575
return cx.type_struct(
7676
&[
77-
layout.scalar_pair_element_gcc_type(cx, 0, false),
78-
layout.scalar_pair_element_gcc_type(cx, 1, false),
77+
layout.scalar_pair_element_gcc_type(cx, 0),
78+
layout.scalar_pair_element_gcc_type(cx, 1),
7979
],
8080
false,
8181
);
@@ -150,7 +150,7 @@ pub trait LayoutGccExt<'tcx> {
150150
fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
151151
fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
152152
fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc>;
153-
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize, immediate: bool) -> Type<'gcc>;
153+
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize) -> Type<'gcc>;
154154
fn gcc_field_index(&self, index: usize) -> u64;
155155
fn pointee_info_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, offset: Size) -> Option<PointeeInfo>;
156156
}
@@ -182,23 +182,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
182182
/// of that field's type - this is useful for taking the address of
183183
/// that field and ensuring the struct has the right alignment.
184184
fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
185+
// This must produce the same result for `repr(transparent)` wrappers as for the inner type!
186+
// In other words, this should generally not look at the type at all, but only at the
187+
// layout.
185188
if let Abi::Scalar(ref scalar) = self.abi {
186189
// Use a different cache for scalars because pointers to DSTs
187190
// can be either fat or thin (data pointers of fat pointers).
188191
if let Some(&ty) = cx.scalar_types.borrow().get(&self.ty) {
189192
return ty;
190193
}
191-
let ty =
192-
match *self.ty.kind() {
193-
ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
194-
cx.type_ptr_to(cx.layout_of(ty).gcc_type(cx))
195-
}
196-
ty::Adt(def, _) if def.is_box() => {
197-
cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).gcc_type(cx))
198-
}
199-
ty::FnPtr(sig) => cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, ty::List::empty())),
200-
_ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO),
201-
};
194+
let ty = self.scalar_gcc_type_at(cx, scalar, Size::ZERO);
202195
cx.scalar_types.borrow_mut().insert(self.ty, ty);
203196
return ty;
204197
}
@@ -272,23 +265,10 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
272265
}
273266
}
274267

275-
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize, immediate: bool) -> Type<'gcc> {
276-
// TODO(antoyo): remove llvm hack:
277-
// HACK(eddyb) special-case fat pointers until LLVM removes
278-
// pointee types, to avoid bitcasting every `OperandRef::deref`.
279-
match self.ty.kind() {
280-
ty::Ref(..) | ty::RawPtr(_) => {
281-
return self.field(cx, index).gcc_type(cx);
282-
}
283-
// only wide pointer boxes are handled as pointers
284-
// thin pointer boxes with scalar allocators are handled by the general logic below
285-
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
286-
let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty());
287-
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
288-
}
289-
_ => {}
290-
}
291-
268+
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize) -> Type<'gcc> {
269+
// This must produce the same result for `repr(transparent)` wrappers as for the inner type!
270+
// In other words, this should generally not look at the type at all, but only at the
271+
// layout.
292272
let (a, b) = match self.abi {
293273
Abi::ScalarPair(ref a, ref b) => (a, b),
294274
_ => bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self),
@@ -367,8 +347,8 @@ impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
367347
layout.gcc_field_index(index)
368348
}
369349

370-
fn scalar_pair_element_backend_type(&self, layout: TyAndLayout<'tcx>, index: usize, immediate: bool) -> Type<'gcc> {
371-
layout.scalar_pair_element_gcc_type(self, index, immediate)
350+
fn scalar_pair_element_backend_type(&self, layout: TyAndLayout<'tcx>, index: usize, _immediate: bool) -> Type<'gcc> {
351+
layout.scalar_pair_element_gcc_type(self, index)
372352
}
373353

374354
fn cast_backend_type(&self, ty: &CastTarget) -> Type<'gcc> {

compiler/rustc_codegen_llvm/src/type_of.rs

+8-30
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::context::TypeLowering;
33
use crate::type_::Type;
44
use rustc_codegen_ssa::traits::*;
55
use rustc_middle::bug;
6-
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
6+
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
77
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
88
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
99
use rustc_target::abi::HasDataLayout;
@@ -215,20 +215,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
215215
/// of that field's type - this is useful for taking the address of
216216
/// that field and ensuring the struct has the right alignment.
217217
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
218+
// This must produce the same result for `repr(transparent)` wrappers as for the inner type!
219+
// In other words, this should generally not look at the type at all, but only at the
220+
// layout.
218221
if let Abi::Scalar(scalar) = self.abi {
219222
// Use a different cache for scalars because pointers to DSTs
220223
// can be either fat or thin (data pointers of fat pointers).
221224
if let Some(&llty) = cx.scalar_lltypes.borrow().get(&self.ty) {
222225
return llty;
223226
}
224-
let llty = match *self.ty.kind() {
225-
ty::Ref(..) | ty::RawPtr(_) => cx.type_ptr(),
226-
ty::Adt(def, _) if def.is_box() => cx.type_ptr(),
227-
ty::FnPtr(sig) => {
228-
cx.fn_ptr_backend_type(cx.fn_abi_of_fn_ptr(sig, ty::List::empty()))
229-
}
230-
_ => self.scalar_llvm_type_at(cx, scalar),
231-
};
227+
let llty = self.scalar_llvm_type_at(cx, scalar);
232228
cx.scalar_lltypes.borrow_mut().insert(self.ty, llty);
233229
return llty;
234230
}
@@ -303,27 +299,9 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
303299
index: usize,
304300
immediate: bool,
305301
) -> &'a Type {
306-
// HACK(eddyb) special-case fat pointers until LLVM removes
307-
// pointee types, to avoid bitcasting every `OperandRef::deref`.
308-
match *self.ty.kind() {
309-
ty::Ref(..) | ty::RawPtr(_) => {
310-
return self.field(cx, index).llvm_type(cx);
311-
}
312-
// only wide pointer boxes are handled as pointers
313-
// thin pointer boxes with scalar allocators are handled by the general logic below
314-
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
315-
let ptr_ty = Ty::new_mut_ptr(cx.tcx, self.ty.boxed_ty());
316-
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
317-
}
318-
// `dyn* Trait` has the same ABI as `*mut dyn Trait`
319-
ty::Dynamic(bounds, region, ty::DynStar) => {
320-
let ptr_ty =
321-
Ty::new_mut_ptr(cx.tcx, Ty::new_dynamic(cx.tcx, bounds, region, ty::Dyn));
322-
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
323-
}
324-
_ => {}
325-
}
326-
302+
// This must produce the same result for `repr(transparent)` wrappers as for the inner type!
303+
// In other words, this should generally not look at the type at all, but only at the
304+
// layout.
327305
let Abi::ScalarPair(a, b) = self.abi else {
328306
bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self);
329307
};

compiler/rustc_const_eval/src/transform/validate.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ use rustc_mir_dataflow::{Analysis, ResultsCursor};
2020
use rustc_target::abi::{Size, FIRST_VARIANT};
2121
use rustc_target::spec::abi::Abi;
2222

23+
use crate::util::is_within_packed;
24+
2325
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
2426
enum EdgeKind {
2527
Unwind,
@@ -93,6 +95,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
9395
cfg_checker.visit_body(body);
9496
cfg_checker.check_cleanup_control_flow();
9597

98+
// Also run the TypeChecker.
9699
for (location, msg) in validate_types(tcx, self.mir_phase, param_env, body) {
97100
cfg_checker.fail(location, msg);
98101
}
@@ -427,22 +430,42 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
427430
self.check_unwind_edge(location, *unwind);
428431

429432
// The call destination place and Operand::Move place used as an argument might be
430-
// passed by a reference to the callee. Consequently they must be non-overlapping.
431-
// Currently this simply checks for duplicate places.
433+
// passed by a reference to the callee. Consequently they must be non-overlapping
434+
// and cannot be packed. Currently this simply checks for duplicate places.
432435
self.place_cache.clear();
433436
self.place_cache.insert(destination.as_ref());
437+
if is_within_packed(self.tcx, &self.body.local_decls, *destination).is_some() {
438+
// This is bad! The callee will expect the memory to be aligned.
439+
self.fail(
440+
location,
441+
format!(
442+
"encountered packed place in `Call` terminator destination: {:?}",
443+
terminator.kind,
444+
),
445+
);
446+
}
434447
let mut has_duplicates = false;
435448
for arg in args {
436449
if let Operand::Move(place) = arg {
437450
has_duplicates |= !self.place_cache.insert(place.as_ref());
451+
if is_within_packed(self.tcx, &self.body.local_decls, *place).is_some() {
452+
// This is bad! The callee will expect the memory to be aligned.
453+
self.fail(
454+
location,
455+
format!(
456+
"encountered `Move` of a packed place in `Call` terminator: {:?}",
457+
terminator.kind,
458+
),
459+
);
460+
}
438461
}
439462
}
440463

441464
if has_duplicates {
442465
self.fail(
443466
location,
444467
format!(
445-
"encountered overlapping memory in `Call` terminator: {:?}",
468+
"encountered overlapping memory in `Move` arguments to `Call` terminator: {:?}",
446469
terminator.kind,
447470
),
448471
);
@@ -541,6 +564,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
541564
}
542565
}
543566

567+
/// A faster version of the validation pass that only checks those things which may break when apply
568+
/// generic substitutions.
544569
pub fn validate_types<'tcx>(
545570
tcx: TyCtxt<'tcx>,
546571
mir_phase: MirPhase,

compiler/rustc_const_eval/src/util/alignment.rs

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ where
3434
false
3535
}
3636
_ => {
37+
// We cannot figure out the layout. Conservatively assume that this is disaligned.
3738
debug!("is_disaligned({:?}) - true", place);
3839
true
3940
}

compiler/rustc_data_structures/src/graph/implementation/mod.rs

+4-19
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,15 @@
2020
//! the field `next_edge`). Each of those fields is an array that should
2121
//! be indexed by the direction (see the type `Direction`).
2222
23-
use crate::snapshot_vec::{SnapshotVec, SnapshotVecDelegate};
2423
use rustc_index::bit_set::BitSet;
2524
use std::fmt::Debug;
2625

2726
#[cfg(test)]
2827
mod tests;
2928

3029
pub struct Graph<N, E> {
31-
nodes: SnapshotVec<Node<N>>,
32-
edges: SnapshotVec<Edge<E>>,
30+
nodes: Vec<Node<N>>,
31+
edges: Vec<Edge<E>>,
3332
}
3433

3534
pub struct Node<N> {
@@ -45,20 +44,6 @@ pub struct Edge<E> {
4544
pub data: E,
4645
}
4746

48-
impl<N> SnapshotVecDelegate for Node<N> {
49-
type Value = Node<N>;
50-
type Undo = ();
51-
52-
fn reverse(_: &mut Vec<Node<N>>, _: ()) {}
53-
}
54-
55-
impl<N> SnapshotVecDelegate for Edge<N> {
56-
type Value = Edge<N>;
57-
type Undo = ();
58-
59-
fn reverse(_: &mut Vec<Edge<N>>, _: ()) {}
60-
}
61-
6247
#[derive(Copy, Clone, PartialEq, Debug)]
6348
pub struct NodeIndex(pub usize);
6449

@@ -86,11 +71,11 @@ impl NodeIndex {
8671

8772
impl<N: Debug, E: Debug> Graph<N, E> {
8873
pub fn new() -> Graph<N, E> {
89-
Graph { nodes: SnapshotVec::new(), edges: SnapshotVec::new() }
74+
Graph { nodes: Vec::new(), edges: Vec::new() }
9075
}
9176

9277
pub fn with_capacity(nodes: usize, edges: usize) -> Graph<N, E> {
93-
Graph { nodes: SnapshotVec::with_capacity(nodes), edges: SnapshotVec::with_capacity(edges) }
78+
Graph { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
9479
}
9580

9681
// # Simple accessors

compiler/rustc_hir_analysis/src/collect.rs

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pub fn provide(providers: &mut Providers) {
5656
resolve_bound_vars::provide(providers);
5757
*providers = Providers {
5858
type_of: type_of::type_of,
59+
type_of_opaque: type_of::type_of_opaque,
5960
item_bounds: item_bounds::item_bounds,
6061
explicit_item_bounds: item_bounds::explicit_item_bounds,
6162
generics_of: generics_of::generics_of,

0 commit comments

Comments
 (0)