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

weak lang items are not allowed to be #[track_caller] #124067

Merged
merged 2 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0522.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Erroneous code example:
#![feature(lang_items)]

#[lang = "cookie"]
fn cookie() -> ! { // error: definition of an unknown language item: `cookie`
fn cookie() -> ! { // error: definition of an unknown lang item: `cookie`
loop {}
}
```
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// ==========================================================================
gated!(
lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, EncodeCrossCrate::No, lang_items,
"language items are subject to change",
"lang items are subject to change",
),
rustc_attr!(
rustc_pass_by_value, Normal, template!(Word), ErrorFollowing,
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Defines language items.
//! Defines lang items.
//!
//! Language items are items that represent concepts intrinsic to the language
//! itself. Examples are:
Expand All @@ -16,7 +16,7 @@ use rustc_macros::HashStable_Generic;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span;

/// All of the language items, defined or not.
/// All of the lang items, defined or not.
/// Defined lang items can come from the current crate or its dependencies.
#[derive(HashStable_Generic, Debug)]
pub struct LanguageItems {
Expand Down Expand Up @@ -57,7 +57,7 @@ macro_rules! language_item_table {
) => {

enum_from_u32! {
/// A representation of all the valid language items in Rust.
/// A representation of all the valid lang items in Rust.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
pub enum LangItem {
$(
Expand Down Expand Up @@ -165,7 +165,7 @@ language_item_table! {
CoerceUnsized, sym::coerce_unsized, coerce_unsized_trait, Target::Trait, GenericRequirement::Minimum(1);
DispatchFromDyn, sym::dispatch_from_dyn, dispatch_from_dyn_trait, Target::Trait, GenericRequirement::Minimum(1);

// language items relating to transmutability
// lang items relating to transmutability
TransmuteOpts, sym::transmute_opts, transmute_opts, Target::Struct, GenericRequirement::Exact(0);
TransmuteTrait, sym::transmute_trait, transmute_trait, Target::Trait, GenericRequirement::Exact(2);

Expand Down Expand Up @@ -291,7 +291,7 @@ language_item_table! {
OwnedBox, sym::owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1);
GlobalAlloc, sym::global_alloc_ty, global_alloc_ty, Target::Struct, GenericRequirement::None;

// Experimental language item for Miri
// Experimental lang item for Miri
PtrUnique, sym::ptr_unique, ptr_unique, Target::Struct, GenericRequirement::Exact(1);

PhantomData, sym::phantom_data, phantom_data, Target::Struct, GenericRequirement::Exact(1);
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,20 +534,20 @@ pub fn check_intrinsic_type(

sym::va_start | sym::va_end => match mk_va_list_ty(hir::Mutability::Mut) {
Some((va_list_ref_ty, _)) => (0, 0, vec![va_list_ref_ty], Ty::new_unit(tcx)),
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
None => bug!("`va_list` lang item needed for C-variadic intrinsics"),
},

sym::va_copy => match mk_va_list_ty(hir::Mutability::Not) {
Some((va_list_ref_ty, va_list_ty)) => {
let va_list_ptr_ty = Ty::new_mut_ptr(tcx, va_list_ty);
(0, 0, vec![va_list_ptr_ty, va_list_ref_ty], Ty::new_unit(tcx))
}
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
None => bug!("`va_list` lang item needed for C-variadic intrinsics"),
},

sym::va_arg => match mk_va_list_ty(hir::Mutability::Mut) {
Some((va_list_ref_ty, _)) => (1, 0, vec![va_list_ref_ty], param(0)),
None => bug!("`va_list` language item needed for C-variadic intrinsics"),
None => bug!("`va_list` lang item needed for C-variadic intrinsics"),
},

sym::nontemporal_store => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
tcx.arena.alloc_from_iter(self.root.stability_implications.decode(self))
}

/// Iterates over the language items in the given crate.
/// Iterates over the lang items in the given crate.
fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] {
tcx.arena.alloc_from_iter(
self.root
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/middle/lang_items.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Detecting language items.
//! Detecting lang items.
//!
//! Language items are items that represent concepts intrinsic to the language
//! itself. Examples are:
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/deduce_param_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub fn deduced_param_attrs<'tcx>(
return &[];
}

// If the Freeze language item isn't present, then don't bother.
// If the Freeze lang item isn't present, then don't bother.
if tcx.lang_items().freeze_trait().is_none() {
return &[];
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/lower_slice_len.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl<'tcx> MirPass<'tcx> for LowerSliceLenCalls {
pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let language_items = tcx.lang_items();
let Some(slice_len_fn_item_def_id) = language_items.slice_len_fn() else {
// there is no language item to compare to :)
// there is no lang item to compare to :)
return;
};

Expand Down
23 changes: 16 additions & 7 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ passes_incorrect_meta_item = expected a quoted string literal
passes_incorrect_meta_item_suggestion = consider surrounding this with quotes

passes_incorrect_target =
`{$name}` language item must be applied to a {$kind} with {$at_least ->
`{$name}` lang item must be applied to a {$kind} with {$at_least ->
[true] at least {$num}
*[false] {$num}
} generic {$num ->
Expand Down Expand Up @@ -394,12 +394,21 @@ passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]

passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments

passes_lang_item_fn = {$name ->
[panic_impl] `#[panic_handler]`
*[other] `{$name}` lang item
} function

