Skip to content

Rollup of 6 pull requests #128297

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

Closed
wants to merge 18 commits into from
Closed
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ceec6dd
update text for E0736 and E0739
folkertdev Jul 16, 2024
4bd3632
improve error message when `#[naked]` is used with `#[inline]`
folkertdev Jul 16, 2024
7e6c083
improve error message when `#[naked]` is used with `#[track-caller] a…
folkertdev Jul 16, 2024
4d082b7
add error message when `#[naked]` is used with `#[test]`
folkertdev Jul 16, 2024
c6a166b
switch to an allowlist approach
folkertdev Jul 17, 2024
a3bb010
allow `#[target_feature]` on `#[naked]` functions
folkertdev Jul 23, 2024
bad25e3
Add a README to rustbook to explain its purpose
ehuss Jul 27, 2024
c7e688e
fix `tests/ui/asm/naked-functions.rs` for aarch64
folkertdev Jul 27, 2024
ad05195
stabilize const_waker
slanterns Jul 26, 2024
c9e408e
bitwise and bytewise methods on `NonZero`
pitaj Jul 27, 2024
ec0b354
stabilize `is_sorted`
slanterns Jul 27, 2024
5eea6d7
rustc book: document how the RUST_TARGET_PATH variable is used
lolbinarycat Jul 27, 2024
bcb18a8
Rollup merge of #127853 - folkertdev:naked-function-error-messages, r…
matthiaskrgr Jul 28, 2024
78883da
Rollup merge of #128228 - slanterns:const_waker, r=dtolnay
matthiaskrgr Jul 28, 2024
aa07def
Rollup merge of #128276 - ehuss:rustbook-readme, r=Kobzol
matthiaskrgr Jul 28, 2024
5b59640
Rollup merge of #128279 - slanterns:is_sorted, r=dtolnay
matthiaskrgr Jul 28, 2024
6644c87
Rollup merge of #128282 - pitaj:nonzero_bitwise, r=workingjubilee
matthiaskrgr Jul 28, 2024
0b4d21b
Rollup merge of #128285 - lolbinarycat:rustc-custom-targets, r=jieyouxu
matthiaskrgr Jul 28, 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
5 changes: 5 additions & 0 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
@@ -220,6 +220,11 @@ builtin_macros_multiple_defaults = multiple declared defaults
.note = only one variant can be default
.suggestion = make `{$ident}` default

builtin_macros_naked_functions_testing_attribute =
cannot use `#[naked]` with testing attributes
.label = function marked with testing attribute here
.naked_attribute = `#[naked]` is incompatible with testing attributes

builtin_macros_no_default_variant = no default declared
.help = make a unit variant default by placing `#[default]` above it
.suggestion = make `{$ident}` default
10 changes: 10 additions & 0 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
@@ -923,3 +923,13 @@ pub(crate) struct ExpectedItem<'a> {
pub span: Span,
pub token: &'a str,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)]
pub struct NakedFunctionTestingAttribute {
#[primary_span]
#[label(builtin_macros_naked_attribute)]
pub naked_span: Span,
#[label]
pub testing_span: Span,
}
8 changes: 8 additions & 0 deletions compiler/rustc_builtin_macros/src/test.rs
Original file line number Diff line number Diff line change
@@ -133,6 +133,14 @@ pub(crate) fn expand_test_or_bench(
};
};

if let Some(attr) = attr::find_by_name(&item.attrs, sym::naked) {
cx.dcx().emit_err(errors::NakedFunctionTestingAttribute {
testing_span: attr_sp,
naked_span: attr.span,
});
return vec![Annotatable::Item(item)];
}

// check_*_signature will report any errors in the type so compilation
// will fail. We shouldn't try to expand in this case because the errors
// would be spurious.
1 change: 0 additions & 1 deletion compiler/rustc_codegen_cranelift/example/std_example.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
coroutines,
stmt_expr_attributes,
coroutine_trait,
is_sorted,
repr_simd,
tuple_trait,
unboxed_closures
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_gcc/example/std_example.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(internal_features)]
#![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted, stmt_expr_attributes)]
#![feature(core_intrinsics, coroutines, coroutine_trait, stmt_expr_attributes)]

#[cfg(feature="master")]
#[cfg(target_arch="x86_64")]
18 changes: 12 additions & 6 deletions compiler/rustc_error_codes/src/error_codes/E0736.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
`#[track_caller]` and `#[naked]` cannot both be applied to the same function.
Functions marked with the `#[naked]` attribute are restricted in what other
attributes they may be marked with.

Notable attributes that are incompatible with `#[naked]` are:

* `#[inline]`
* `#[track_caller]`
* `#[test]`, `#[ignore]`, `#[should_panic]`

Erroneous code example:

