Skip to content

Commit b69e089

Browse files
committed
Auto merge of #159166 - jhpratt:rollup-l3XyKzC, r=jhpratt
Rollup of 3 pull requests Successful merges: - #159125 (`mut` restriction lowering) - #159154 (compiler: redescribe llvmlike_vector_align as rust_vector_align) - #159157 (Better comment the struct used by `{read,write}_unaligned`) Failed merges: - #158732 (Apply MCP 1003 and move diagnostics.rs into its own module)
2 parents be8e824 + a768871 commit b69e089

20 files changed

Lines changed: 448 additions & 58 deletions

File tree

compiler/rustc_abi/src/callconv/reg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl Reg {
6969
128 => dl.f128_align,
7070
_ => panic!("unsupported float: {self:?}"),
7171
},
72-
RegKind::Vector { .. } => dl.llvmlike_vector_align(self.size),
72+
RegKind::Vector { .. } => dl.rust_vector_align(self.size),
7373
}
7474
}
7575
}

compiler/rustc_abi/src/layout.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,7 +1514,7 @@ where
15141514
BackendRepr::SimdScalableVector { element, count, number_of_vectors },
15151515
size.checked_mul(number_of_vectors.0 as u64, dl)
15161516
.ok_or_else(|| LayoutCalculatorError::SizeOverflow)?,
1517-
dl.llvmlike_vector_align(size),
1517+
dl.rust_vector_align(size),
15181518
),
15191519
// Non-power-of-two vectors have padding up to the next power-of-two.
15201520
// If we're a packed repr, remove the padding while keeping the alignment as close
@@ -1523,7 +1523,7 @@ where
15231523
(BackendRepr::Memory { sized: true }, size, Align::max_aligned_factor(size))
15241524
}
15251525
SimdVectorKind::PackedFixed | SimdVectorKind::Fixed => {
1526-
(BackendRepr::SimdVector { element, count }, size, dl.llvmlike_vector_align(size))
1526+
(BackendRepr::SimdVector { element, count }, size, dl.rust_vector_align(size))
15271527
}
15281528
};
15291529
let size = size.align_to(align);

compiler/rustc_abi/src/lib.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -658,17 +658,25 @@ impl TargetDataLayout {
658658

659659
/// psABI-mandated alignment for a vector type, if any
660660
#[inline]
661-
fn cabi_vector_align(&self, vec_size: Size) -> Option<Align> {
661+
fn c_vector_align(&self, vec_size: Size) -> Option<Align> {
662662
self.vector_align
663663
.iter()
664664
.find(|(size, _align)| *size == vec_size)
665665
.map(|(_size, align)| *align)
666666
}
667667

668-
/// an alignment resembling the one LLVM would pick for a vector
668+
/// Rust-assigned alignment of any vector type
669+
///
670+
/// When the shape of a vector matches that in a C psABI, we *must* agree when performing FFI.
671+
/// This currently answers correctly for C compatibility purposes as it is a useful default.
672+
/// Otherwise this choice is arbitrary, as vector types do not necessarily match hardware so
673+
/// this can conjure "imaginary" answers that just happen to be convenient for us.
674+
///
675+
/// Importantly, Rust vector alignment is not required to be monotonic between vector sizes,
676+
/// even though it currently is.
669677
#[inline]
670-
pub fn llvmlike_vector_align(&self, vec_size: Size) -> Align {
671-
self.cabi_vector_align(vec_size)
678+
pub fn rust_vector_align(&self, vec_size: Size) -> Align {
679+
self.c_vector_align(vec_size)
672680
.unwrap_or(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap())
673681
}
674682

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
897897
None => Ident::new(sym::integer(index), self.lower_span(f.span)),
898898
},
899899
vis_span: self.lower_span(f.vis.span),
900+
mut_restriction: self.lower_mut_restriction(&f.mut_restriction),
900901
default: f
901902
.default
902903
.as_ref()
@@ -1792,11 +1793,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
17921793
}
17931794
}
17941795