passes_lang_item_fn_with_target_feature =
`{$name}` language item function is not allowed to have `#[target_feature]`
.label = `{$name}` language item function is not allowed to have `#[target_feature]`
{passes_lang_item_fn} is not allowed to have `#[target_feature]`
.label = {passes_lang_item_fn} is not allowed to have `#[target_feature]`

passes_lang_item_fn_with_track_caller =
{passes_lang_item_fn} is not allowed to have `#[track_caller]`
.label = {passes_lang_item_fn} is not allowed to have `#[target_feature]`

passes_lang_item_on_incorrect_target =
`{$name}` language item must be applied to a {$expected_target}
`{$name}` lang item must be applied to a {$expected_target}
.label = attribute should be applied to a {$expected_target}, not a {$actual_target}

passes_layout_abi =
Expand Down Expand Up @@ -455,7 +464,7 @@ passes_missing_const_stab_attr =
{$descr} has missing const stability attribute

passes_missing_lang_item =
language item required, but not found: `{$name}`
lang item required, but not found: `{$name}`
.note = this can occur when a binary crate with `#![no_std]` is compiled for a target where `{$name}` is defined in the standard library
.help = you may be able to compile for a target that doesn't need `{$name}`, specify a target with `--target` or in `.cargo/config`

Expand Down Expand Up @@ -696,8 +705,8 @@ passes_unknown_feature =
unknown feature `{$feature}`

passes_unknown_lang_item =
definition of an unknown language item: `{$name}`
.label = definition of unknown language item `{$name}`
definition of an unknown lang item: `{$name}`
.label = definition of unknown lang item `{$name}`

