Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #124769

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b90bcd6
Make autolabelling for macOS slightly better
madsmtm Apr 19, 2024
e64cbc4
Rename `macos` ping group to `apple`
madsmtm Apr 19, 2024
fc37633
Support Result<T, E> across FFI when niche optimization can be used
MasterAwesome Mar 9, 2024
b3e6d52
We don't need to check for non-exhaustive fields
MasterAwesome Mar 9, 2024
08b85a1
Don't lint niche optimized variants in enums
MasterAwesome Mar 9, 2024
223d5eb
Add tests
MasterAwesome Mar 9, 2024
014ddac
Disallow single-variant enums
MasterAwesome Mar 9, 2024
b3f6511
Add a test against Result<(), ()>
MasterAwesome Mar 19, 2024
764f64f
Reword `is_niche_optimization_candidate` doc
MasterAwesome Mar 19, 2024
437ca26
Remove comment out of RFC's scope
MasterAwesome Mar 19, 2024
ed532cc
Put the RFC behind a feature gate `result_ffi_guarantees`
MasterAwesome Mar 19, 2024
43e6600
Implement lldb formattter for "clang encoded" enums (LLDB 18.1+)
Apr 23, 2024
f90b15b
Add `rustfmt` cfg to well known cfgs list
Urgau May 5, 2024
0cbebd0
Fix bad color for setting cog in ayu theme
GuillaumeGomez May 5, 2024
e460901
Add GUI regression test for setting's cog color
GuillaumeGomez May 5, 2024
6c1b8d2
Meta: Enable the triagebot transfer command
fmease May 4, 2024
dc153f8
Change the label for the Apple ping group to the new O-apple
madsmtm May 5, 2024
6fc3ff3
Rollup merge of #124146 - madsmtm:apple-triage, r=dtolnay
fmease May 5, 2024
c94f367
Rollup merge of #124742 - Urgau:check-cfg-rustfmt, r=fmease
fmease May 5, 2024
5ea5fcc
Rollup merge of #124745 - VladimirMakaev:lldb-enum-formatter, r=Mark-…
fmease May 5, 2024
0940dc6
Rollup merge of #124747 - MasterAwesome:master, r=davidtwco
fmease May 5, 2024
fc0fe8a
Rollup merge of #124765 - GuillaumeGomez:fix-wrong-cog-colotr, r=notr…
fmease May 5, 2024
31e2302
Rollup merge of #124768 - fmease:enable-triagebot-transfer-2, r=jackh726
fmease May 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,9 @@ declare_features! (
(incomplete, repr128, "1.16.0", Some(56071)),
/// Allows `repr(simd)` and importing the various simd intrinsics.
(unstable, repr_simd, "1.4.0", Some(27731)),
/// Allows enums like Result<T, E> to be used across FFI, if T's niche value can
/// be used to describe E or vise-versa.
(unstable, result_ffi_guarantees, "CURRENT_RUSTC_VERSION", Some(110503)),
/// Allows bounding the return type of AFIT/RPITIT.
(incomplete, return_type_notation, "1.70.0", Some(109417)),
/// Allows `extern "rust-cold"`.
Expand Down
69 changes: 56 additions & 13 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,32 @@ fn get_nullable_type<'tcx>(
})
}

/// A type is niche-optimization candidate iff:
/// - Is a zero-sized type with alignment 1 (a “1-ZST”).
/// - Has no fields.
/// - Does not have the `#[non_exhaustive]` attribute.
fn is_niche_optimization_candidate<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> bool {
if tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| !layout.is_1zst()) {
return false;
}

match ty.kind() {
ty::Adt(ty_def, _) => {
let non_exhaustive = ty_def.is_variant_list_non_exhaustive();
let empty = (ty_def.is_struct() && ty_def.all_fields().next().is_none())
|| (ty_def.is_enum() && ty_def.variants().is_empty());

!non_exhaustive && empty
}
ty::Tuple(tys) => tys.is_empty(),
_ => false,
}
}

