Skip to content

Commit 123632e

Browse files
committed
Auto merge of rust-lang#120290 - fmease:rollup-f87t55u, r=fmease
Rollup of 7 pull requests Successful merges: - rust-lang#119460 (coverage: Never emit improperly-ordered coverage regions) - rust-lang#120062 (llvm: change data layout bug to an error and make it trigger more) - rust-lang#120124 (Split assembly tests for ELF and MachO) - rust-lang#120165 (Switch `NonZero` alias direction.) - rust-lang#120185 (coverage: Don't instrument `#[automatically_derived]` functions) - rust-lang#120265 (Remove no-system-llvm) - rust-lang#120285 (Remove extra # from url in suggestion) r? `@ghost` `@rustbot` modify labels: rollup
2 parents f6ee4bf + 1c10029 commit 123632e

File tree

68 files changed

+391
-374
lines changed

Some content is hidden

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

68 files changed

+391
-374
lines changed

compiler/rustc_codegen_llvm/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ codegen_llvm_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdy
3939
4040
codegen_llvm_lto_proc_macro = lto cannot be used for `proc-macro` crate type without `-Zdylib-lto`
4141
42+
codegen_llvm_mismatch_data_layout =
43+
data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}`
44+
4245
codegen_llvm_missing_features =
4346
add the missing features in a `target_feature` attribute
4447

compiler/rustc_codegen_llvm/src/context.rs

+9-29
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
3434
use smallvec::SmallVec;
3535

3636
use libc::c_uint;
37+
use std::borrow::Borrow;
3738
use std::cell::{Cell, RefCell};
3839
use std::ffi::CStr;
3940
use std::str;
@@ -155,42 +156,21 @@ pub unsafe fn create_module<'ll>(
155156
}
156157

157158
// Ensure the data-layout values hardcoded remain the defaults.
158-
if sess.target.is_builtin {
159-
// tm is disposed by its drop impl
159+
{
160160
let tm = crate::back::write::create_informational_target_machine(tcx.sess);
161161
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
162162

163163
let llvm_data_layout = llvm::LLVMGetDataLayoutStr(llmod);
164164
let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
165165
.expect("got a non-UTF8 data-layout from LLVM");
166166

167-
// Unfortunately LLVM target specs change over time, and right now we
168-
// don't have proper support to work with any more than one
169-
// `data_layout` than the one that is in the rust-lang/rust repo. If
170-
// this compiler is configured against a custom LLVM, we may have a
171-
// differing data layout, even though we should update our own to use
172-
// that one.
173-
//
174-
// As an interim hack, if CFG_LLVM_ROOT is not an empty string then we
175-
// disable this check entirely as we may be configured with something
176-
// that has a different target layout.
177-
//
178-
// Unsure if this will actually cause breakage when rustc is configured
179-
// as such.
180-
//
181-
// FIXME(#34960)
182-
let cfg_llvm_root = option_env!("CFG_LLVM_ROOT").unwrap_or("");
183-
let custom_llvm_used = !cfg_llvm_root.trim().is_empty();
184-
185-
if !custom_llvm_used && target_data_layout != llvm_data_layout {
186-
bug!(
187-
"data-layout for target `{rustc_target}`, `{rustc_layout}`, \
188-
differs from LLVM target's `{llvm_target}` default layout, `{llvm_layout}`",
189-
rustc_target = sess.opts.target_triple,
190-
rustc_layout = target_data_layout,
191-
llvm_target = sess.target.llvm_target,
192-
llvm_layout = llvm_data_layout
193-
);
167+
if target_data_layout != llvm_data_layout {
168+
tcx.dcx().emit_err(crate::errors::MismatchedDataLayout {
169+
rustc_target: sess.opts.target_triple.to_string().as_str(),
170+
rustc_layout: target_data_layout.as_str(),
171+
llvm_target: sess.target.llvm_target.borrow(),
172+
llvm_layout: llvm_data_layout,
173+
});
194174
}
195175
}
196176

compiler/rustc_codegen_llvm/src/errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,12 @@ pub(crate) struct CopyBitcode {
244244
pub struct UnknownCompression {
245245
pub algorithm: &'static str,
246246
}
247+
248+
#[derive(Diagnostic)]
249+
#[diag(codegen_llvm_mismatch_data_layout)]
250+
pub struct MismatchedDataLayout<'a> {
251+
pub rustc_target: &'a str,
252+
pub rustc_layout: &'a str,
253+
pub llvm_target: &'a str,
254+
pub llvm_layout: &'a str,
255+
}

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+29-25
Original file line numberDiff line numberDiff line change
@@ -2140,46 +2140,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21402140
expr_ty: Ty<'tcx>,
21412141
) -> bool {
21422142
let tcx = self.tcx;
2143-
let (adt, unwrap) = match expected.kind() {
2143+
let (adt, substs, unwrap) = match expected.kind() {
21442144
// In case Option<NonZero*> is wanted, but * is provided, suggest calling new
2145-
ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
2146-
// Unwrap option
2147-
let ty::Adt(adt, _) = args.type_at(0).kind() else {
2145+
ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
2146+
let nonzero_type = substs.type_at(0); // Unwrap option type.
2147+
let ty::Adt(adt, substs) = nonzero_type.kind() else {
21482148
return false;
21492149
};
2150-
2151-
(adt, "")
2150+
(adt, substs, "")
21522151
}
2153-
// In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types
2154-
ty::Adt(adt, _) => (adt, ".unwrap()"),
2152+
// In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
2153+
ty::Adt(adt, substs) => (adt, substs, ".unwrap()"),
21552154
_ => return false,
21562155
};
21572156

2158-
let map = [
2159-
(sym::NonZeroU8, tcx.types.u8),
2160-
(sym::NonZeroU16, tcx.types.u16),
2161-
(sym::NonZeroU32, tcx.types.u32),
2162-
(sym::NonZeroU64, tcx.types.u64),
2163-
(sym::NonZeroU128, tcx.types.u128),
2164-
(sym::NonZeroI8, tcx.types.i8),
2165-
(sym::NonZeroI16, tcx.types.i16),
2166-
(sym::NonZeroI32, tcx.types.i32),
2167-
(sym::NonZeroI64, tcx.types.i64),
2168-
(sym::NonZeroI128, tcx.types.i128),
2157+
if !self.tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
2158+
return false;
2159+
}
2160+
2161+
// FIXME: This can be simplified once `NonZero<T>` is stable.
2162+
let coercable_types = [
2163+
("NonZeroU8", tcx.types.u8),
2164+
("NonZeroU16", tcx.types.u16),
2165+
("NonZeroU32", tcx.types.u32),
2166+
("NonZeroU64", tcx.types.u64),
2167+
("NonZeroU128", tcx.types.u128),
2168+
("NonZeroI8", tcx.types.i8),
2169+
("NonZeroI16", tcx.types.i16),
2170+
("NonZeroI32", tcx.types.i32),
2171+
("NonZeroI64", tcx.types.i64),
2172+
("NonZeroI128", tcx.types.i128),
21692173
];
21702174

2171-
let Some((s, _)) = map.iter().find(|&&(s, t)| {
2172-
self.tcx.is_diagnostic_item(s, adt.did()) && self.can_coerce(expr_ty, t)
2175+
let int_type = substs.type_at(0);
2176+
2177+
let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
2178+
if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None }
21732179
}) else {
21742180
return false;
21752181
};
21762182

2177-
let path = self.tcx.def_path_str(adt.non_enum_variant().def_id);
2178-
21792183
err.multipart_suggestion(
2180-
format!("consider calling `{s}::new`"),
2184+
format!("consider calling `{nonzero_alias}::new`"),
21812185
vec![
2182-
(expr.span.shrink_to_lo(), format!("{path}::new(")),
2186+
(expr.span.shrink_to_lo(), format!("{nonzero_alias}::new(")),
21832187
(expr.span.shrink_to_hi(), format!("){unwrap}")),
21842188
],
21852189
Applicability::MaybeIncorrect,

compiler/rustc_mir_transform/src/coverage/mod.rs

+45-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ fn make_code_region(
329329
start_line = source_map.doctest_offset_line(&file.name, start_line);
330330
end_line = source_map.doctest_offset_line(&file.name, end_line);
331331

332-
Some(CodeRegion {
332+
check_code_region(CodeRegion {
333333
file_name,
334334
start_line: start_line as u32,
335335
start_col: start_col as u32,
@@ -338,6 +338,39 @@ fn make_code_region(
338338
})
339339
}
340340

341+
/// If `llvm-cov` sees a code region that is improperly ordered (end < start),
342+
/// it will immediately exit with a fatal error. To prevent that from happening,
343+
/// discard regions that are improperly ordered, or might be interpreted in a
344+
/// way that makes them improperly ordered.
345+
fn check_code_region(code_region: CodeRegion) -> Option<CodeRegion> {
346+
let CodeRegion { file_name: _, start_line, start_col, end_line, end_col } = code_region;
347+
348+
// Line/column coordinates are supposed to be 1-based. If we ever emit
349+
// coordinates of 0, `llvm-cov` might misinterpret them.
350+
let all_nonzero = [start_line, start_col, end_line, end_col].into_iter().all(|x| x != 0);
351+
// Coverage mappings use the high bit of `end_col` to indicate that a
352+
// region is actually a "gap" region, so make sure it's unset.
353+
let end_col_has_high_bit_unset = (end_col & (1 << 31)) == 0;
354+
// If a region is improperly ordered (end < start), `llvm-cov` will exit
355+
// with a fatal error, which is inconvenient for users and hard to debug.
356+
let is_ordered = (start_line, start_col) <= (end_line, end_col);
357+
358+
if all_nonzero && end_col_has_high_bit_unset && is_ordered {
359+
Some(code_region)
360+
} else {
361+
debug!(
362+
?code_region,
363+
?all_nonzero,
364+
?end_col_has_high_bit_unset,
365+
?is_ordered,
366+
"Skipping code region that would be misinterpreted or rejected by LLVM"
367+
);
368+
// If this happens in a debug build, ICE to make it easier to notice.
369+
debug_assert!(false, "Improper code region: {code_region:?}");
370+
None
371+
}
372+
}
373+
341374
fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
342375
// Only instrument functions, methods, and closures (not constants since they are evaluated
343376
// at compile time by Miri).
@@ -351,7 +384,18 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
351384
return false;
352385
}
353386

387+
// Don't instrument functions with `#[automatically_derived]` on their
388+
// enclosing impl block, on the assumption that most users won't care about
389+
// coverage for derived impls.
390+
if let Some(impl_of) = tcx.impl_of_method(def_id.to_def_id())
391+
&& tcx.is_automatically_derived(impl_of)
392+
{
393+
trace!("InstrumentCoverage skipped for {def_id:?} (automatically derived)");
394+
return false;
395+
}
396+
354397
if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_COVERAGE) {
398+
trace!("InstrumentCoverage skipped for {def_id:?} (`#[coverage(off)]`)");
355399
return false;
356400
}
357401