passes_unlabeled_cf_in_while_condition =
`break` or `continue` with no label in the condition of a `while` loop
Expand Down
25 changes: 22 additions & 3 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::StashKey;
use rustc_errors::{Applicability, DiagCtxt, IntoDiagArg, MultiSpan};
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
use rustc_hir as hir;
use rustc_hir::def_id::LocalModDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{self as hir};
use rustc_hir::{
self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
};
Expand Down Expand Up @@ -519,7 +519,26 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.dcx().emit_err(errors::NakedTrackedCaller { attr_span });
false
}
Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true,
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.
if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
&& let Some(item) = hir::LangItem::from_name(lang_item)
&& item.is_weak()
{
let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();

self.dcx().emit_err(errors::LangItemWithTrackCaller {
attr_span,
name: lang_item,
sig_span: sig.span,
});
false
} else {
true
}
}
Target::Method(..) | Target::ForeignFn | Target::Closure => true,
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
// `#[track_caller]` attribute with just a lint, because we previously
// erroneously allowed it and some crates used it accidentally, to be compatible
Expand Down Expand Up @@ -602,7 +621,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
) -> bool {
match target {
Target::Fn => {
// `#[target_feature]` is not allowed in language items.
// `#[target_feature]` is not allowed in lang items.
if let Some((lang_item, _)) = hir::lang_items::extract(attrs)
// Calling functions with `#[target_feature]` is
// not unsafe on WASM, see #84988
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,16 @@ pub struct MissingLangItem {
pub name: Symbol,
}

#[derive(Diagnostic)]
#[diag(passes_lang_item_fn_with_track_caller)]
pub struct LangItemWithTrackCaller {
#[primary_span]
pub attr_span: Span,
pub name: Symbol,
#[label]
pub sig_span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_lang_item_fn_with_target_feature)]
pub struct LangItemWithTargetFeature {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/lang_items.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Detecting language items.
//! Detecting lang items.
//!
//! Language items are items that represent concepts intrinsic to the language
//! itself. Examples are:
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/weak_lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::errors::{
};

/// Checks the crate for usage of weak lang items, returning a vector of all the
/// language items required by this crate, but not defined yet.
/// lang items required by this crate, but not defined yet.
pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems, krate: &ast::Crate) {
// These are never called by user code, they're generated by the compiler.
// They will never implicitly be added to the `missing` array unless we do
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ pub struct Resolver<'a, 'tcx> {
block_map: NodeMap<Module<'a>>,
/// A fake module that contains no definition and no prelude. Used so that
/// some AST passes can generate identifiers that only resolve to local or
/// language items.
/// lang items.
empty_module: Module<'a>,
module_map: FxHashMap<DefId, Module<'a>>,
binding_parent_modules: FxHashMap<NameBinding<'a>, Module<'a>>,
Expand Down
16 changes: 8 additions & 8 deletions tests/ui/assoc-lang-items.stderr
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
error[E0522]: definition of an unknown language item: `dummy_lang_item_1`
error[E0522]: definition of an unknown lang item: `dummy_lang_item_1`
--> $DIR/assoc-lang-items.rs:4:5
|
LL | #[lang = "dummy_lang_item_1"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown language item `dummy_lang_item_1`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown lang item `dummy_lang_item_1`

error[E0522]: definition of an unknown language item: `dummy_lang_item_2`
error[E0522]: definition of an unknown lang item: `dummy_lang_item_2`
--> $DIR/assoc-lang-items.rs:7:5
|
LL | #[lang = "dummy_lang_item_2"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown language item `dummy_lang_item_2`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown lang item `dummy_lang_item_2`

error[E0522]: definition of an unknown language item: `dummy_lang_item_3`
error[E0522]: definition of an unknown lang item: `dummy_lang_item_3`
--> $DIR/assoc-lang-items.rs:10:5
|
LL | #[lang = "dummy_lang_item_3"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown language item `dummy_lang_item_3`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown lang item `dummy_lang_item_3`

error[E0522]: definition of an unknown language item: `dummy_lang_item_4`
error[E0522]: definition of an unknown lang item: `dummy_lang_item_4`
--> $DIR/assoc-lang-items.rs:17:5
|
LL | #[lang = "dummy_lang_item_4"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown language item `dummy_lang_item_4`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown lang item `dummy_lang_item_4`

error: aborting due to 4 previous errors

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0522.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#[lang = "cookie"]
fn cookie() -> ! {
//~^^ ERROR definition of an unknown language item: `cookie` [E0522]
//~^^ ERROR definition of an unknown lang item: `cookie` [E0522]
loop {}
}

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/error-codes/E0522.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0522]: definition of an unknown language item: `cookie`
error[E0522]: definition of an unknown lang item: `cookie`
--> $DIR/E0522.rs:3:1
|
LL | #[lang = "cookie"]
| ^^^^^^^^^^^^^^^^^^ definition of unknown language item `cookie`
| ^^^^^^^^^^^^^^^^^^ definition of unknown lang item `cookie`

error: aborting due to 1 previous error

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0718.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![feature(lang_items)]

// Box is expected to be a struct, so this will error.
#[lang = "owned_box"] //~ ERROR language item must be applied to a struct
#[lang = "owned_box"] //~ ERROR lang item must be applied to a struct
static X: u32 = 42;

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0718.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0718]: `owned_box` language item must be applied to a struct
error[E0718]: `owned_box` lang item must be applied to a struct
--> $DIR/E0718.rs:4:1
|
LL | #[lang = "owned_box"]
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/feature-gates/feature-gate-lang-items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[lang = "foo"] //~ ERROR language items are subject to change
//~^ ERROR definition of an unknown language item: `foo`
#[lang = "foo"] //~ ERROR lang items are subject to change
//~^ ERROR definition of an unknown lang item: `foo`
trait Foo {}

fn main() {}
6 changes: 3 additions & 3 deletions tests/ui/feature-gates/feature-gate-lang-items.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0658]: language items are subject to change
error[E0658]: lang items are subject to change
--> $DIR/feature-gate-lang-items.rs:1:1
|
LL | #[lang = "foo"]
Expand All @@ -7,11 +7,11 @@ LL | #[lang = "foo"]
= help: add `#![feature(lang_items)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0522]: definition of an unknown language item: `foo`
error[E0522]: definition of an unknown lang item: `foo`
--> $DIR/feature-gate-lang-items.rs:1:1
|
LL | #[lang = "foo"]
| ^^^^^^^^^^^^^^^ definition of unknown language item `foo`
| ^^^^^^^^^^^^^^^ definition of unknown lang item `foo`

error: aborting due to 2 previous errors

Expand Down
6 changes: 3 additions & 3 deletions tests/ui/lang-items/issue-83471.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
#![no_core]

#[lang = "sized"]
//~^ ERROR: language items are subject to change [E0658]
//~^ ERROR: lang items are subject to change [E0658]
trait Sized {}

#[lang = "fn"]
//~^ ERROR: language items are subject to change [E0658]
//~| ERROR: `fn` language item must be applied to a trait with 1 generic argument
//~^ ERROR: lang items are subject to change [E0658]
//~| ERROR: `fn` lang item must be applied to a trait with 1 generic argument
trait Fn {
fn call(export_name);
//~^ ERROR: expected type
Expand Down
Loading
Loading