Skip to content

Commit be0e608

Browse files
committed
Auto merge of rust-lang#124769 - fmease:rollup-gwdj5yz, r=fmease
Rollup of 6 pull requests Successful merges: - rust-lang#124146 (Triagebot: Rename `macos` ping group to `apple`) - rust-lang#124742 (Add `rustfmt` cfg to well known cfgs list) - rust-lang#124745 (Implement lldb formattter for "clang encoded" enums (LLDB 18.1+) (v2)) - rust-lang#124747 (Support Result<T, E> across FFI when niche optimization can be used (v2)) - rust-lang#124765 ([rustdoc] Fix bad color for setting cog in ayu theme) - rust-lang#124768 ([resubmission] Meta: Enable the brand new triagebot transfer command) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9c9b568 + 31e2302 commit be0e608

Some content is hidden

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

43 files changed

+1102
-140
lines changed

compiler/rustc_feature/src/unstable.rs

+3
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,9 @@ declare_features! (
579579
(incomplete, repr128, "1.16.0", Some(56071)),
580580
/// Allows `repr(simd)` and importing the various simd intrinsics.
581581
(unstable, repr_simd, "1.4.0", Some(27731)),
582+
/// Allows enums like Result<T, E> to be used across FFI, if T's niche value can
583+
/// be used to describe E or vise-versa.
584+
(unstable, result_ffi_guarantees, "CURRENT_RUSTC_VERSION", Some(110503)),
582585
/// Allows bounding the return type of AFIT/RPITIT.
583586
(incomplete, return_type_notation, "1.70.0", Some(109417)),
584587
/// Allows `extern "rust-cold"`.

compiler/rustc_lint/src/types.rs

+56-13
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,32 @@ fn get_nullable_type<'tcx>(
11011101
})
11021102
}
11031103

1104+
/// A type is niche-optimization candidate iff:
1105+
/// - Is a zero-sized type with alignment 1 (a “1-ZST”).
1106+
/// - Has no fields.
1107+
/// - Does not have the `#[non_exhaustive]` attribute.
1108+
fn is_niche_optimization_candidate<'tcx>(
1109+
tcx: TyCtxt<'tcx>,
1110+
param_env: ty::ParamEnv<'tcx>,
1111+
ty: Ty<'tcx>,
1112+
) -> bool {
1113+
if tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| !layout.is_1zst()) {
1114+
return false;
1115+
}
1116+
1117+
match ty.kind() {
1118+
ty::Adt(ty_def, _) => {
1119+
let non_exhaustive = ty_def.is_variant_list_non_exhaustive();
1120+
let empty = (ty_def.is_struct() && ty_def.all_fields().next().is_none())
1121+
|| (ty_def.is_enum() && ty_def.variants().is_empty());
1122+
1123+
!non_exhaustive && empty
1124+
}
1125+
ty::Tuple(tys) => tys.is_empty(),
1126+
_ => false,
1127+
}
1128+
}
1129+
11041130
/// Check if this enum can be safely exported based on the "nullable pointer optimization". If it
11051131
/// can, return the type that `ty` can be safely converted to, otherwise return `None`.
11061132
/// Currently restricted to function pointers, boxes, references, `core::num::NonZero`,
@@ -1117,6 +1143,22 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
11171143
let field_ty = match &ty_def.variants().raw[..] {
11181144
[var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
11191145
([], [field]) | ([field], []) => field.ty(tcx, args),
1146+
([field1], [field2]) => {
1147+
if !tcx.features().result_ffi_guarantees {
1148+
return None;
1149+
}
1150+
1151+
let ty1 = field1.ty(tcx, args);
1152+
let ty2 = field2.ty(tcx, args);
1153+
1154+
if is_niche_optimization_candidate(tcx, param_env, ty1) {
1155+
ty2
1156+
} else if is_niche_optimization_candidate(tcx, param_env, ty2) {
1157+
ty1
1158+
} else {
1159+
return None;
1160+
}
1161+
}
11201162
_ => return None,
11211163
},
11221164
_ => return None,
@@ -1202,7 +1244,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12021244
args: GenericArgsRef<'tcx>,
12031245
) -> FfiResult<'tcx> {
12041246
use FfiResult::*;
1205-
12061247
let transparent_with_all_zst_fields = if def.repr().transparent() {
12071248
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
12081249
// Transparent newtypes have at most one non-ZST field which needs to be checked..
@@ -1329,27 +1370,29 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
13291370
return FfiSafe;
13301371
}
13311372