compiler/rustc_span/src/symbol.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -246,17 +246,7 @@ symbols! {
246246
MutexGuard,
247247
N,
248248
NonNull,
249-
NonZeroI128,
250-
NonZeroI16,
251-
NonZeroI32,
252-
NonZeroI64,
253-
NonZeroI8,
254-
NonZeroU128,
255-
NonZeroU16,
256-
NonZeroU32,
257-
NonZeroU64,
258-
NonZeroU8,
259-
NonZeroUsize,
249+
NonZero,
260250
None,
261251
Normal,
262252
Ok,

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3155,7 +3155,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
31553155
} else {
31563156
// FIXME: we may suggest array::repeat instead
31573157
err.help("consider using `core::array::from_fn` to initialize the array");
3158-
err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html# for more information");
3158+
err.help("see https://doc.rust-lang.org/stable/std/array/fn.from_fn.html for more information");
31593159
}
31603160

31613161
if self.tcx.sess.is_nightly_build()

library/core/src/num/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,15 @@ pub use dec2flt::ParseFloatError;
6161
#[stable(feature = "rust1", since = "1.0.0")]
6262
pub use error::ParseIntError;
6363

64-
pub(crate) use nonzero::NonZero;
64+
#[unstable(
65+
feature = "nonzero_internals",
66+
reason = "implementation detail which may disappear or be replaced at any time",
67+
issue = "none"
68+
)]
69+
pub use nonzero::ZeroablePrimitive;
70+
71+
#[unstable(feature = "generic_nonzero", issue = "82363")]
72+
pub use nonzero::NonZero;
6573

