Skip to content

Commit 57d0690

Browse files
committed
Auto merge of #157031 - GuillaumeGomez:rollup-FbegncN, r=GuillaumeGomez
Rollup of 10 pull requests Successful merges: - #156970 (coverage: Use original HIR info for synthetic by-move coroutine bodies) - #157022 (MIR inlining: allow backends to opt-in to inlining intrinsics) - #157026 (miri subtree update) - #156390 (Constify Iterator-related methods and functions) - #156845 (Clarify "infinite size" in cyclic-type diagnostic refers to the type name) - #156955 (Fix const-eval of shared generic reborrows) - #156973 (Add uwtable annotation to modules when required) - #156985 (Limit the additional DLL to Windows) - #156988 (interpret/validity: properly treat zero-variant enums so that we do not have to check layout.is_uninhabited) - #157002 (std: Fix thread::available_parallelism on Redox targets)
2 parents 77a4fb6 + 7ade8cc commit 57d0690

95 files changed

Lines changed: 1406 additions & 515 deletions

File tree

Some content is hidden

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

compiler/rustc_codegen_cranelift/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ impl CodegenBackend for CraneliftCodegenBackend {
237237
) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>) {
238238
ongoing_codegen.downcast::<driver::aot::OngoingCodegen>().unwrap().join(sess, outputs)
239239
}
240+
241+
fn fallback_intrinsics(&self) -> Vec<Symbol> {
242+
vec![sym::type_id_eq]
243+
}
240244
}
241245

242246
/// Determine if the Cranelift ir verifier should run.

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ use rustc_middle::ty::TyCtxt;
9898
use rustc_middle::util::Providers;
9999
use rustc_session::Session;
100100
use rustc_session::config::{OptLevel, OutputFilenames};
101-
use rustc_span::Symbol;
101+
use rustc_span::{Symbol, sym};
102102
use rustc_target::spec::{Arch, RelocModel};
103103
use tempfile::TempDir;
104104

@@ -311,6 +311,10 @@ impl CodegenBackend for GccCodegenBackend {
311311
fn target_config(&self, sess: &Session) -> TargetConfig {
312312
target_config(sess, &self.target_info)
313313
}
314+
315+
fn fallback_intrinsics(&self) -> Vec<Symbol> {
316+
vec![sym::type_id_eq]
317+
}
314318
}
315319

316320
fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> {

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ pub(crate) fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option<bool>)
165165
// NOTE: We should determine if we even need async unwind tables, as they
166166
// take have more overhead and if we can use sync unwind tables we
167167
// probably should.
168+
//
169+
// Similar logic exists for the per-module uwtable annotation in `context.rs`.
168170
let async_unwind = !use_sync_unwind.unwrap_or(false);
169171
llvm::CreateUWTableAttr(llcx, async_unwind)
170172
}

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,25 @@ pub(crate) unsafe fn create_module<'ll>(
311311
);
312312
}
313313

314+
if sess.must_emit_unwind_tables() {
315+
// This assertion checks that Max is the correct merge behavior.
316+
// Async unwind tables are strictly more useful than sync uwtables.
317+
const {
318+
assert!((llvm::UWTableKind::None as u32) < (llvm::UWTableKind::Sync as u32));
319+
assert!((llvm::UWTableKind::Sync as u32) < (llvm::UWTableKind::Async as u32));
320+
}
321+
322+
llvm::add_module_flag_u32(
323+
llmod,
324+
llvm::ModuleFlagMergeBehavior::Max,
325+
"uwtable",
326+
match sess.opts.unstable_opts.use_sync_unwind {
327+
Some(true) => llvm::UWTableKind::Sync as u32,
328+
Some(false) | None => llvm::UWTableKind::Async as u32,
329+
},
330+
);
331+
}
332+
314333
// Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
315334
if sess.is_sanitizer_kcfi_enabled() {
316335
llvm::add_module_flag_u32(llmod, llvm::ModuleFlagMergeBehavior::Override, "kcfi", 1);

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,14 @@ impl CodegenBackend for LlvmCodegenBackend {
333333
will_not_use_fallback
334334
}
335335

336+
fn fallback_intrinsics(&self) -> Vec<Symbol> {
337+
// `type_id_eq` is a safe choice since *all* backends use the fallback body for that.
338+
// When adding more intrinsics, keep in mind that the distributed standard library
339+
// is compiled with the LLVM backend but might later be included in a project built
340+
// with cranelift or GCC.
341+
vec![sym::type_id_eq]
342+
}
343+
336344
fn target_cpu(&self, sess: &Session) -> String {
337345
crate::llvm_util::target_cpu(sess).to_string()
338346
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,18 @@ pub(crate) enum DLLStorageClass {
240240
DllExport = 2, // Function to be accessible from DLL.
241241
}
242242

243+
/// Must match the layout of `llvm::UWTableKind`.
244+
#[derive(Copy, Clone)]
245+
#[repr(C)]
246+
pub(crate) enum UWTableKind {
247+
/// No unwind table requested
248+
None = 0,
249+
/// "Synchronous" unwind tables
250+
Sync = 1,
251+
/// "Asynchronous" unwind tables (instr precise)
252+
Async = 2,
253+
}
254+
243255
/// Must match the layout of `LLVMRustAttributeKind`.
244256
/// Semantically a subset of the C++ enum llvm::Attribute::AttrKind,
245257
/// though it is not ABI compatible (since it's a C++ enum)

compiler/rustc_codegen_ssa/src/traits/backend.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ pub trait CodegenBackend {
7979
vec![]
8080
}
8181

82+
/// Returns a list of all intrinsics that this backend definitely
83+
/// does *not* replace, which means their fallback bodies can be MIR-inlined.
84+
fn fallback_intrinsics(&self) -> Vec<Symbol> {
85+
vec![]
86+
}
87+
8288
/// Is ThinLTO supported by this backend?
8389
fn thin_lto_supported(&self) -> bool {
8490
true

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
230230
})?;
231231
}
232232

