Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #115326

Merged
merged 25 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
739144f
MIR validation: reject in-place argument/return for packed fields
RalfJung Aug 24, 2023
0fde82f
codegen_llvm/llvm_type: avoid matching on the Rust type
RalfJung Aug 26, 2023
e7b3c94
Pass ErrorGuaranteed to cycle error
compiler-errors Aug 27, 2023
bf53598
More precisely detect cycle errors from type_of on opaque
compiler-errors Aug 27, 2023
1116707
panic macro: Document edition differences
ijackson Apr 28, 2022
55159e8
print macros: add xrefs to format syntax documentation
ijackson Apr 28, 2022
2ec8b6b
panic macro: Link directly to format syntax, not to format!
ijackson Apr 28, 2022
39c642e
format, format_args: Make xref to std::fmt much more prominent
ijackson Apr 28, 2022
5016695
improve panic.md edition disucssion, and nits
RalfJung Aug 28, 2023
4120936
Revert "Make `rustc_on_unimplemented` std-agnostic for `alloc::rc`"
dtolnay Aug 28, 2023
823bacb
Revert "Suggest using `Arc` on `!Send`/`!Sync` types"
dtolnay Aug 28, 2023
dc70fb6
also avoid matching on the type in scalar_pair_element_llvm_type
RalfJung Aug 28, 2023
99d76a4
carry out the same changes in the gcc backend
RalfJung Aug 28, 2023
5a4ba68
Devacationize oli-obk
oli-obk Aug 28, 2023
3b26b3d
don't use SnapshotVec in Graph implementation, as it looks unused; us…
klensy Aug 21, 2023
9b9cb51
remove an unused argument
RalfJung Aug 28, 2023
ecf2f68
Tweak output of `to_pretty_impl_header` involving only anon lifetimes
estebank Aug 28, 2023
88b476c
Rollup merge of #115164 - RalfJung:no-in-place-packed, r=b-naber
matthiaskrgr Aug 28, 2023
a5b7504
Rollup merge of #115240 - RalfJung:llvm-no-type, r=bjorn3
matthiaskrgr Aug 28, 2023
b4c63f0
Rollup merge of #115294 - compiler-errors:cycle-err, r=oli-obk
matthiaskrgr Aug 28, 2023
2eff0de
Rollup merge of #115310 - RalfJung:panic-and-format, r=scottmcm
matthiaskrgr Aug 28, 2023
9b0abe3
Rollup merge of #115311 - dtolnay:usearcself, r=compiler-errors
matthiaskrgr Aug 28, 2023
7b6d264
Rollup merge of #115317 - oli-obk:no_moar_vacation, r=oli-obk
matthiaskrgr Aug 28, 2023
de6b03b
Rollup merge of #115319 - klensy:no-snapshot-in-graph, r=WaffleLapkin
matthiaskrgr Aug 28, 2023
07a32e2
Rollup merge of #115322 - estebank:list-tweak, r=compiler-errors
matthiaskrgr Aug 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
PassMode::Ignore => continue,
PassMode::Direct(_) => arg.layout.immediate_gcc_type(cx),
PassMode::Pair(..) => {
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 0, true));
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 1, true));
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 0));
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 1));
continue;
}
PassMode::Indirect { extra_attrs: Some(_), .. } => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {

let mut load = |i, scalar: &abi::Scalar, align| {
let llptr = self.struct_gep(pair_type, place.llval, i as u64);
let llty = place.layout.scalar_pair_element_gcc_type(self, i, false);
let llty = place.layout.scalar_pair_element_gcc_type(self, i);
let load = self.load(llty, llptr, align);
scalar_load_metadata(self, load, scalar);
if scalar.is_bool() { self.trunc(load, self.type_i1()) } else { load }
Expand Down
48 changes: 14 additions & 34 deletions compiler/rustc_codegen_gcc/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use gccjit::{Struct, Type};
use crate::rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods};
use rustc_middle::bug;
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_target::abi::{self, Abi, Align, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants};
use rustc_target::abi::call::{CastTarget, FnAbi, Reg};
Expand Down Expand Up @@ -74,8 +74,8 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
Abi::ScalarPair(..) => {
return cx.type_struct(
&[
layout.scalar_pair_element_gcc_type(cx, 0, false),
layout.scalar_pair_element_gcc_type(cx, 1, false),
layout.scalar_pair_element_gcc_type(cx, 0),
layout.scalar_pair_element_gcc_type(cx, 1),
],
false,
);
Expand Down Expand Up @@ -150,7 +150,7 @@ pub trait LayoutGccExt<'tcx> {
fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
fn immediate_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
fn scalar_gcc_type_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, scalar: &abi::Scalar, offset: Size) -> Type<'gcc>;
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize, immediate: bool) -> Type<'gcc>;
fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize) -> Type<'gcc>;
fn gcc_field_index(&self, index: usize) -> u64;
fn pointee_info_at<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, offset: Size) -> Option<PointeeInfo>;
}
Expand Down Expand Up @@ -182,23 +182,16 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
/// of that field's type - this is useful for taking the address of
/// that field and ensuring the struct has the right alignment.
fn gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
// This must produce the same result for `repr(transparent)` wrappers as for the inner type!
// In other words, this should generally not look at the type at all, but only at the
// layout.
if let Abi::Scalar(ref scalar) = self.abi {
// Use a different cache for scalars because pointers to DSTs
// can be either fat or thin (data pointers of fat pointers).
if let Some(&ty) = cx.scalar_types.borrow().get(&self.ty) {
return ty;
}
let ty =
match *self.ty.kind() {
ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
cx.type_ptr_to(cx.layout_of(ty).gcc_type(cx))
}
ty::Adt(def, _) if def.is_box() => {
cx.type_ptr_to(cx.layout_of(self.ty.boxed_ty()).gcc_type(cx))
}
ty::FnPtr(sig) => cx.fn_ptr_backend_type(&cx.fn_abi_of_fn_ptr(sig, ty::List::empty())),
_ => self.scalar_gcc_type_at(cx, scalar, Size::ZERO),
};
let ty = self.scalar_gcc_type_at(cx, scalar, Size::ZERO);
cx.scalar_types.borrow_mut().insert(self.ty, ty);
return ty;
}
Expand Down Expand Up @@ -272,23 +265,10 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
}
}

fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize, immediate: bool) -> Type<'gcc> {
// TODO(antoyo): remove llvm hack:
// HACK(eddyb) special-case fat pointers until LLVM removes
// pointee types, to avoid bitcasting every `OperandRef::deref`.
match self.ty.kind() {
ty::Ref(..) | ty::RawPtr(_) => {
return self.field(cx, index).gcc_type(cx);
}
// only wide pointer boxes are handled as pointers
// thin pointer boxes with scalar allocators are handled by the general logic below
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty());
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
}
_ => {}
}

fn scalar_pair_element_gcc_type<'gcc>(&self, cx: &CodegenCx<'gcc, 'tcx>, index: usize) -> Type<'gcc> {
// This must produce the same result for `repr(transparent)` wrappers as for the inner type!
// In other words, this should generally not look at the type at all, but only at the
// layout.
let (a, b) = match self.abi {
Abi::ScalarPair(ref a, ref b) => (a, b),
_ => bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self),
Expand Down Expand Up @@ -367,8 +347,8 @@ impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
layout.gcc_field_index(index)
}

fn scalar_pair_element_backend_type(&self, layout: TyAndLayout<'tcx>, index: usize, immediate: bool) -> Type<'gcc> {
layout.scalar_pair_element_gcc_type(self, index, immediate)
fn scalar_pair_element_backend_type(&self, layout: TyAndLayout<'tcx>, index: usize, _immediate: bool) -> Type<'gcc> {
layout.scalar_pair_element_gcc_type(self, index)
}

fn cast_backend_type(&self, ty: &CastTarget) -> Type<'gcc> {
Expand Down
38 changes: 8 additions & 30 deletions compiler/rustc_codegen_llvm/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::context::TypeLowering;
use crate::type_::Type;
use rustc_codegen_ssa::traits::*;
use rustc_middle::bug;
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_target::abi::HasDataLayout;
Expand Down Expand Up @@ -215,20 +215,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
/// of that field's type - this is useful for taking the address of
/// that field and ensuring the struct has the right alignment.
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
// This must produce the same result for `repr(transparent)` wrappers as for the inner type!
// In other words, this should generally not look at the type at all, but only at the
// layout.
if let Abi::Scalar(scalar) = self.abi {
// Use a different cache for scalars because pointers to DSTs
// can be either fat or thin (data pointers of fat pointers).
if let Some(&llty) = cx.scalar_lltypes.borrow().get(&self.ty) {
return llty;
}
let llty = match *self.ty.kind() {
ty::Ref(..) | ty::RawPtr(_) => cx.type_ptr(),
ty::Adt(def, _) if def.is_box() => cx.type_ptr(),
ty::FnPtr(sig) => {
cx.fn_ptr_backend_type(cx.fn_abi_of_fn_ptr(sig, ty::List::empty()))
}
_ => self.scalar_llvm_type_at(cx, scalar),
};
let llty = self.scalar_llvm_type_at(cx, scalar);
cx.scalar_lltypes.borrow_mut().insert(self.ty, llty);
return llty;
}
Expand Down Expand Up @@ -303,27 +299,9 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
index: usize,
immediate: bool,
) -> &'a Type {
// HACK(eddyb) special-case fat pointers until LLVM removes
// pointee types, to avoid bitcasting every `OperandRef::deref`.
match *self.ty.kind() {
ty::Ref(..) | ty::RawPtr(_) => {
return self.field(cx, index).llvm_type(cx);
}
// only wide pointer boxes are handled as pointers
// thin pointer boxes with scalar allocators are handled by the general logic below
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
let ptr_ty = Ty::new_mut_ptr(cx.tcx, self.ty.boxed_ty());
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
}
// `dyn* Trait` has the same ABI as `*mut dyn Trait`
ty::Dynamic(bounds, region, ty::DynStar) => {
let ptr_ty =
Ty::new_mut_ptr(cx.tcx, Ty::new_dynamic(cx.tcx, bounds, region, ty::Dyn));
return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index, immediate);
}
_ => {}
}