6674
#[stable(feature = "nonzero", since = "1.28.0")]
6775
pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};

library/core/src/num/nonzero.rs

+30-19
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::cmp::Ordering;
44
use crate::fmt;
55
use crate::hash::{Hash, Hasher};
6-
use crate::marker::StructuralPartialEq;
6+
use crate::marker::{StructuralEq, StructuralPartialEq};
77
use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
88
use crate::str::FromStr;
99

@@ -30,9 +30,7 @@ mod private {
3030
issue = "none"
3131
)]
3232
#[const_trait]
33-
pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {
34-
type NonZero;
35-
}
33+
pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {}
3634

3735
macro_rules! impl_zeroable_primitive {
3836
($NonZero:ident ( $primitive:ty )) => {
@@ -48,9 +46,7 @@ macro_rules! impl_zeroable_primitive {
4846
reason = "implementation detail which may disappear or be replaced at any time",
4947
issue = "none"
5048
)]
51-
impl const ZeroablePrimitive for $primitive {
52-
type NonZero = $NonZero;
53-
}
49+
impl const ZeroablePrimitive for $primitive {}
5450
};
5551
}
5652

@@ -67,12 +63,23 @@ impl_zeroable_primitive!(NonZeroI64(i64));
6763
impl_zeroable_primitive!(NonZeroI128(i128));
6864
impl_zeroable_primitive!(NonZeroIsize(isize));
6965

