Skip to content

Commit 99768c8

Browse files
committed
Auto merge of #135921 - matthiaskrgr:rollup-5mzn76m, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #134746 (Don't ICE in coerce when autoderef fails to structurally normalize non-WF type in new solver) - #135552 ([AIX] Lint on structs that have a different alignment in AIX's C ABI) - #135779 (CI: free disk on linux arm runner) - #135790 (Update windows-gnu targets to set `DebuginfoKind::DWARF`) - #135879 (fix outdated file path ref in llvm) - #135883 (Remove erroneous `unsafe` in `BTreeSet::upper_bound_mut`) - #135884 (remove implied end of slice) - #135887 (improvements on `build_steps::test` implementation) - #135898 (rustdoc-json-types: Finalize dyn compatibility renaming) r? `@ghost` `@rustbot` modify labels: rollup
2 parents fc0094f + 4b3d7ef commit 99768c8

37 files changed

+669
-94
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,17 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
461461
// to the target type), since that should be the least
462462
// confusing.
463463
let Some(InferOk { value: ty, mut obligations }) = found else {
464-
let err = first_error.expect("coerce_borrowed_pointer had no error");
465-
debug!("coerce_borrowed_pointer: failed with err = {:?}", err);
466-
return Err(err);
464+
if let Some(first_error) = first_error {
465+
debug!("coerce_borrowed_pointer: failed with err = {:?}", first_error);
466+
return Err(first_error);
467+
} else {
468+
// This may happen in the new trait solver since autoderef requires
469+
// the pointee to be structurally normalizable, or else it'll just bail.
470+
// So when we have a type like `&<not well formed>`, then we get no
471+
// autoderef steps (even though there should be at least one). That means
472+
// we get no type mismatches, since the loop above just exits early.
473+
return Err(TypeError::Mismatch);
474+
}
467475
};
468476

469477
if ty == a && mt_a.mutbl.is_not() && autoderef.step_count() == 1 {

compiler/rustc_lint/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,8 @@ lint_unused_result = unused result of type `{$ty}`
972972
973973
lint_use_let_underscore_ignore_suggestion = use `let _ = ...` to ignore the expression or result
974974
975+
lint_uses_power_alignment = repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
976+
975977
lint_variant_size_differences =
976978
enum variant is more than three times larger ({$largest} bytes) than the next largest
977979

compiler/rustc_lint/src/lints.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,10 @@ pub(crate) struct OverflowingLiteral<'a> {
16941694
pub lit: String,
16951695
}
16961696

1697+
#[derive(LintDiagnostic)]
1698+
#[diag(lint_uses_power_alignment)]
1699+
pub(crate) struct UsesPowerAlignment;
1700+
16971701
#[derive(LintDiagnostic)]
16981702
#[diag(lint_unused_comparisons)]
16991703
pub(crate) struct UnusedComparisons;

compiler/rustc_lint/src/types.rs

+129-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use std::iter;
22
use std::ops::ControlFlow;
33

4-
use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, Variants, WrappingRange};
4+
use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, VariantIdx, Variants, WrappingRange};
55
use rustc_data_structures::fx::FxHashSet;
66
use rustc_errors::DiagMessage;
77
use rustc_hir::{Expr, ExprKind, LangItem};
88
use rustc_middle::bug;
99
use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton};
1010
use rustc_middle::ty::{
11-
self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
11+
self, Adt, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
12+
TypeVisitableExt,
1213
};
1314
use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
1415
use rustc_span::def_id::LocalDefId;
@@ -23,7 +24,7 @@ use crate::lints::{
2324
AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad,
2425
AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons,
2526
InvalidNanComparisonsSuggestion, UnpredictableFunctionPointerComparisons,
26-
UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons,
27+
UnpredictableFunctionPointerComparisonsSuggestion, UnusedComparisons, UsesPowerAlignment,
2728
VariantSizeDifferencesDiag,
2829
};
2930
use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};
@@ -727,7 +728,60 @@ declare_lint! {
727728
"proper use of libc types in foreign item definitions"
728729
}
729730