1795-
pub(super) fn lower_impl_restriction(
1796-
&mut self,
1797-
r: &ImplRestriction,
1798-
) -> &'hir hir::ImplRestriction<'hir> {
1799-
let kind = match &r.kind {
1796+
fn lower_restriction_kind(&mut self, kind: &RestrictionKind) -> hir::RestrictionKind<'hir> {
1797+
match kind {
18001798
RestrictionKind::Unrestricted => hir::RestrictionKind::Unrestricted,
18011799
RestrictionKind::Restricted { path, id, shorthand: _ } => {
18021800
let res = self.get_partial_res(*id);
@@ -1820,10 +1818,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
18201818
hir::RestrictionKind::Unrestricted
18211819
}
18221820
}
1823-
};
1821+
}
1822+
}
1823+
1824+
pub(super) fn lower_impl_restriction(
1825+
&mut self,
1826+
r: &ImplRestriction,
1827+
) -> &'hir hir::ImplRestriction<'hir> {
1828+
let kind = self.lower_restriction_kind(&r.kind);
18241829
self.arena.alloc(hir::ImplRestriction { kind, span: self.lower_span(r.span) })
18251830
}
18261831

1832+
pub(super) fn lower_mut_restriction(
1833+
&mut self,
1834+
r: &MutRestriction,
1835+
) -> &'hir hir::MutRestriction<'hir> {
1836+
let kind = self.lower_restriction_kind(&r.kind);
1837+
self.arena.alloc(hir::MutRestriction { kind, span: self.lower_span(r.span) })
1838+
}
1839+
18271840
/// Return the pair of the lowered `generics` as `hir::Generics` and the evaluation of `f` with
18281841
/// the carried impl trait definitions and bounds.
18291842
#[instrument(level = "debug", skip(self, f))]

compiler/rustc_hir/src/hir.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4498,6 +4498,7 @@ pub struct PolyTraitRef<'hir> {
44984498
pub struct FieldDef<'hir> {
44994499
pub span: Span,
45004500
pub vis_span: Span,
4501+
pub mut_restriction: &'hir MutRestriction<'hir>,
45014502
pub ident: Ident,
45024503
#[stable_hash(ignore)]
45034504
pub hir_id: HirId,
@@ -4755,6 +4756,12 @@ pub struct ImplRestriction<'hir> {
47554756
pub span: Span,
47564757
}
47574758

4759+
#[derive(Debug, Clone, Copy, StableHash)]
4760+
pub struct MutRestriction<'hir> {
4761+
pub kind: RestrictionKind<'hir>,
4762+
pub span: Span,
4763+
}
4764+
47584765
#[derive(Debug, Clone, Copy, StableHash)]
47594766
pub enum RestrictionKind<'hir> {
47604767
/// The restriction does not affect the item.