233-
Reborrow(_, _, place) => {
234-
let op = self.eval_place_to_op(place, Some(dest.layout))?;
235-
self.copy_op(&op, &dest)?;
233+
Reborrow(_, mutability, place) => {
234+
let op = self.eval_place_to_op(place, None)?;
235+
if mutability.is_not() {
236+
// Shared generic reborrows use `CoerceShared`: a bitwise copy into a
237+
// distinct same-layout target ADT.
238+
self.copy_op_allow_transmute(&op, &dest)?;
239+
} else {
240+
self.copy_op(&op, &dest)?;
241+
}
236242
}
237243

238244
RawPtr(kind, place) => {

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,16 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
13531353
interp_ok(())
13541354
}
13551355

1356+
#[inline]
1357+
fn visit_variantless(&mut self, val: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
1358+
let ty = val.layout.ty;
1359+
assert!(ty.is_enum(), "encountered non-enum variantless type `{ty}`");
1360+
throw_validation_failure!(
1361+
self.path,
1362+
format!("encountered a value of zero-variant enum `{ty}`")
1363+
);
1364+
}
1365+
13561366
#[inline]
13571367
fn visit_value(&mut self, val: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
13581368
trace!("visit_value: {:?}, {:?}", *val, val.layout);
@@ -1557,23 +1567,14 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
15571567
}
15581568
}
15591569

1560-
// *After* all of this, check further information stored in the layout.
1561-
// On leaf types like `!` or empty enums, this will raise the error.
1562-
// This means that for types wrapping such a type, we won't ever get here, but it's
1563-
// just the simplest way to check for this case.
1564-
//
1565-
// FIXME: We could avoid some redundant checks here. For newtypes wrapping
1566-
// scalars, we do the same check on every "level" (e.g., first we check
1567-
// the fields of MyNewtype, and then we check MyNewType again).
1568-
if val.layout.is_uninhabited() {
1569-
let ty = val.layout.ty;
1570-
throw_validation_failure!(
1571-
self.path,
1572-
format!("encountered a value of uninhabited type `{ty}`")
1573-
);
1574-
}
1570+
// Assert that we checked everything there is to check about this type.
1571+
assert!(
1572+
!val.layout.is_uninhabited(),
1573+
"a value of type `{}` passed validation but that type is uninhabited",
1574+
val.layout.ty
1575+
);
15751576
if cfg!(debug_assertions) {
1576-
// Check that we don't miss any new changes to layout computation in our checks above.
1577+
// Only run expensive checks when debug assertions are enabled.
15771578
match val.layout.backend_repr {
15781579
BackendRepr::Scalar(scalar_layout) => {
15791580
if !scalar_layout.is_uninit_valid() {

compiler/rustc_const_eval/src/interpret/visitor.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
4141
fn visit_box(&mut self, _box_ty: Ty<'tcx>, _v: &Self::V) -> InterpResult<'tcx> {
4242
interp_ok(())
4343
}
44+
/// Visits the given type after it has been found to have no variants.
45+
#[inline(always)]
46+
fn visit_variantless(&mut self, _v: &Self::V) -> InterpResult<'tcx> {
47+
interp_ok(())
48+
}
4449

4550
/// Called each time we recurse down to a field of a "product-like" aggregate
4651
/// (structs, tuples, arrays and the like, but not enums), passing in old (outer)
@@ -193,7 +198,11 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
193198
self.visit_variant(v, idx, &inner)?;
194199
}
195200
// For single-variant layouts, we already did everything there is to do.
196-
Variants::Single { .. } | Variants::Empty => {}
201+
Variants::Single { .. } => {}
202+
// Non-variant layouts need special treatment by the visitor.
203+
Variants::Empty => {
204+
self.visit_variantless(v)?;
205+
}
197206
}
198207

199208
interp_ok(())

0 commit comments

Comments
 (0)