```compile_fail,E0736
#[inline]
#[naked]
#[track_caller]
fn foo() {}
```

This is primarily due to ABI incompatibilities between the two attributes.
See [RFC 2091] for details on this and other limitations.

[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
These incompatibilities are due to the fact that naked functions deliberately
impose strict restrictions regarding the code that the compiler is
allowed to produce for this function.
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0739.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
`#[track_caller]` can not be applied on struct.
`#[track_caller]` must be applied to a function

Erroneous code example:

1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -64,7 +64,6 @@ This API is completely unstable and subject to change.
#![doc(rust_logo)]
#![feature(control_flow_enum)]
#![feature(if_let_guard)]
#![feature(is_sorted)]
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(never_type)]
12 changes: 8 additions & 4 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -1984,14 +1984,18 @@ declare_lint! {
///
/// ```rust
/// trait MyIterator : Iterator {
/// // is_sorted is an unstable method that already exists on the Iterator trait
/// fn is_sorted(self) -> bool where Self: Sized {true}
/// // is_partitioned is an unstable method that already exists on the Iterator trait
/// fn is_partitioned<P>(self, predicate: P) -> bool
/// where
/// Self: Sized,
/// P: FnMut(Self::Item) -> bool,
/// {true}
/// }
///
/// impl<T: ?Sized> MyIterator for T where T: Iterator { }
///
/// let x = vec![1, 2, 3];
/// let _ = x.iter().is_sorted();
/// let _ = x.iter().is_partitioned(|_| true);
/// ```
///
/// {{produces}}
@@ -2007,7 +2011,7 @@ declare_lint! {
/// is an early-warning to let you know that there may be a collision in
/// the future. This can be avoided by adding type annotations to
/// disambiguate which trait method you intend to call, such as
/// `MyIterator::is_sorted(my_iter)` or renaming or removing the method.
/// `MyIterator::is_partitioned(my_iter, my_predicate)` or renaming or removing the method.
///
/// [nightly channel]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
/// [`feature` attribute]: https://doc.rust-lang.org/nightly/unstable-book/
1 change: 0 additions & 1 deletion compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(is_sorted)]
#![feature(let_chains)]
#![feature(map_try_insert)]
#![feature(never_type)]
1 change: 0 additions & 1 deletion compiler/rustc_monomorphize/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// tidy-alphabetical-start
#![feature(array_windows)]
#![feature(is_sorted)]
// tidy-alphabetical-end

use rustc_hir::lang_items::LangItem;
11 changes: 5 additions & 6 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
@@ -69,9 +69,6 @@ passes_break_non_loop =
.suggestion = use `break` on its own without a value inside this `{$kind}` loop
.break_expr_suggestion = alternatively, you might have meant to use the available loop label

passes_cannot_inline_naked_function =
naked functions cannot be inlined

passes_cannot_stabilize_deprecated =
an API can't be stabilized after it is deprecated
.label = invalid version
@@ -485,16 +482,18 @@ passes_naked_functions_asm_block =
passes_naked_functions_asm_options =
asm options unsupported in naked functions: {$unsupported_options}

passes_naked_functions_incompatible_attribute =
attribute incompatible with `#[naked]`
.label = the `{$attr}` attribute is incompatible with `#[naked]`
.naked_attribute = function marked with `#[naked]` here

passes_naked_functions_must_use_noreturn =
asm in naked functions must use `noreturn` option
.suggestion = consider specifying that the asm block is responsible for returning from the function

passes_naked_functions_operands =
only `const` and `sym` operands are supported in naked functions

passes_naked_tracked_caller =
cannot use `#[track_caller]` with `#[naked]`

passes_no_link =
attribute should be applied to an `extern crate` item
.label = not an `extern crate` item
73 changes: 64 additions & 9 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
@@ -155,7 +155,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::rustc_std_internal_symbol] => {
self.check_rustc_std_internal_symbol(attr, span, target)
}
[sym::naked] => self.check_naked(hir_id, attr, span, target),
[sym::naked] => self.check_naked(hir_id, attr, span, target, attrs),
[sym::rustc_never_returns_null_ptr] => {
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
}
@@ -410,12 +410,71 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}