70-
#[unstable(
71-
feature = "nonzero_internals",
72-
reason = "implementation detail which may disappear or be replaced at any time",
73-
issue = "none"
74-
)]
75-
pub(crate) type NonZero<T> = <T as ZeroablePrimitive>::NonZero;
66+
/// A value that is known not to equal zero.
67+
///
68+
/// This enables some memory layout optimization.
69+
/// For example, `Option<NonZero<u32>>` is the same size as `u32`:
70+
///
71+
/// ```
72+
/// #![feature(generic_nonzero)]
73+
/// use core::mem::size_of;
74+
///
75+
/// assert_eq!(size_of::<Option<core::num::NonZero<u32>>>(), size_of::<u32>());
76+
/// ```
77+
#[unstable(feature = "generic_nonzero", issue = "82363")]
78+
#[repr(transparent)]
79+
#[rustc_layout_scalar_valid_range_start(1)]
80+
#[rustc_nonnull_optimization_guaranteed]
81+
#[rustc_diagnostic_item = "NonZero"]
82+
pub struct NonZero<T: ZeroablePrimitive>(T);
7683

7784
macro_rules! impl_nonzero_fmt {
7885
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
@@ -131,12 +138,7 @@ macro_rules! nonzero_integer {
131138
///
132139
/// [null pointer optimization]: crate::option#representation
133140
#[$stability]
134-
#[derive(Copy, Eq)]
135-
#[repr(transparent)]
136-
#[rustc_layout_scalar_valid_range_start(1)]
137-
#[rustc_nonnull_optimization_guaranteed]
138-
#[rustc_diagnostic_item = stringify!($Ty)]
139-
pub struct $Ty($Int);
141+
pub type $Ty = NonZero<$Int>;
140142

141143
impl $Ty {
142144
/// Creates a non-zero without checking whether the value is non-zero.
@@ -506,6 +508,9 @@ macro_rules! nonzero_integer {
506508
}
507509
}
508510

511+
#[$stability]
512+
impl Copy for $Ty {}
513+
509514
#[$stability]
510515
impl PartialEq for $Ty {
511516
#[inline]
@@ -522,6 +527,12 @@ macro_rules! nonzero_integer {
522527
#[unstable(feature = "structural_match", issue = "31434")]
523528
impl StructuralPartialEq for $Ty {}
524529

530+
#[$stability]
531+
impl Eq for $Ty {}
532+
533+
#[unstable(feature = "structural_match", issue = "31434")]
534+
impl StructuralEq for $Ty {}
535+
525536
#[$stability]
526537
impl PartialOrd for $Ty {
527538
#[inline]

library/std/src/num.rs

+10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ pub use core::num::Wrapping;
1616
#[stable(feature = "rust1", since = "1.0.0")]
1717
pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError};
1818

19+
#[unstable(
20+
feature = "nonzero_internals",
21+
reason = "implementation detail which may disappear or be replaced at any time",
22+
issue = "none"
23+
)]
24+
pub use core::num::ZeroablePrimitive;
25+
26+
#[unstable(feature = "generic_nonzero", issue = "82363")]
27+
pub use core::num::NonZero;
28+
1929
#[stable(feature = "signed_nonzero", since = "1.34.0")]
2030
pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
2131
#[stable(feature = "nonzero", since = "1.28.0")]

0 commit comments

Comments
 (0)