Skip to content

Commit 52036f5

Browse files
committed
Auto merge of #2928 - oli-obk:rustup, r=oli-obk
Rustup
2 parents 15a6362 + 24595f5 commit 52036f5

File tree

861 files changed

+18108
-2829
lines changed

Some content is hidden

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

861 files changed

+18108
-2829
lines changed

Cargo.lock

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ dependencies = [
6565
"rand_xorshift",
6666
]
6767

68+
[[package]]
69+
name = "allocator-api2"
70+
version = "0.2.14"
71+
source = "registry+https://github.com/rust-lang/crates.io-index"
72+
checksum = "c4f263788a35611fba42eb41ff811c5d0360c58b97402570312a350736e2542e"
73+
6874
[[package]]
6975
name = "ammonia"
7076
version = "3.2.0"
@@ -1522,6 +1528,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
15221528
checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038"
15231529
dependencies = [
15241530
"ahash 0.8.2",
1531+
]
1532+
1533+
[[package]]
1534+
name = "hashbrown"
1535+
version = "0.14.0"
1536+
source = "registry+https://github.com/rust-lang/crates.io-index"
1537+
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
1538+
dependencies = [
1539+
"allocator-api2",
15251540
"compiler_builtins",
15261541
"rustc-std-workspace-alloc",
15271542
"rustc-std-workspace-core",
@@ -4633,7 +4648,7 @@ dependencies = [
46334648
"core",
46344649
"dlmalloc",
46354650
"fortanix-sgx-abi",
4636-
"hashbrown 0.13.1",
4651+
"hashbrown 0.14.0",
46374652
"hermit-abi 0.3.0",
46384653
"libc",
46394654
"miniz_oxide",

compiler/rustc_abi/src/layout.rs

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -57,48 +57,54 @@ pub trait LayoutCalculator {
5757
// run and bias niches to the right and then check which one is closer to one of the struct's
5858
// edges.
5959
if let Some(layout) = &layout {
60-
if let Some(niche) = layout.largest_niche {
61-
let head_space = niche.offset.bytes();
62-
let niche_length = niche.value.size(dl).bytes();
63-
let tail_space = layout.size.bytes() - head_space - niche_length;
64-
65-
// This may end up doing redundant work if the niche is already in the last field
66-
// (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get
67-
// the unpadded size so we try anyway.
68-
if fields.len() > 1 && head_space != 0 && tail_space > 0 {
69-
let alt_layout = univariant(self, dl, fields, repr, kind, NicheBias::End)
70-
.expect("alt layout should always work");
71-
let niche = alt_layout
72-
.largest_niche
73-
.expect("alt layout should have a niche like the regular one");
74-
let alt_head_space = niche.offset.bytes();
75-
let alt_niche_len = niche.value.size(dl).bytes();
76-
let alt_tail_space = alt_layout.size.bytes() - alt_head_space - alt_niche_len;
77-
78-
debug_assert_eq!(layout.size.bytes(), alt_layout.size.bytes());
79-
80-
let prefer_alt_layout =
81-
alt_head_space > head_space && alt_head_space > tail_space;
82-
83-
debug!(
84-
"sz: {}, default_niche_at: {}+{}, default_tail_space: {}, alt_niche_at/head_space: {}+{}, alt_tail: {}, num_fields: {}, better: {}\n\
85-
layout: {}\n\
86-
alt_layout: {}\n",
87-
layout.size.bytes(),
88-
head_space,
89-
niche_length,
90-
tail_space,
91-
alt_head_space,
92-
alt_niche_len,
93-
alt_tail_space,
94-
layout.fields.count(),
95-
prefer_alt_layout,
96-
format_field_niches(&layout, &fields, &dl),
97-
format_field_niches(&alt_layout, &fields, &dl),
98-
);
99-
100-
if prefer_alt_layout {
101-
return Some(alt_layout);
60+
// Don't try to calculate an end-biased layout for unsizable structs,
61+
// otherwise we could end up with different layouts for
62+
// Foo<Type> and Foo<dyn Trait> which would break unsizing
63+
if !matches!(kind, StructKind::MaybeUnsized) {
64+
if let Some(niche) = layout.largest_niche {
65+
let head_space = niche.offset.bytes();
66+
let niche_length = niche.value.size(dl).bytes();
67+
let tail_space = layout.size.bytes() - head_space - niche_length;
68+
69+
// This may end up doing redundant work if the niche is already in the last field
70+
// (e.g. a trailing bool) and there is tail padding. But it's non-trivial to get
71+
// the unpadded size so we try anyway.
72+
if fields.len() > 1 && head_space != 0 && tail_space > 0 {
73+
let alt_layout = univariant(self, dl, fields, repr, kind, NicheBias::End)
74+
.expect("alt layout should always work");
75+
let niche = alt_layout
76+
.largest_niche
77+
.expect("alt layout should have a niche like the regular one");
78+
let alt_head_space = niche.offset.bytes();
79+
let alt_niche_len = niche.value.size(dl).bytes();
80+
let alt_tail_space =
81+
alt_layout.size.bytes() - alt_head_space - alt_niche_len;
82+
83+
debug_assert_eq!(layout.size.bytes(), alt_layout.size.bytes());
84+
85+
let prefer_alt_layout =
86+
alt_head_space > head_space && alt_head_space > tail_space;
87+
88+
debug!(
89+
"sz: {}, default_niche_at: {}+{}, default_tail_space: {}, alt_niche_at/head_space: {}+{}, alt_tail: {}, num_fields: {}, better: {}\n\
90+
layout: {}\n\
91+
alt_layout: {}\n",
92+
layout.size.bytes(),
93+
head_space,
94+
niche_length,
95+
tail_space,
96+
alt_head_space,
97+
alt_niche_len,
98+
alt_tail_space,
99+
layout.fields.count(),
100+
prefer_alt_layout,
101+
format_field_niches(&layout, &fields, &dl),
102+
format_field_niches(&alt_layout, &fields, &dl),
103+
);
104+
105+
if prefer_alt_layout {
106+
return Some(alt_layout);
107+
}
102108
}
103109
}
104110
}
@@ -828,6 +834,7 @@ fn univariant(
828834
if optimize && fields.len() > 1 {
829835
let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
830836
let optimizing = &mut inverse_memory_index.raw[..end];
837+
let fields_excluding_tail = &fields.raw[..end];
831838

832839
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
833840
// the field ordering to try and catch some code making assumptions about layouts
@@ -844,8 +851,11 @@ fn univariant(
844851
}
845852
// Otherwise we just leave things alone and actually optimize the type's fields
846853
} else {
847-
let max_field_align = fields.iter().map(|f| f.align().abi.bytes()).max().unwrap_or(1);
848-
let largest_niche_size = fields
854+
// To allow unsizing `&Foo<Type>` -> `&Foo<dyn Trait>`, the layout of the struct must
855+
// not depend on the layout of the tail.
856+
let max_field_align =
857+
fields_excluding_tail.iter().map(|f| f.align().abi.bytes()).max().unwrap_or(1);
858+
let largest_niche_size = fields_excluding_tail
849859
.iter()
850860
.filter_map(|f| f.largest_niche())
851861
.map(|n| n.available(dl))

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,12 @@ impl<'a> AstValidator<'a> {
364364
self.err_handler().emit_err(errors::BoundInContext { span, ctx });
365365
}
366366

367-
fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
367+
fn check_foreign_ty_genericless(
368+
&self,
369+
generics: &Generics,
370+
before_where_clause: &TyAliasWhereClause,
371+
after_where_clause: &TyAliasWhereClause,
372+
) {
368373
let cannot_have = |span, descr, remove_descr| {
369374
self.err_handler().emit_err(errors::ExternTypesCannotHave {
370375
span,
@@ -378,9 +383,14 @@ impl<'a> AstValidator<'a> {
378383
cannot_have(generics.span, "generic parameters", "generic parameters");
379384
}
380385

381-
if !generics.where_clause.predicates.is_empty() {
382-
cannot_have(where_span, "`where` clauses", "`where` clause");
383-
}
386+
let check_where_clause = |where_clause: &TyAliasWhereClause| {
387+
if let TyAliasWhereClause(true, where_clause_span) = where_clause {
388+
cannot_have(*where_clause_span, "`where` clauses", "`where` clause");
389+
}
390+
};
391+
392+
check_where_clause(before_where_clause);
393+
check_where_clause(after_where_clause);
384394
}
385395

386396
fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
@@ -1039,7 +1049,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10391049
self.check_defaultness(fi.span, *defaultness);
10401050
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
10411051
self.check_type_no_bounds(bounds, "`extern` blocks");
1042-
self.check_foreign_ty_genericless(generics, where_clauses.0.1);
1052+
self.check_foreign_ty_genericless(generics, &where_clauses.0, &where_clauses.1);
10431053
self.check_foreign_item_ascii_only(fi.ident);
10441054
}
10451055
ForeignItemKind::Static(_, _, body) => {

0 commit comments

Comments
 (0)