/// Check if this enum can be safely exported based on the "nullable pointer optimization". If it
/// can, return the type that `ty` can be safely converted to, otherwise return `None`.
/// Currently restricted to function pointers, boxes, references, `core::num::NonZero`,
Expand All @@ -1117,6 +1143,22 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
let field_ty = match &ty_def.variants().raw[..] {
[var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
([], [field]) | ([field], []) => field.ty(tcx, args),
([field1], [field2]) => {
if !tcx.features().result_ffi_guarantees {
return None;
}

let ty1 = field1.ty(tcx, args);
let ty2 = field2.ty(tcx, args);

if is_niche_optimization_candidate(tcx, param_env, ty1) {
ty2
} else if is_niche_optimization_candidate(tcx, param_env, ty2) {
ty1
} else {
return None;
}
}
_ => return None,
},
_ => return None,
Expand Down Expand Up @@ -1202,7 +1244,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
args: GenericArgsRef<'tcx>,
) -> FfiResult<'tcx> {
use FfiResult::*;

let transparent_with_all_zst_fields = if def.repr().transparent() {
if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
// Transparent newtypes have at most one non-ZST field which needs to be checked..
Expand Down Expand Up @@ -1329,27 +1370,29 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
return FfiSafe;
}

if def.is_variant_list_non_exhaustive() && !def.did().is_local() {
return FfiUnsafe {
ty,
reason: fluent::lint_improper_ctypes_non_exhaustive,
help: None,
};
}

// Check for a repr() attribute to specify the size of the
// discriminant.
if !def.repr().c() && !def.repr().transparent() && def.repr().int.is_none()
{
// Special-case types like `Option<extern fn()>`.
if repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode)
.is_none()
// Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
if let Some(ty) =
repr_nullable_ptr(self.cx.tcx, self.cx.param_env, ty, self.mode)
{
return FfiUnsafe {
ty,
reason: fluent::lint_improper_ctypes_enum_repr_reason,
help: Some(fluent::lint_improper_ctypes_enum_repr_help),
};
return self.check_type_for_ffi(cache, ty);
}
}