1373+
if def.is_variant_list_non_exhaustive() && !def.did().is_local() {
1374+
return FfiUnsafe {
1375+
ty,
1376+
reason: fluent::lint_improper_ctypes_non_exhaustive,
1377+
help: None,
1378+
};
1379+
}
1380+
13321381
// Check for a repr() attribute to specify the size of the
13331382
// discriminant.
13341383
if !def.repr().c() && !def.repr().transparent() && def.repr().int.is_none()
13351384
{
1336-
// Special-case types like `Option<extern fn()>`.
1337-
if repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode)
1338-
.is_none()
1385+
// Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
1386+
if let Some(ty) =
1387+
repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode)
13391388
{
1340-
return FfiUnsafe {
1341-
ty,
1342-
reason: fluent::lint_improper_ctypes_enum_repr_reason,
1343-
help: Some(fluent::lint_improper_ctypes_enum_repr_help),
1344-
};
1389+
return self.check_type_for_ffi(cache, ty);
13451390
}
1346-
}
13471391

1348-
if def.is_variant_list_non_exhaustive() && !def.did().is_local() {
13491392
return FfiUnsafe {
13501393
ty,
1351-
reason: fluent::lint_improper_ctypes_non_exhaustive,
1352-
help: None,
1394+
reason: fluent::lint_improper_ctypes_enum_repr_reason,
1395+
help: Some(fluent::lint_improper_ctypes_enum_repr_help),
13531396
};
13541397
}
13551398