/// Checks if `#[naked]` is applied to a function definition.
fn check_naked(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
fn check_naked(
&self,
hir_id: HirId,
attr: &Attribute,
span: Span,
target: Target,
attrs: &[Attribute],
) -> bool {
// many attributes don't make sense in combination with #[naked].
// Notable attributes that are incompatible with `#[naked]` are:
//
// * `#[inline]`
// * `#[track_caller]`
// * `#[test]`, `#[ignore]`, `#[should_panic]`
//
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
const ALLOW_LIST: &[rustc_span::Symbol] = &[
// conditional compilation
sym::cfg,
sym::cfg_attr,
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
sym::test,
sym::ignore,
sym::should_panic,
sym::bench,
// diagnostics
sym::allow,
sym::warn,
sym::deny,
sym::forbid,
sym::deprecated,
sym::must_use,
// abi, linking and FFI
sym::export_name,
sym::link_section,
sym::linkage,
sym::no_mangle,
sym::naked,
sym::instruction_set,
// code generation
sym::cold,
sym::target_feature,
// documentation
sym::doc,
];

match target {
Target::Fn
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
for other_attr in attrs {
if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
span: other_attr.span,
naked_span: attr.span,
attr: other_attr.name_or_empty(),
});

return false;
}
}

true
}
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
// `#[allow_internal_unstable]` attribute with just a lint, because we previously
// `#[naked]` attribute with just a lint, because we previously
// erroneously allowed it and some crates used it accidentally, to be compatible
// with crates depending on them, we can't throw an error here.
Target::Field | Target::Arm | Target::MacroDef => {
@@ -488,7 +547,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}

/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
/// Checks if a `#[track_caller]` is applied to a function. Returns `true` if valid.
fn check_track_caller(
&self,
hir_id: HirId,
@@ -498,10 +557,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
target: Target,
) -> bool {
match target {
_ if attrs.iter().any(|attr| attr.has_name(sym::naked)) => {
self.dcx().emit_err(errors::NakedTrackedCaller { attr_span });
false
}
Target::Fn => {
// `#[track_caller]` is not valid on weak lang items because they are called via
// `extern` declarations and `#[track_caller]` would alter their ABI.
25 changes: 11 additions & 14 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
@@ -79,13 +79,6 @@ pub struct AttrShouldBeAppliedToFn {
pub on_crate: bool,
}

#[derive(Diagnostic)]
#[diag(passes_naked_tracked_caller, code = E0736)]
pub struct NakedTrackedCaller {
#[primary_span]
pub attr_span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_should_be_applied_to_fn, code = E0739)]
pub struct TrackedCallerWrongLocation {
@@ -1124,13 +1117,6 @@ pub struct UnlabeledCfInWhileCondition<'a> {
pub cf_type: &'a str,
}

#[derive(Diagnostic)]
#[diag(passes_cannot_inline_naked_function)]
pub struct CannotInlineNakedFunction {
#[primary_span]
pub span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes_undefined_naked_function_abi)]
pub struct UndefinedNakedFunctionAbi;
@@ -1196,6 +1182,17 @@ pub struct NakedFunctionsMustUseNoreturn {
pub last_span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
pub struct NakedFunctionIncompatibleAttribute {
#[primary_span]
#[label]
pub span: Span,
#[label(passes_naked_attribute)]
pub naked_span: Span,
pub attr: Symbol,
}

#[derive(Diagnostic)]
#[diag(passes_attr_only_in_functions)]
pub struct AttrOnlyInFunctions {
14 changes: 2 additions & 12 deletions compiler/rustc_passes/src/naked_functions.rs
Original file line number Diff line number Diff line change
@@ -14,9 +14,8 @@ use rustc_span::Span;
use rustc_target::spec::abi::Abi;

use crate::errors::{
CannotInlineNakedFunction, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions,
NakedFunctionsMustUseNoreturn, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
UndefinedNakedFunctionAbi,
NakedFunctionsAsmBlock, NakedFunctionsAsmOptions, NakedFunctionsMustUseNoreturn,
NakedFunctionsOperands, NoPatterns, ParamsNotAllowed, UndefinedNakedFunctionAbi,
};

pub(crate) fn provide(providers: &mut Providers) {
@@ -53,15 +52,6 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
check_no_patterns(tcx, body.params);
check_no_parameters_use(tcx, body);
check_asm(tcx, def_id, body);
check_inline(tcx, def_id);
}
}

/// Check that the function isn't inlined.
fn check_inline(tcx: TyCtxt<'_>, def_id: LocalDefId) {
let attrs = tcx.get_attrs(def_id, sym::inline);
for attr in attrs {
tcx.dcx().emit_err(CannotInlineNakedFunction { span: attr.span });
}
}

2 changes: 0 additions & 2 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -92,7 +92,6 @@
// tidy-alphabetical-start
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))]
#![cfg_attr(test, feature(is_sorted))]
#![cfg_attr(test, feature(new_uninit))]
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
@@ -117,7 +116,6 @@
#![feature(const_pin)]
#![feature(const_refs_to_cell)]
#![feature(const_size_of_val)]
#![feature(const_waker)]
#![feature(core_intrinsics)]
#![feature(deprecated_suggestion)]
#![feature(deref_pure_trait)]
Loading