730-
declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS]);
731+
declare_lint! {
732+
/// The `uses_power_alignment` lint detects specific `repr(C)`
733+
/// aggregates on AIX.
734+
/// In its platform C ABI, AIX uses the "power" (as in PowerPC) alignment
735+
/// rule (detailed in https://www.ibm.com/docs/en/xl-c-and-cpp-aix/16.1?topic=data-using-alignment-modes#alignment),
736+
/// which can also be set for XLC by `#pragma align(power)` or
737+
/// `-qalign=power`. Aggregates with a floating-point type as the
738+
/// recursively first field (as in "at offset 0") modify the layout of
739+
/// *subsequent* fields of the associated structs to use an alignment value
740+
/// where the floating-point type is aligned on a 4-byte boundary.
741+
///
742+
/// The power alignment rule for structs needed for C compatibility is
743+
/// unimplementable within `repr(C)` in the compiler without building in
744+
/// handling of references to packed fields and infectious nested layouts,
745+
/// so a warning is produced in these situations.
746+
///
747+
/// ### Example
748+
///
749+
/// ```rust,ignore (fails on non-powerpc64-ibm-aix)
750+
/// #[repr(C)]
751+
/// pub struct Floats {
752+
/// a: f64,
753+
/// b: u8,
754+
/// c: f64,
755+
/// }
756+
/// ```
757+
///
758+
/// This will produce:
759+
///
760+
/// ```text
761+
/// warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type
762+
/// --> <source>:5:3
763+
/// |
764+
/// 5 | c: f64,
765+
/// | ^^^^^^
766+
/// |
767+
/// = note: `#[warn(uses_power_alignment)]` on by default
768+
/// ```
769+
///
770+
/// ### Explanation
771+
///
772+
/// The power alignment rule specifies that the above struct has the
773+
/// following alignment:
774+
/// - offset_of!(Floats, a) == 0
775+
/// - offset_of!(Floats, b) == 8
776+
/// - offset_of!(Floats, c) == 12
777+
/// However, rust currently aligns `c` at offset_of!(Floats, c) == 16.
778+
/// Thus, a warning should be produced for the above struct in this case.
779+
USES_POWER_ALIGNMENT,
780+
Warn,
781+
"Structs do not follow the power alignment rule under repr(C)"
782+
}
783+
784+
declare_lint_pass!(ImproperCTypesDefinitions => [IMPROPER_CTYPES_DEFINITIONS, USES_POWER_ALIGNMENT]);
731785

732786
#[derive(Clone, Copy)]
733787
pub(crate) enum CItemKind {
@@ -1539,6 +1593,71 @@ impl ImproperCTypesDefinitions {
15391593
vis.check_type_for_ffi_and_report_errors(span, fn_ptr_ty, true, false);
15401594
}
15411595
}
1596+
1597+
fn check_arg_for_power_alignment<'tcx>(
1598+
&mut self,
1599+
cx: &LateContext<'tcx>,
1600+
ty: Ty<'tcx>,
1601+
) -> bool {
1602+
// Structs (under repr(C)) follow the power alignment rule if:
1603+
// - the first field of the struct is a floating-point type that
1604+
// is greater than 4-bytes, or
1605+
// - the first field of the struct is an aggregate whose
1606+
// recursively first field is a floating-point type greater than
1607+
// 4 bytes.
1608+
if cx.tcx.sess.target.os != "aix" {
1609+
return false;
1610+
}
1611+
if ty.is_floating_point() && ty.primitive_size(cx.tcx).bytes() > 4 {
1612+
return true;
1613+
} else if let Adt(adt_def, _) = ty.kind()
1614+
&& adt_def.is_struct()
1615+
{
1616+
let struct_variant = adt_def.variant(VariantIdx::ZERO);
1617+
// Within a nested struct, all fields are examined to correctly
1618+
// report if any fields after the nested struct within the
1619+
// original struct are misaligned.
1620+
for struct_field in &struct_variant.fields {
1621+
let field_ty = cx.tcx.type_of(struct_field.did).instantiate_identity();
1622+
if self.check_arg_for_power_alignment(cx, field_ty) {
1623+
return true;
1624+
}
1625+
}
1626+
}
1627+
return false;
1628+
}
1629+
1630+
fn check_struct_for_power_alignment<'tcx>(
1631+
&mut self,
1632+
cx: &LateContext<'tcx>,
1633+
item: &'tcx hir::Item<'tcx>,
1634+
) {
1635+
let adt_def = cx.tcx.adt_def(item.owner_id.to_def_id());
1636+
if adt_def.repr().c()
1637+
&& !adt_def.repr().packed()
1638+
&& cx.tcx.sess.target.os == "aix"
1639+
&& !adt_def.all_fields().next().is_none()
1640+
{
1641+
let struct_variant_data = item.expect_struct().0;
1642+
for (index, ..) in struct_variant_data.fields().iter().enumerate() {
1643+
// Struct fields (after the first field) are checked for the
1644+
// power alignment rule, as fields after the first are likely
1645+
// to be the fields that are misaligned.
1646+
if index != 0 {
1647+
let first_field_def = struct_variant_data.fields()[index];
1648+
let def_id = first_field_def.def_id;
1649+
let ty = cx.tcx.type_of(def_id).instantiate_identity();
1650+
if self.check_arg_for_power_alignment(cx, ty) {
1651+
cx.emit_span_lint(
1652+
USES_POWER_ALIGNMENT,
1653+
first_field_def.span,
1654+
UsesPowerAlignment,
1655+
);
1656+
}
1657+
}
1658+
}
1659+
}
1660+
}
15421661
}
15431662