// This must produce the same result for `repr(transparent)` wrappers as for the inner type!
// In other words, this should generally not look at the type at all, but only at the
// layout.
let Abi::ScalarPair(a, b) = self.abi else {
bug!("TyAndLayout::scalar_pair_element_llty({:?}): not applicable", self);
};
Expand Down
31 changes: 28 additions & 3 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use rustc_mir_dataflow::{Analysis, ResultsCursor};
use rustc_target::abi::{Size, FIRST_VARIANT};
use rustc_target::spec::abi::Abi;

use crate::util::is_within_packed;

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum EdgeKind {
Unwind,
Expand Down Expand Up @@ -93,6 +95,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
cfg_checker.visit_body(body);
cfg_checker.check_cleanup_control_flow();

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

// The call destination place and Operand::Move place used as an argument might be
// passed by a reference to the callee. Consequently they must be non-overlapping.
// Currently this simply checks for duplicate places.
// passed by a reference to the callee. Consequently they must be non-overlapping
// and cannot be packed. Currently this simply checks for duplicate places.
self.place_cache.clear();
self.place_cache.insert(destination.as_ref());
if is_within_packed(self.tcx, &self.body.local_decls, *destination).is_some() {
// This is bad! The callee will expect the memory to be aligned.
self.fail(
location,
format!(
"encountered packed place in `Call` terminator destination: {:?}",
terminator.kind,
),
);
}
let mut has_duplicates = false;
for arg in args {
if let Operand::Move(place) = arg {
has_duplicates |= !self.place_cache.insert(place.as_ref());
if is_within_packed(self.tcx, &self.body.local_decls, *place).is_some() {
// This is bad! The callee will expect the memory to be aligned.
self.fail(
location,
format!(
"encountered `Move` of a packed place in `Call` terminator: {:?}",
terminator.kind,
),
);
}
}
}

if has_duplicates {
self.fail(
location,
format!(
"encountered overlapping memory in `Call` terminator: {:?}",
"encountered overlapping memory in `Move` arguments to `Call` terminator: {:?}",
terminator.kind,
),
);
Expand Down Expand Up @@ -541,6 +564,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
}
}

/// A faster version of the validation pass that only checks those things which may break when apply
/// generic substitutions.
pub fn validate_types<'tcx>(
tcx: TyCtxt<'tcx>,
mir_phase: MirPhase,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/util/alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ where
false
}
_ => {
// We cannot figure out the layout. Conservatively assume that this is disaligned.
debug!("is_disaligned({:?}) - true", place);
true
}
Expand Down
23 changes: 4 additions & 19 deletions compiler/rustc_data_structures/src/graph/implementation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@
//! the field `next_edge`). Each of those fields is an array that should
//! be indexed by the direction (see the type `Direction`).

use crate::snapshot_vec::{SnapshotVec, SnapshotVecDelegate};
use rustc_index::bit_set::BitSet;
use std::fmt::Debug;

#[cfg(test)]
mod tests;

pub struct Graph<N, E> {
nodes: SnapshotVec<Node<N>>,
edges: SnapshotVec<Edge<E>>,
nodes: Vec<Node<N>>,
edges: Vec<Edge<E>>,
}

pub struct Node<N> {
Expand All @@ -45,20 +44,6 @@ pub struct Edge<E> {
pub data: E,
}

impl<N> SnapshotVecDelegate for Node<N> {
type Value = Node<N>;
type Undo = ();

fn reverse(_: &mut Vec<Node<N>>, _: ()) {}
}

impl<N> SnapshotVecDelegate for Edge<N> {
type Value = Edge<N>;
type Undo = ();

fn reverse(_: &mut Vec<Edge<N>>, _: ()) {}
}

#[derive(Copy, Clone, PartialEq, Debug)]
pub struct NodeIndex(pub usize);

Expand Down Expand Up @@ -86,11 +71,11 @@ impl NodeIndex {

impl<N: Debug, E: Debug> Graph<N, E> {
pub fn new() -> Graph<N, E> {
Graph { nodes: SnapshotVec::new(), edges: SnapshotVec::new() }
Graph { nodes: Vec::new(), edges: Vec::new() }
}

pub fn with_capacity(nodes: usize, edges: usize) -> Graph<N, E> {
Graph { nodes: SnapshotVec::with_capacity(nodes), edges: SnapshotVec::with_capacity(edges) }
Graph { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
}

// # Simple accessors
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub fn provide(providers: &mut Providers) {
resolve_bound_vars::provide(providers);
*providers = Providers {
type_of: type_of::type_of,
type_of_opaque: type_of::type_of_opaque,
item_bounds: item_bounds::item_bounds,
explicit_item_bounds: item_bounds::explicit_item_bounds,
generics_of: generics_of::generics_of,
Expand Down
Loading