if def.is_variant_list_non_exhaustive() && !def.did().is_local() {
return FfiUnsafe {
ty,
reason: fluent::lint_improper_ctypes_non_exhaustive,
help: None,
reason: fluent::lint_improper_ctypes_enum_repr_reason,
help: Some(fluent::lint_improper_ctypes_enum_repr_help),
};
}

Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_session/src/config/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,13 +262,15 @@ impl CheckCfg {

ins!(sym::debug_assertions, no_values);

// These four are never set by rustc, but we set them anyway: they
// should not trigger a lint because `cargo clippy`, `cargo doc`,
// `cargo test` and `cargo miri run` (respectively) can set them.
// These four are never set by rustc, but we set them anyway; they
// should not trigger the lint because `cargo clippy`, `cargo doc`,
// `cargo test`, `cargo miri run` and `cargo fmt` (respectively)
// can set them.
ins!(sym::clippy, no_values);
ins!(sym::doc, no_values);
ins!(sym::doctest, no_values);
ins!(sym::miri, no_values);
ins!(sym::rustfmt, no_values);

ins!(sym::overflow_checks, no_values);

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,7 @@ symbols! {
require,
residual,
result,
result_ffi_guarantees,
resume,
return_position_impl_trait_in_trait,
return_type_notation,
Expand Down
3 changes: 2 additions & 1 deletion src/doc/rustc/src/check-cfg.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Those well known names and values follows the same stability as what they refer
Well known names and values checking is always enabled as long as at least one
`--check-cfg` argument is present.

As of `2024-04-06T`, the list of known names is as follows:
As of `2024-05-06T`, the list of known names is as follows:

<!--- See CheckCfg::fill_well_known in compiler/rustc_session/src/config.rs -->

Expand All @@ -84,6 +84,7 @@ As of `2024-04-06T`, the list of known names is as follows:
- `panic`
- `proc_macro`
- `relocation_model`
- `rustfmt`
- `sanitize`
- `sanitizer_cfi_generalize_pointers`
- `sanitizer_cfi_normalize_integers`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# `result_ffi_guarantees`

The tracking issue for this feature is: [#110503]

[#110503]: https://github.com/rust-lang/rust/issues/110503

------------------------

This feature adds the possibility of using `Result<T, E>` in FFI if T's niche
value can be used to describe E or vise-versa.

See [RFC 3391] for more information.

[RFC 3391]: https://github.com/rust-lang/rfcs/blob/master/text/3391-result_ffi_guarantees.md
3 changes: 2 additions & 1 deletion src/etc/lldb_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ def synthetic_lookup(valobj, dict):
return synthetic_lookup(valobj.GetChildAtIndex(discriminant), dict)
if rust_type == RustType.SINGLETON_ENUM:
return synthetic_lookup(valobj.GetChildAtIndex(0), dict)

if rust_type == RustType.ENUM:
return ClangEncodedEnumProvider(valobj, dict)
if rust_type == RustType.STD_VEC:
return StdVecSyntheticProvider(valobj, dict)
if rust_type == RustType.STD_VEC_DEQUE:
Expand Down
52 changes: 52 additions & 0 deletions src/etc/lldb_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,58 @@ def has_children(self):
# type: () -> bool
return True

class ClangEncodedEnumProvider:
"""Pretty-printer for 'clang-encoded' enums support implemented in LLDB"""
DISCRIMINANT_MEMBER_NAME = "$discr$"
VALUE_MEMBER_NAME = "value"

def __init__(self, valobj, dict):
self.valobj = valobj
self.update()

def has_children(self):
return True

def num_children(self):
if self.is_default:
return 1
return 2

def get_child_index(self, name):
if name == ClangEncodedEnumProvider.VALUE_MEMBER_NAME:
return 0
if name == ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME:
return 1
return -1

def get_child_at_index(self, index):
if index == 0:
return self.variant.GetChildMemberWithName(ClangEncodedEnumProvider.VALUE_MEMBER_NAME)
if index == 1:
return self.variant.GetChildMemberWithName(
ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME)


def update(self):
all_variants = self.valobj.GetChildAtIndex(0)
index = self._getCurrentVariantIndex(all_variants)
self.variant = all_variants.GetChildAtIndex(index)
self.is_default = self.variant.GetIndexOfChildWithName(
ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME) == -1

def _getCurrentVariantIndex(self, all_variants):
default_index = 0
for i in range(all_variants.GetNumChildren()):
variant = all_variants.GetChildAtIndex(i)
discr = variant.GetChildMemberWithName(
ClangEncodedEnumProvider.DISCRIMINANT_MEMBER_NAME)
if discr.IsValid():
discr_unsigned_value = discr.GetValueAsUnsigned()
if variant.GetName() == f"$variant${discr_unsigned_value}":
return i
else:
default_index = i
return default_index

class TupleSyntheticProvider:
"""Pretty-printer for tuples and tuple enum variants"""
Expand Down
7 changes: 6 additions & 1 deletion src/etc/rust_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class RustType(object):

ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$"
ENUM_DISR_FIELD_NAME = "<<variant>>"
ENUM_LLDB_ENCODED_VARIANTS = "$variants$"

STD_TYPE_TO_REGEX = {
RustType.STD_STRING: STD_STRING_REGEX,
Expand Down Expand Up @@ -96,7 +97,11 @@ def classify_struct(name, fields):
if regex.match(name):
return ty

if fields[0].name == ENUM_DISR_FIELD_NAME:
# <<variant>> is emitted by GDB while LLDB(18.1+) emits "$variants$"
if (
fields[0].name == ENUM_DISR_FIELD_NAME
or fields[0].name == ENUM_LLDB_ENCODED_VARIANTS
):
return RustType.ENUM

if is_tuple_fields(fields):
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/html/static/css/noscript.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ nav.sub {
--search-tab-button-not-selected-background: #e6e6e6;
--search-tab-button-selected-border-top-color: #0089ff;
--search-tab-button-selected-background: #fff;
--settings-menu-filter: none;
--stab-background-color: #fff5d6;
--stab-code-color: #000;
--code-highlight-kw-color: #8959a8;
Expand Down
4 changes: 4 additions & 0 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,7 @@ a.tooltip:hover::after {
,5.1715698,7.5,6 S6.8284302,7.5,6,7.5z" fill="black"/></svg>');
width: 22px;
height: 22px;
filter: var(--settings-menu-filter);
}

#sidebar-button > a:before {
Expand Down Expand Up @@ -2419,6 +2420,7 @@ by default.
--search-tab-button-not-selected-background: #e6e6e6;
--search-tab-button-selected-border-top-color: #0089ff;
--search-tab-button-selected-background: #fff;
--settings-menu-filter: none;
--stab-background-color: #fff5d6;
--stab-code-color: #000;
--code-highlight-kw-color: #8959a8;
Expand Down Expand Up @@ -2524,6 +2526,7 @@ by default.
--search-tab-button-not-selected-background: #252525;
--search-tab-button-selected-border-top-color: #0089ff;
--search-tab-button-selected-background: #353535;
--settings-menu-filter: none;
--stab-background-color: #314559;
--stab-code-color: #e6e1cf;
--code-highlight-kw-color: #ab8ac1;
Expand Down Expand Up @@ -2636,6 +2639,7 @@ Original by Dempfi (https://github.com/dempfi/ayu)
--search-tab-button-not-selected-background: transparent !important;
--search-tab-button-selected-border-top-color: none;
--search-tab-button-selected-background: #141920 !important;
--settings-menu-filter: invert(100%);
--stab-background-color: #314559;
--stab-code-color: #e6e1cf;
--code-highlight-kw-color: #ff7733;
Expand Down
5 changes: 4 additions & 1 deletion tests/debuginfo/borrowed-enum.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Require a gdb or lldb that can read DW_TAG_variant_part.
//@ min-gdb-version: 8.2
//@ needs-rust-lldb
//@ min-lldb-version: 1800

//@ compile-flags:-g

Expand All @@ -23,10 +23,13 @@
// lldb-command:run

// lldb-command:v *the_a_ref
// lldbg-check:(borrowed_enum::ABC) *the_a_ref = { value = { x = 0 y = 8970181431921507452 } $discr$ = 0 }
// lldbr-check:(borrowed_enum::ABC::TheA) *the_a_ref = TheA { TheA: 0, TheB: 8970181431921507452 }
// lldb-command:v *the_b_ref
// lldbg-check:(borrowed_enum::ABC) *the_b_ref = { value = { 0 = 0 1 = 286331153 2 = 286331153 } $discr$ = 1 }
// lldbr-check:(borrowed_enum::ABC::TheB) *the_b_ref = { = 0 = 286331153 = 286331153 }
// lldb-command:v *univariant_ref
// lldbg-check:(borrowed_enum::Univariant) *univariant_ref = { value = { 0 = 4820353753753434 } }
// lldbr-check:(borrowed_enum::Univariant) *univariant_ref = { TheOnlyCase = { = 4820353753753434 } }

#![allow(unused_variables)]
Expand Down
16 changes: 4 additions & 12 deletions tests/debuginfo/coroutine-objects.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Require a gdb that can read DW_TAG_variant_part.
//@ min-gdb-version: 8.2
//@ min-lldb-version: 1800

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

//@ compile-flags:-g
Expand All @@ -26,16 +27,7 @@

// lldb-command:run
// lldb-command:v b
// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b =
// lldb-command:continue
// lldb-command:v b
// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b =
// lldb-command:continue
// lldb-command:v b
// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b =
// lldb-command:continue
// lldb-command:v b
// lldbg-check:(coroutine_objects::main::{coroutine_env#0}) b =
// lldb-check:(coroutine_objects::main::{coroutine_env#0}) b = { value = { _ref__a = 0x[...] } $discr$ = ',' }

// === CDB TESTS ===================================================================================

Expand Down
4 changes: 2 additions & 2 deletions tests/debuginfo/enum-thinlto.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Require a gdb that can read DW_TAG_variant_part.
//@ min-gdb-version: 8.2

//@ min-lldb-version: 1800
//@ compile-flags:-g -Z thinlto

// === GDB TESTS ===================================================================================
Expand All @@ -15,7 +15,7 @@
// lldb-command:run

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

#![allow(unused_variables)]
Expand Down
4 changes: 2 additions & 2 deletions tests/debuginfo/issue-57822.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

// Require a gdb that can read DW_TAG_variant_part.
//@ min-gdb-version: 8.2

//@ min-lldb-version: 1800
//@ compile-flags:-g

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

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

#![feature(omit_gdb_pretty_printer_section, coroutines, coroutine_trait, stmt_expr_attributes)]
#![omit_gdb_pretty_printer_section]
Expand Down
Loading
Loading