Skip to content

Commit 2518c0f

Browse files
committed
Auto merge of rust-lang#3044 - rust-lang:rustup-2023-08-31, r=RalfJung
Automatic sync from rustc
2 parents d9c11c6 + f57b415 commit 2518c0f

File tree

2,065 files changed

+18910
-10896
lines changed

Some content is hidden

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

2,065 files changed

+18910
-10896
lines changed

Cargo.lock

Lines changed: 211 additions & 31 deletions
Large diffs are not rendered by default.

compiler/rustc_abi/src/layout.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,10 @@ pub trait LayoutCalculator {
157157
// for non-ZST uninhabited data (mostly partial initialization).
158158
let absent = |fields: &IndexSlice<FieldIdx, Layout<'_>>| {
159159
let uninhabited = fields.iter().any(|f| f.abi().is_uninhabited());
160-
let is_zst = fields.iter().all(|f| f.0.is_zst());
161-
uninhabited && is_zst
160+
// We cannot ignore alignment; that might lead us to entirely discard a variant and
161+
// produce an enum that is less aligned than it should be!
162+
let is_1zst = fields.iter().all(|f| f.0.is_1zst());
163+
uninhabited && is_1zst
162164
};
163165
let (present_first, present_second) = {
164166
let mut present_variants = variants
@@ -357,10 +359,8 @@ pub trait LayoutCalculator {
357359
// It'll fit, but we need to make some adjustments.
358360
match layout.fields {
359361
FieldsShape::Arbitrary { ref mut offsets, .. } => {
360-
for (j, offset) in offsets.iter_enumerated_mut() {
361-
if !variants[i][j].0.is_zst() {
362-
*offset += this_offset;
363-
}
362+
for offset in offsets.iter_mut() {
363+
*offset += this_offset;
364364
}
365365
}
366366
_ => {
@@ -504,7 +504,7 @@ pub trait LayoutCalculator {
504504
// to make room for a larger discriminant.
505505
for field_idx in st.fields.index_by_increasing_offset() {
506506
let field = &field_layouts[FieldIdx::from_usize(field_idx)];
507-
if !field.0.is_zst() || field.align().abi.bytes() != 1 {
507+
if !field.0.is_1zst() {
508508
start_align = start_align.min(field.align().abi);
509509
break;
510510
}
@@ -603,12 +603,15 @@ pub trait LayoutCalculator {
603603
abi = Abi::Scalar(tag);
604604
} else {
605605
// Try to use a ScalarPair for all tagged enums.
606+
// That's possible only if we can find a common primitive type for all variants.
606607
let mut common_prim = None;
607608
let mut common_prim_initialized_in_all_variants = true;
608609
for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
609610
let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
610611
panic!();
611612
};
613+
// We skip *all* ZST here and later check if we are good in terms of alignment.
614+
// This lets us handle some cases involving aligned ZST.
612615
let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.0.is_zst());
613616
let (field, offset) = match (fields.next(), fields.next()) {
614617
(None, None) => {
@@ -954,9 +957,6 @@ fn univariant(
954957
};
955958

956959
(
957-
// Place ZSTs first to avoid "interesting offsets", especially with only one
958-
// or two non-ZST fields. This helps Scalar/ScalarPair layouts.
959-
!f.0.is_zst(),
960960
// Then place largest alignments first.
961961
cmp::Reverse(alignment_group_key(f)),
962962
// Then prioritize niche placement within alignment group according to
@@ -1073,9 +1073,10 @@ fn univariant(
10731073
let size = min_size.align_to(align.abi);
10741074
let mut layout_of_single_non_zst_field = None;
10751075
let mut abi = Abi::Aggregate { sized };
1076-
// Unpack newtype ABIs and find scalar pairs.
1076+
// Try to make this a Scalar/ScalarPair.
10771077
if sized && size.bytes() > 0 {
1078-
// All other fields must be ZSTs.
1078+
// We skip *all* ZST here and later check if we are good in terms of alignment.
1079+
// This lets us handle some cases involving aligned ZST.
10791080
let mut non_zst_fields = fields.iter_enumerated().filter(|&(_, f)| !f.0.is_zst());
10801081

10811082
match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) {

compiler/rustc_abi/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,15 +1660,25 @@ pub struct PointeeInfo {
16601660

16611661
impl LayoutS {
16621662
/// Returns `true` if the layout corresponds to an unsized type.
1663+
#[inline]
16631664
pub fn is_unsized(&self) -> bool {
16641665
self.abi.is_unsized()
16651666
}
16661667

1668+
#[inline]
16671669
pub fn is_sized(&self) -> bool {
16681670
self.abi.is_sized()
16691671
}
16701672

1673+
/// Returns `true` if the type is sized and a 1-ZST (meaning it has size 0 and alignment 1).
1674+
pub fn is_1zst(&self) -> bool {
1675+
self.is_sized() && self.size.bytes() == 0 && self.align.abi.bytes() == 1
1676+
}
1677+
16711678
/// Returns `true` if the type is a ZST and not unsized.
1679+
///
1680+
/// Note that this does *not* imply that the type is irrelevant for layout! It can still have
1681+
/// non-trivial alignment constraints. You probably want to use `is_1zst` instead.
16721682
pub fn is_zst(&self) -> bool {
16731683
match self.abi {
16741684
Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. } => false,

compiler/rustc_codegen_cranelift/src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
480480
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
481481
self.0.sess.span_fatal(span, err.to_string())
482482
} else {
483-
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
483+
self.0.sess.span_fatal(span, format!("failed to get layout for `{}`: {}", ty, err))
484484
}
485485
}
486486
}

compiler/rustc_codegen_cranelift/src/unsize.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ fn unsize_ptr<'tcx>(
8888
let src_f = src_layout.field(fx, i);
8989
assert_eq!(src_layout.fields.offset(i).bytes(), 0);
9090
assert_eq!(dst_layout.fields.offset(i).bytes(), 0);
91-
if src_f.is_zst() {
91+
if src_f.is_1zst() {
92+
// We are looking for the one non-1-ZST field; this is not it.
9293
continue;
9394
}
9495
assert_eq!(src_layout.size, src_f.size);
@@ -151,6 +152,7 @@ pub(crate) fn coerce_unsized_into<'tcx>(
151152
let dst_f = dst.place_field(fx, FieldIdx::new(i));
152153

153154
if dst_f.layout().is_zst() {
155+
// No data here, nothing to copy/coerce.
154156
continue;
155157
}
156158

compiler/rustc_codegen_cranelift/src/vtable.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
5151
'descend_newtypes: while !arg.layout().ty.is_unsafe_ptr() && !arg.layout().ty.is_ref() {
5252
for i in 0..arg.layout().fields.count() {
5353
let field = arg.value_field(fx, FieldIdx::new(i));
54-
if !field.layout().is_zst() {
55-
// we found the one non-zero-sized field that is allowed
54+
if !field.layout().is_1zst() {
55+
// we found the one non-1-ZST field that is allowed
5656
// now find *its* non-zero-sized field, or stop if it's a
5757
// pointer
5858
arg = field;

compiler/rustc_codegen_gcc/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_codegen_ssa::traits::{
77
BaseTypeMethods,
88
MiscMethods,
99
};
10+
use rustc_codegen_ssa::errors as ssa_errors;
1011
use rustc_data_structures::base_n;
1112
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1213
use rustc_middle::span_bug;
@@ -479,7 +480,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
479480
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
480481
self.sess().emit_fatal(respan(span, err.into_diagnostic()))
481482
} else {
482-
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
483+
self.tcx.sess.emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
483484
}
484485
}
485486
}

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::value::Value;
1010

1111
use cstr::cstr;
1212
use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
13+
use rustc_codegen_ssa::errors as ssa_errors;
1314
use rustc_codegen_ssa::traits::*;
1415
use rustc_data_structures::base_n;
1516
use rustc_data_structures::fx::FxHashMap;
@@ -1000,7 +1001,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
10001001
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
10011002
self.sess().emit_fatal(Spanned { span, node: err.into_diagnostic() })
10021003
} else {
1003-
span_bug!(span, "failed to get layout for `{ty}`: {err:?}")
1004+
self.tcx.sess.emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
10041005
}
10051006
}
10061007
}

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

Lines changed: 46 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_hir as hir;
1616
use rustc_hir::def_id::DefId;
1717
use rustc_llvm::RustString;
1818
use rustc_middle::bug;
19-
use rustc_middle::mir::coverage::{CodeRegion, CounterId, CoverageKind, ExpressionId, Op, Operand};
19+
use rustc_middle::mir::coverage::{CounterId, CoverageKind};
2020
use rustc_middle::mir::Coverage;
2121
use rustc_middle::ty;
2222
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
@@ -104,144 +104,67 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
104104
fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage) {
105105
let bx = self;
106106

107+
let Some(coverage_context) = bx.coverage_context() else { return };
108+
let mut coverage_map = coverage_context.function_coverage_map.borrow_mut();
109+
let func_coverage = coverage_map
110+
.entry(instance)
111+
.or_insert_with(|| FunctionCoverage::new(bx.tcx(), instance));
112+
107113
let Coverage { kind, code_region } = coverage.clone();
108114
match kind {
109115
CoverageKind::Counter { function_source_hash, id } => {
110-
if bx.set_function_source_hash(instance, function_source_hash) {
111-
// If `set_function_source_hash()` returned true, the coverage map is enabled,
112-
// so continue adding the counter.
113-
if let Some(code_region) = code_region {
114-
// Note: Some counters do not have code regions, but may still be referenced
115-
// from expressions. In that case, don't add the counter to the coverage map,
116-
// but do inject the counter intrinsic.
117-
bx.add_coverage_counter(instance, id, code_region);
118-
}
119-
120-
let coverageinfo = bx.tcx().coverageinfo(instance.def);
121-
122-
let fn_name = bx.get_pgo_func_name_var(instance);
123-
let hash = bx.const_u64(function_source_hash);
124-
let num_counters = bx.const_u32(coverageinfo.num_counters);
125-
let index = bx.const_u32(id.as_u32());
116+
debug!(
117+
"ensuring function source hash is set for instance={:?}; function_source_hash={}",
118+
instance, function_source_hash,
119+
);
120+
func_coverage.set_function_source_hash(function_source_hash);
121+
122+
if let Some(code_region) = code_region {
123+
// Note: Some counters do not have code regions, but may still be referenced
124+
// from expressions. In that case, don't add the counter to the coverage map,
125+
// but do inject the counter intrinsic.
126126
debug!(
127-
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
128-
fn_name, hash, num_counters, index,
127+
"adding counter to coverage_map: instance={:?}, id={:?}, region={:?}",
128+
instance, id, code_region,
129129
);
130-
bx.instrprof_increment(fn_name, hash, num_counters, index);
130+
func_coverage.add_counter(id, code_region);
131131
}
132+
// We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,
133+
// as that needs an exclusive borrow.
134+
drop(coverage_map);
135+
136+
let coverageinfo = bx.tcx().coverageinfo(instance.def);
137+
138+
let fn_name = bx.get_pgo_func_name_var(instance);
139+
let hash = bx.const_u64(function_source_hash);
140+
let num_counters = bx.const_u32(coverageinfo.num_counters);
141+
let index = bx.const_u32(id.as_u32());
142+
debug!(
143+
"codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})",
144+
fn_name, hash, num_counters, index,
145+
);
146+
bx.instrprof_increment(fn_name, hash, num_counters, index);
132147
}
133148
CoverageKind::Expression { id, lhs, op, rhs } => {
134-
bx.add_coverage_counter_expression(instance, id, lhs, op, rhs, code_region);
149+
debug!(
150+
"adding counter expression to coverage_map: instance={:?}, id={:?}, {:?} {:?} {:?}; region: {:?}",
151+
instance, id, lhs, op, rhs, code_region,
152+
);
153+
func_coverage.add_counter_expression(id, lhs, op, rhs, code_region);
135154
}
136155
CoverageKind::Unreachable => {
137-
bx.add_coverage_unreachable(
138-
instance,
139-
code_region.expect("unreachable regions always have code regions"),
156+
let code_region =
157+
code_region.expect("unreachable regions always have code regions");
158+
debug!(
159+
"adding unreachable code to coverage_map: instance={:?}, at {:?}",
160+
instance, code_region,
140161
);
162+
func_coverage.add_unreachable_region(code_region);
141163
}
142164
}
143165
}
144166
}
145167

146-
// These methods used to be part of trait `CoverageInfoBuilderMethods`, but
147-
// after moving most coverage code out of SSA they are now just ordinary methods.
148-
impl<'tcx> Builder<'_, '_, 'tcx> {
149-
/// Returns true if the function source hash was added to the coverage map (even if it had
150-
/// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
151-
/// not enabled (a coverage map is not being generated).
152-
fn set_function_source_hash(
153-
&mut self,
154-
instance: Instance<'tcx>,
155-
function_source_hash: u64,
156-
) -> bool {
157-
if let Some(coverage_context) = self.coverage_context() {
158-
debug!(
159-
"ensuring function source hash is set for instance={:?}; function_source_hash={}",
160-
instance, function_source_hash,
161-
);
162-
let mut coverage_map = coverage_context.function_coverage_map.borrow_mut();
163-
coverage_map
164-
.entry(instance)
165-
.or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
166-
.set_function_source_hash(function_source_hash);
167-
true
168-
} else {
169-
false
170-
}
171-
}
172-
173-
/// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage`
174-
/// is not enabled (a coverage map is not being generated).
175-
fn add_coverage_counter(
176-
&mut self,
177-
instance: Instance<'tcx>,
178-
id: CounterId,
179-
region: CodeRegion,
180-
) -> bool {
181-
if let Some(coverage_context) = self.coverage_context() {
182-
debug!(
183-
"adding counter to coverage_map: instance={:?}, id={:?}, region={:?}",
184-
instance, id, region,
185-
);
186-
let mut coverage_map = coverage_context.function_coverage_map.borrow_mut();
187-
coverage_map
188-
.entry(instance)
189-
.or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
190-
.add_counter(id, region);
191-
true
192-
} else {
193-
false
194-
}
195-
}
196-
197-
/// Returns true if the expression was added to the coverage map; false if
198-
/// `-C instrument-coverage` is not enabled (a coverage map is not being generated).
199-
fn add_coverage_counter_expression(
200-
&mut self,
201-
instance: Instance<'tcx>,
202-
id: ExpressionId,
203-
lhs: Operand,
204-
op: Op,
205-
rhs: Operand,
206-
region: Option<CodeRegion>,
207-
) -> bool {
208-
if let Some(coverage_context) = self.coverage_context() {
209-
debug!(
210-
"adding counter expression to coverage_map: instance={:?}, id={:?}, {:?} {:?} {:?}; \
211-
region: {:?}",
212-
instance, id, lhs, op, rhs, region,
213-
);
214-
let mut coverage_map = coverage_context.function_coverage_map.borrow_mut();
215-
coverage_map
216-
.entry(instance)
217-
.or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
218-
.add_counter_expression(id, lhs, op, rhs, region);
219-
true
220-
} else {
221-
false
222-
}
223-
}
224-
225-
/// Returns true if the region was added to the coverage map; false if `-C instrument-coverage`
226-
/// is not enabled (a coverage map is not being generated).
227-
fn add_coverage_unreachable(&mut self, instance: Instance<'tcx>, region: CodeRegion) -> bool {
228-
if let Some(coverage_context) = self.coverage_context() {
229-
debug!(
230-
"adding unreachable code to coverage_map: instance={:?}, at {:?}",
231-
instance, region,
232-
);
233-
let mut coverage_map = coverage_context.function_coverage_map.borrow_mut();
234-
coverage_map
235-
.entry(instance)
236-
.or_insert_with(|| FunctionCoverage::new(self.tcx, instance))
237-
.add_unreachable_region(region);
238-
true
239-
} else {
240-
false
241-
}
242-
}
243-
}
244-
245168
fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance<'tcx> {
246169
let tcx = cx.tcx;
247170

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,9 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
445445
ty::RawPtr(ty::TypeAndMut { ty: pointee_type, .. }) | ty::Ref(_, pointee_type, _) => {
446446
build_pointer_or_reference_di_node(cx, t, pointee_type, unique_type_id)
447447
}
448-
// Box<T, A> may have a non-ZST allocator A. In that case, we
448+
// Box<T, A> may have a non-1-ZST allocator A. In that case, we
449449
// cannot treat Box<T, A> as just an owned alias of `*mut T`.
450-
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
450+
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_1zst() => {
451451
build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
452452
}
453453
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib
3535
codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error}
3636
codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error}
3737
38+
codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err}
39+
3840
codegen_ssa_failed_to_write = failed to write {$path}: {$error}
3941
4042
codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced

0 commit comments

Comments
 (0)