15441663
/// `ImproperCTypesDefinitions` checks items outside of foreign items (e.g. stuff that isn't in
@@ -1562,8 +1681,13 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
15621681
}
15631682
// See `check_fn`..
15641683
hir::ItemKind::Fn { .. } => {}
1684+
// Structs are checked based on if they follow the power alignment
1685+
// rule (under repr(C)).
1686+
hir::ItemKind::Struct(..) => {
1687+
self.check_struct_for_power_alignment(cx, item);
1688+
}
15651689
// See `check_field_def`..
1566-
hir::ItemKind::Union(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) => {}
1690+
hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) => {}
15671691
// Doesn't define something that can contain a external type to be checked.
15681692
hir::ItemKind::Impl(..)
15691693
| hir::ItemKind::TraitAlias(..)

compiler/rustc_parse_format/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ impl<'a> Parser<'a> {
545545
}
546546
}
547547
}
548-
&self.input[start..self.input.len()]
548+
&self.input[start..]
549549
}
550550

551551
/// Parses an `Argument` structure, or what's contained within braces inside the format string.

compiler/rustc_target/src/spec/base/windows_gnu.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ pub(crate) fn opts() -> TargetOptions {
9797
emit_debug_gdb_scripts: false,
9898
requires_uwtable: true,
9999
eh_frame_header: false,
100+
debuginfo_kind: DebuginfoKind::Dwarf,
100101
// FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
101102
// output DWO, despite using DWARF, doesn't use ELF..
102-
debuginfo_kind: DebuginfoKind::Pdb,
103103
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
104104
..Default::default()
105105
}

compiler/rustc_target/src/spec/base/windows_gnullvm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ pub(crate) fn opts() -> TargetOptions {
4444
has_thread_local: true,
4545
crt_static_allows_dylibs: true,
4646
crt_static_respected: true,
47+
debuginfo_kind: DebuginfoKind::Dwarf,
4748
// FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
4849
// output DWO, despite using DWARF, doesn't use ELF..
49-
debuginfo_kind: DebuginfoKind::Pdb,
5050
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
5151
..Default::default()
5252
}

library/alloc/src/collections/btree/set.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1442,20 +1442,20 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
14421442
///
14431443
/// let mut set = BTreeSet::from([1, 2, 3, 4]);
14441444
///
1445-
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Included(&3)) };
1445+
/// let mut cursor = set.upper_bound_mut(Bound::Included(&3));
14461446
/// assert_eq!(cursor.peek_prev(), Some(&3));
14471447
/// assert_eq!(cursor.peek_next(), Some(&4));
14481448
///
1449-
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Excluded(&3)) };
1449+
/// let mut cursor = set.upper_bound_mut(Bound::Excluded(&3));
14501450
/// assert_eq!(cursor.peek_prev(), Some(&2));
14511451
/// assert_eq!(cursor.peek_next(), Some(&3));
14521452
///
1453-
/// let mut cursor = unsafe { set.upper_bound_mut(Bound::Unbounded) };
1453+
/// let mut cursor = set.upper_bound_mut(Bound::Unbounded);
14541454
/// assert_eq!(cursor.peek_prev(), Some(&4));
14551455
/// assert_eq!(cursor.peek_next(), None);
14561456
/// ```
14571457
#[unstable(feature = "btree_cursors", issue = "107540")]
1458-
pub unsafe fn upper_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
1458+
pub fn upper_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
14591459
where
14601460
T: Borrow<Q> + Ord,
14611461
Q: Ord,

src/bootstrap/src/core/build_steps/llvm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,7 @@ impl Step for CrtBeginEnd {
13381338
.file(crtbegin_src)
13391339
.file(crtend_src);
13401340

1341-
// Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt
1341+
// Those flags are defined in src/llvm-project/compiler-rt/lib/builtins/CMakeLists.txt
13421342
// Currently only consumer of those objects is musl, which use .init_array/.fini_array
13431343
// instead of .ctors/.dtors
13441344
cfg.flag("-std=c11")

0 commit comments

Comments
 (0)