compiler/rustc_hir/src/intravisit.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1405,8 +1405,21 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(
14051405

14061406
pub fn walk_field_def<'v, V: Visitor<'v>>(
14071407
visitor: &mut V,
1408-
FieldDef { hir_id, ident, ty, default, span: _, vis_span: _, def_id: _, safety: _ }: &'v FieldDef<'v>,
1408+
FieldDef {
1409+
hir_id,
1410+
ident,
1411+
ty,
1412+
default,
1413+
span: _,
1414+
vis_span: _,
1415+
mut_restriction,
1416+
def_id: _,
1417+
safety: _,
1418+
}: &'v FieldDef<'v>,
14091419
) -> V::Result {
1420+
if let RestrictionKind::Restricted(path) = mut_restriction.kind {
1421+
walk_list!(visitor, visit_path_segment, path.segments);
1422+
}
14101423
try_visit!(visitor.visit_id(*hir_id));
14111424
try_visit!(visitor.visit_ident(*ident));
14121425
visit_opt!(visitor, visit_anon_const, default);

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ impl<'a> State<'a> {
901901
self.commasep(Inconsistent, struct_def.fields(), |s, field| {
902902
s.maybe_print_comment(field.span.lo());
903903
s.print_attrs(s.attrs(field.hir_id));
904+
s.print_mut_restriction(field.mut_restriction);
904905
s.print_type(field.ty);
905906
});
906907
self.pclose();
@@ -922,6 +923,7 @@ impl<'a> State<'a> {
922923
self.hardbreak_if_not_bol();
923924
self.maybe_print_comment(field.span.lo());
924925
self.print_attrs(self.attrs(field.hir_id));
926+
self.print_mut_restriction(field.mut_restriction);
925927
self.print_ident(field.ident);
926928
self.word_nbsp(":");
927929
self.print_type(field.ty);
@@ -2655,17 +2657,29 @@ impl<'a> State<'a> {
26552657
}
26562658
}
26572659

2658-
fn print_impl_restriction(&mut self, r: &hir::ImplRestriction<'_>) {
2659-
match r.kind {
2660+
fn print_restriction<S: Into<std::borrow::Cow<'static, str>>>(
2661+
&mut self,
2662+
k: &hir::RestrictionKind<'_>,
2663+
prefix: S,
2664+
) {
2665+
match k {
26602666
hir::RestrictionKind::Unrestricted => {}
26612667
hir::RestrictionKind::Restricted(path) => {
2662-
self.word("impl(");
2663-
self.word_nbsp("in");
2668+
self.word(prefix.into());
2669+
self.word_nbsp("(in");
26642670
self.print_path(path, false);
2665-
self.word(")");
2671+
self.word_nbsp(")");
26662672
}
26672673
}
26682674
}
2675+
2676+
fn print_mut_restriction(&mut self, r: &hir::MutRestriction<'_>) {
2677+
self.print_restriction(&r.kind, "mut");
2678+
}
2679+
2680+
fn print_impl_restriction(&mut self, r: &hir::ImplRestriction<'_>) {
2681+
self.print_restriction(&r.kind, "impl");
2682+
}
26692683
}
26702684

26712685
/// Does this expression require a semicolon to be treated

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_macros::{Diagnostic, Subdiagnostic};
88
use rustc_span::{Ident, Span, Spanned, Symbol};
99

1010
use crate::Res;
11-
use crate::late::PatternSource;
11+
use crate::late::{PatternSource, ResolvingRestrictionKind};
1212

1313
#[derive(Diagnostic)]
1414
#[diag("can't use {$is_self ->
@@ -546,8 +546,17 @@ pub(crate) struct ExpectedModuleFound {
546546
pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);
547547

548548
#[derive(Diagnostic)]
549-
#[diag("trait implementation can only be restricted to ancestor modules")]
550-
pub(crate) struct RestrictionAncestorOnly(#[primary_span] pub(crate) Span);
549+
#[diag(
550+
"{$kind ->
551+
[impl] trait implementation
552+
*[mut] field mutation
553+
} can only be restricted to ancestor modules"
554+
)]
555+
pub(crate) struct RestrictionAncestorOnly {
556+
#[primary_span]
557+
pub(crate) span: Span,
558+
pub(crate) kind: ResolvingRestrictionKind,
559+
}
551560

552561
#[derive(Diagnostic)]
553562
#[diag("cannot use a tool module through an import")]

compiler/rustc_resolve/src/late.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,23 @@ pub(crate) enum AliasPossibility {
426426
Maybe,
427427
}
428428

429+
/// Whether resolving `impl` or `mut` restriction paths
430+
#[derive(Debug, Clone, Copy)]
431+
pub(crate) enum ResolvingRestrictionKind {
432+
Impl,
433+
Mut,
434+
}
435+
436+
impl IntoDiagArg for ResolvingRestrictionKind {
437+
fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
438+
use std::borrow::Cow;
439+
match self {
440+
ResolvingRestrictionKind::Impl => DiagArgValue::Str(Cow::Borrowed("impl")),
441+
ResolvingRestrictionKind::Mut => DiagArgValue::Str(Cow::Borrowed("mut")),
442+
}
443+
}
444+
}
445+
429446
#[derive(Copy, Clone, Debug)]
430447
pub(crate) enum PathSource<'a, 'ast, 'ra> {
431448
/// Type paths `Path`.
@@ -1489,11 +1506,12 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
14891506
ty,
14901507
is_placeholder: _,
14911508
default,
1492-
mut_restriction: _,
1509+
mut_restriction,
14931510
safety: _,
14941511
} = f;
14951512
walk_list!(self, visit_attribute, attrs);
14961513
try_visit!(self.visit_vis(vis));
1514+
self.resolve_restriction_path(&mut_restriction.kind, ResolvingRestrictionKind::Mut);
14971515
visit_opt!(self, visit_ident, ident);
14981516
try_visit!(self.visit_ty(ty));
14991517
if let Some(v) = &default {
@@ -2864,7 +2882,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
28642882

28652883
ItemKind::Trait(Trait { generics, bounds, items, impl_restriction, .. }) => {
28662884
// resolve paths for `impl` restrictions
2867-
self.resolve_impl_restriction_path(impl_restriction);
2885+
self.resolve_restriction_path(
2886+
&impl_restriction.kind,
2887+
ResolvingRestrictionKind::Impl,
2888+
);
28682889

28692890
// Create a new rib for the trait-wide type parameters.
28702891
self.with_generic_param_rib(
@@ -4480,8 +4501,12 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
44804501
}
44814502
}
44824503

4483-
fn resolve_impl_restriction_path(&mut self, restriction: &'ast ast::ImplRestriction) {
4484-
match &restriction.kind {
4504+
fn resolve_restriction_path(
4505+
&mut self,
4506+
restriction: &'ast ast::RestrictionKind,
4507+
kind: ResolvingRestrictionKind,
4508+
) {
4509+
match &restriction {
44854510
ast::RestrictionKind::Unrestricted => (),
44864511
ast::RestrictionKind::Restricted { path, id, shorthand: _ } => {
44874512
self.smart_resolve_path(*id, &None, path, PathSource::Module);
@@ -4494,7 +4519,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
44944519
) {
44954520
self.r
44964521
.dcx()
4497-
.create_err(crate::diagnostics::RestrictionAncestorOnly(path.span))
4522+
.create_err(crate::diagnostics::RestrictionAncestorOnly {
4523+
span: path.span,
4524+
kind,
4525+
})
44984526
.emit();
44994527
}
45004528
}

library/core/src/ptr/mod.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,22 +1810,22 @@ pub const unsafe fn read<T>(src: *const T) -> T {
18101810
pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
18111811
// Always true thanks to the repr, but to demonstrate
18121812
const {
1813-
assert!(mem::offset_of!(Packed::<T>, 0) == 0);
1814-
assert!(size_of::<T>() == size_of::<Packed<T>>());
1813+
assert!(mem::offset_of!(Unaligned::<T>, 0) == 0);
1814+
assert!(size_of::<T>() == size_of::<Unaligned<T>>());
18151815
}
18161816

1817-
let src = src.cast::<Packed<T>>();
1817+
let src = src.cast::<Unaligned<T>>();
18181818
// SAFETY: the caller must guarantee that `src` is valid for reads.
1819-
// Reading it as `Packed<T>` instead of `T` reads those same bytes because
1819+
// Reading it as `Unaligned<T>` instead of `T` reads those same bytes because
18201820
// it's the same size (thus zero offset), but with alignment 1 instead.
18211821
//
18221822
// Similarly, because it's the same bytes it's sound to transmute from the
1823-
// `Packed<T>` to `T`. Transmute is a value-based (not a place-based)
1823+
// `Unaligned<T>` to `T`. Transmute is a value-based (not a place-based)
18241824
// operation that doesn't care about alignment.
18251825
unsafe {
1826-
let packed = read(src);
1826+
let unaligned = read(src);
18271827
// Can't just destructure because that's not allowed in const fn
1828-
mem::transmute_neo(packed)
1828+
mem::transmute_neo(unaligned)
18291829
}
18301830
}
18311831

@@ -2020,14 +2020,14 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
20202020
pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
20212021
// Always true thanks to the repr, but to demonstrate
20222022
const {
2023-
assert!(mem::offset_of!(Packed::<T>, 0) == 0);
2024-
assert!(size_of::<T>() == size_of::<Packed<T>>());
2023+
assert!(mem::offset_of!(Unaligned::<T>, 0) == 0);
2024+
assert!(size_of::<T>() == size_of::<Unaligned<T>>());
20252025
}
20262026

2027-
let dst = dst.cast::<Packed<T>>();
2028-
let src = Packed(src);
2027+
let dst = dst.cast::<Unaligned<T>>();
2028+
let src = Unaligned(src);
20292029
// SAFETY: the caller must guarantee that `dst` is valid for writes.
2030-
// Writing it as `Packed<T>` instead of `T` writes those same bytes because
2030+
// Writing it as `Unaligned<T>` instead of `T` writes those same bytes because
20312031
// it's the same size (thus zero offset), but with alignment 1 instead.
20322032
unsafe { write(dst, src) }
20332033
}
@@ -2828,5 +2828,7 @@ pub macro addr_of_mut($place:expr) {
28282828
&raw mut $place
28292829
}
28302830

2831-
#[repr(C, packed)]
2832-
struct Packed<T>(T);
2831+
/// Used in [`read_unaligned`] and [`write_unaligned`] to load and store `T`
2832+
/// with alignment 1 rather than its usual `align_of::<T>()` alignment.
2833+
#[repr(Rust, packed)]
2834+
struct Unaligned<T>(T);

0 commit comments

Comments
 (0)