compiler/rustc_session/src/config/cfg.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -262,13 +262,15 @@ impl CheckCfg {
262262

263263
ins!(sym::debug_assertions, no_values);
264264

265-
// These four are never set by rustc, but we set them anyway: they
266-
// should not trigger a lint because `cargo clippy`, `cargo doc`,
267-
// `cargo test` and `cargo miri run` (respectively) can set them.
265+
// These four are never set by rustc, but we set them anyway; they
266+
// should not trigger the lint because `cargo clippy`, `cargo doc`,
267+
// `cargo test`, `cargo miri run` and `cargo fmt` (respectively)
268+
// can set them.
268269
ins!(sym::clippy, no_values);
269270
ins!(sym::doc, no_values);
270271
ins!(sym::doctest, no_values);
271272
ins!(sym::miri, no_values);
273+
ins!(sym::rustfmt, no_values);
272274

273275
ins!(sym::overflow_checks, no_values);
274276

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,7 @@ symbols! {
15111511
require,
15121512
residual,
15131513
result,
1514+
result_ffi_guarantees,
15141515
resume,
15151516
return_position_impl_trait_in_trait,
15161517
return_type_notation,

src/doc/rustc/src/check-cfg.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Those well known names and values follows the same stability as what they refer
7171
Well known names and values checking is always enabled as long as at least one
7272
`--check-cfg` argument is present.
7373
74-
As of `2024-04-06T`, the list of known names is as follows:
74+
As of `2024-05-06T`, the list of known names is as follows:
7575
7676
<!--- See CheckCfg::fill_well_known in compiler/rustc_session/src/config.rs -->
7777
@@ -84,6 +84,7 @@ As of `2024-04-06T`, the list of known names is as follows:
8484
- `panic`
8585
- `proc_macro`
8686
- `relocation_model`
87+
- `rustfmt`
8788
- `sanitize`
8889
- `sanitizer_cfi_generalize_pointers`
8990
- `sanitizer_cfi_normalize_integers`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# `result_ffi_guarantees`
2+
3+
The tracking issue for this feature is: [#110503]
4+
5+
[#110503]: https://github.com/rust-lang/rust/issues/110503
6+
7+
------------------------
8+
9+
This feature adds the possibility of using `Result<T, E>` in FFI if T's niche
10+
value can be used to describe E or vise-versa.
11+
12+
See [RFC 3391] for more information.
13+
14+
[RFC 3391]: https://github.com/rust-lang/rfcs/blob/master/text/3391-result_ffi_guarantees.md

src/etc/lldb_lookup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ def synthetic_lookup(valobj, dict):
8686
return synthetic_lookup(valobj.GetChildAtIndex(discriminant), dict)
8787
if rust_type == RustType.SINGLETON_ENUM:
8888
return synthetic_lookup(valobj.GetChildAtIndex(0), dict)
89-
89+
if rust_type == RustType.ENUM:
90+
return ClangEncodedEnumProvider(valobj, dict)
9091
if rust_type == RustType.STD_VEC:
9192
return StdVecSyntheticProvider(valobj, dict)
9293
if rust_type == RustType.STD_VEC_DEQUE:

src/etc/lldb_providers.py

+52
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,58 @@ def has_children(self):
247247
# type: () -> bool
248248
return True
249249

250+
class ClangEncodedEnumProvider:
251+
"""Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""
252+
DISCRIMINANT_MEMBER_NAME = "$discr$"
253+
VALUE_MEMBER_NAME = "value"
254+
255+
def __init__(self, valobj, dict):
256+
self.valobj = valobj
257+
self.update()
258+
259+
def has_children(self):
260+
return True
261+
262+
def num_children(self):
263+
if self.is_default:
264+
return 1
265+
return 2
266+
267+
def get_child_index(self, name):
268+
if name == ClangEncodedEnumProvider.VALUE_MEMBER_NAME:
269+
return 0
270+
if name == ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME:
271+
return 1
272+
return -1
273+
274+
def get_child_at_index(self, index):
275+
if index == 0:
276+
return self.variant.GetChildMemberWithName(ClangEncodedEnumProvider.VALUE_MEMBER_NAME)
277+
if index == 1:
278+
return self.variant.GetChildMemberWithName(
279+
ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME)
280+
281+
282+
def update(self):
283+
all_variants = self.valobj.GetChildAtIndex(0)
284+
index = self._getCurrentVariantIndex(all_variants)
285+
self.variant = all_variants.GetChildAtIndex(index)
286+
self.is_default = self.variant.GetIndexOfChildWithName(
287+
ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME) == -1
288+
289+
def _getCurrentVariantIndex(self, all_variants):
290+
default_index = 0
291+
for i in range(all_variants.GetNumChildren()):
292+
variant = all_variants.GetChildAtIndex(i)
293+
discr = variant.GetChildMemberWithName(
294+
ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME)
295+
if discr.IsValid():
296+
discr_unsigned_value = discr.GetValueAsUnsigned()
297+
if variant.GetName() == f"$variant${discr_unsigned_value}":
298+
return i
299+
else:
300+
default_index = i
301+
return default_index
250302

251303
class TupleSyntheticProvider:
252304
"""Pretty-printer for tuples and tuple enum variants"""

src/etc/rust_types.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class RustType(object):
6060

6161
ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
6262
ENUM_DISR_FIELD_NAME = "<<variant>>"
63+
ENUM_LLDB_ENCODED_VARIANTS = "$variants$"
6364

6465
STD_TYPE_TO_REGEX = {
6566
RustType.STD_STRING: STD_STRING_REGEX,
@@ -96,7 +97,11 @@ def classify_struct(name, fields):
9697
if regex.match(name):
9798
return ty
9899

99-
if fields[0].name == ENUM_DISR_FIELD_NAME:
100+
# <<variant>> is emitted by GDB while LLDB(18.1+) emits "$variants$"
101+
if (
102+
fields[0].name == ENUM_DISR_FIELD_NAME
103+
or fields[0].name == ENUM_LLDB_ENCODED_VARIANTS
104+
):
100105
return RustType.ENUM
101106

102107
if is_tuple_fields(fields):

src/librustdoc/html/static/css/noscript.css

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ nav.sub {
8585
--search-tab-button-not-selected-background: #e6e6e6;
8686
--search-tab-button-selected-border-top-color: #0089ff;
8787
--search-tab-button-selected-background: #fff;
88+
--settings-menu-filter: none;
8889
--stab-background-color: #fff5d6;
8990
--stab-code-color: #000;
9091
--code-highlight-kw-color: #8959a8;

src/librustdoc/html/static/css/rustdoc.css

+4
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,7 @@ a.tooltip:hover::after {
16251625
,5.1715698,7.5,6 S6.8284302,7.5,6,7.5z" fill="black"/></svg>');
16261626
width: 22px;
16271627
height: 22px;
1628+
filter: var(--settings-menu-filter);
16281629
}
16291630

16301631
#sidebar-button > a:before {
@@ -2419,6 +2420,7 @@ by default.
24192420
--search-tab-button-not-selected-background: #e6e6e6;
24202421
--search-tab-button-selected-border-top-color: #0089ff;
24212422
--search-tab-button-selected-background: #fff;
2423+
--settings-menu-filter: none;
24222424
--stab-background-color: #fff5d6;
24232425
--stab-code-color: #000;
24242426
--code-highlight-kw-color: #8959a8;
@@ -2524,6 +2526,7 @@ by default.
25242526
--search-tab-button-not-selected-background: #252525;
25252527
--search-tab-button-selected-border-top-color: #0089ff;
25262528
--search-tab-button-selected-background: #353535;
2529+
--settings-menu-filter: none;
25272530
--stab-background-color: #314559;
25282531
--stab-code-color: #e6e1cf;
25292532
--code-highlight-kw-color: #ab8ac1;
@@ -2636,6 +2639,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
26362639
--search-tab-button-not-selected-background: transparent !important;
26372640
--search-tab-button-selected-border-top-color: none;
26382641
--search-tab-button-selected-background: #141920 !important;
2642+
--settings-menu-filter: invert(100%);
26392643
--stab-background-color: #314559;
26402644
--stab-code-color: #e6e1cf;
26412645
--code-highlight-kw-color: #ff7733;

tests/debuginfo/borrowed-enum.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Require a gdb or lldb that can read DW_TAG_variant_part.
22
//@ min-gdb-version: 8.2
3-
//@ needs-rust-lldb
3+
//@ min-lldb-version: 1800
44

55
//@ compile-flags:-g
66

@@ -23,10 +23,13 @@
2323
// lldb-command:run
2424

2525
// lldb-command:v *the_a_ref
26+
// lldbg-check:(borrowed_enum::ABC) *the_a_ref = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 }
2627
// lldbr-check:(borrowed_enum::ABC::TheA) *the_a_ref = TheA { TheA: 0, TheB: 8970181431921507452 }
2728
// lldb-command:v *the_b_ref
29+
// lldbg-check:(borrowed_enum::ABC) *the_b_ref = { value = { 0 = 0 1 = 286331153 2 = 286331153 } $discr$ = 1 }
2830
// lldbr-check:(borrowed_enum::ABC::TheB) *the_b_ref = { = 0 = 286331153 = 286331153 }
2931
// lldb-command:v *univariant_ref
32+
// lldbg-check:(borrowed_enum::Univariant) *univariant_ref = { value = { 0 = 4820353753753434 } }
3033
// lldbr-check:(borrowed_enum::Univariant) *univariant_ref = { TheOnlyCase = { = 4820353753753434 } }
3134

3235
#![allow(unused_variables)]

tests/debuginfo/coroutine-objects.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
// Require a gdb that can read DW_TAG_variant_part.
22
//@ min-gdb-version: 8.2
3+
//@ min-lldb-version: 1800
34

4-
// LLDB without native Rust support cannot read DW_TAG_variant_part,
5-
// so it prints nothing for coroutines. But those tests are kept to
5+
// LLDB (18.1+) now supports DW_TAG_variant_part, but there is some bug in either compiler or LLDB
6+
// with memory layout of discriminant for this particular enum
67
// ensure that LLDB won't crash at least (like #57822).
78

89
//@ compile-flags:-g
@@ -26,16 +27,7 @@
2627

2728
// lldb-command:run
2829
// lldb-command:v b
29-
// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b =
30-
// lldb-command:continue
31-
// lldb-command:v b
32-
// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b =
33-
// lldb-command:continue
34-
// lldb-command:v b
35-
// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b =
36-
// lldb-command:continue
37-
// lldb-command:v b
38-
// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b =
30+
// lldb-check:(coroutine_objects::main::{coroutine_env#0}) b = { value = { _ref__a = 0x[...] } $discr$ = ',' }
3931

4032
// === CDB TESTS ===================================================================================
4133

tests/debuginfo/enum-thinlto.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Require a gdb that can read DW_TAG_variant_part.
22
//@ min-gdb-version: 8.2
3-
3+
//@ min-lldb-version: 1800
44
//@ compile-flags:-g -Z thinlto
55

66
// === GDB TESTS ===================================================================================
@@ -15,7 +15,7 @@
1515
// lldb-command:run
1616

1717
// lldb-command:v *abc
18-
// lldbg-check:(enum_thinlto::ABC) *abc =
18+
// lldbg-check:(enum_thinlto::ABC) *abc = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 }
1919
// lldbr-check:(enum_thinlto::ABC) *abc = (x = 0, y = 8970181431921507452)
2020

2121
#![allow(unused_variables)]

tests/debuginfo/issue-57822.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// Require a gdb that can read DW_TAG_variant_part.
55
//@ min-gdb-version: 8.2
6-
6+
//@ min-lldb-version: 1800
77
//@ compile-flags:-g
88

99
// === GDB TESTS ===================================================================================
@@ -24,7 +24,7 @@
2424
// lldbg-check:(issue_57822::main::{closure_env#1}) g = { f = { x = 1 } }
2525

2626
// lldb-command:v b
27-
// lldbg-check:(issue_57822::main::{coroutine_env#3}) b =
27+
// lldbg-check:(issue_57822::main::{coroutine_env#3}) b = { value = { a = { value = { y = 2 } $discr$ = '\x02' } } $discr$ = '\x02' }
2828

2929
#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait, stmt_expr_attributes)]
3030
#![omit_gdb_pretty_printer_section]

0 commit comments

Comments
 (0)